把整张 Excel 塞给大模型,是 AI 表格最贵也最笨的做法

数据少的时候,这个办法很顺。表头、数据、公式一次性进入上下文,模型回答也像模像样。
等文件变成十几张工作表、几万行数据,麻烦就来了:
-
请求体越来越大;
-
首次响应越来越慢;
-
Token 成本直线上升;
-
模型开始关注无关区域;
-
同一个问题,回答变得不稳定。
最反直觉的一点是:给模型的信息越多,它不一定越懂当前任务。
“完整数据”不等于“有效上下文”
用户选中一列,然后说“找出异常值”。
这一轮真正有用的信息可能只有:
-
当前工作表名称;
-
当前选区;
-
选区表头;
-
数据类型;
-
若干统计值;
-
少量异常样本。
其他工作表的图表、样式、批注和历史数据,对当前任务大多是噪声。
所以 AI 表格需要的不是一次性序列化,而是一套分层上下文。

第一层:先给工作簿地图
第一轮只需要让模型知道“这里有什么”:
{
"activeSheet": "销售明细",
"sheets": [
{"name": "销售明细", "usedRange": "A1:H3200"},
{"name": "产品", "usedRange": "A1:D180"},
{"name": "区域", "usedRange": "A1:C35"}
],
"selection": "F2:F3200"
}
SpreadJS 可以通过 getActiveSheet() 获取活动工作表,通过工作表的 getSelections() 获取当前选区,也可以用 getUsedRange() 获取已使用范围。
这几个信息足以让模型建立一张工作簿地图,却不需要把 3200 行销售记录全部发出去。
第二层:按任务取摘要
如果用户要分析 F2:F3200,可以继续提供:
{
"header": "毛利率",
"valueType": "number",
"count": 3199,
"emptyCount": 12,
"min": -0.18,
"max": 0.76,
"average": 0.23,
"samples": [0.21, 0.19, -0.18, 0.24, 0.76]
}
这比原始数据更适合做意图判断。
如果模型决定使用 IQR、Z-Score 或业务阈值,再由工具读取必要的数据并计算。也就是说,先用摘要决定下一步,再按需获取明细。
第三层:工具也要渐进加载
上下文膨胀不只来自数据,还来自工具定义。
表格 Agent 做久了,工具很容易从十几个长到上百个:单元格、样式、公式、图表、数据透视表、导入导出、打印、保护、批注……
如果每一轮都把全部工具描述交给模型,会出现两个问题:
-
工具定义本身占掉大量上下文;
-
相似工具变多后,模型更容易选错。
更好的方式是把工具做成模块:
基础工具
- 读取工作簿摘要
- 读取选区
- 进入样式模块
- 进入公式模块
- 进入图表模块
公式模块
- 设置公式
- 批量填充公式
- 检查公式
- 返回基础工具
用户说“生成趋势图”,模型先进入图表模块,下一轮才看到图表相关工具。模型每一步只面对当前需要的能力,工具选择反而更稳定。
这其实就是 Agent 的状态机:当前在哪个能力域、已经完成什么、接下来允许调用什么,都需要在请求之间保存。
上下文要能增量更新
另一个容易被忽略的问题是:执行一次工具后,工作簿已经变了。
如果每一步都重新扫描整个工作簿,浪费性能;如果完全不更新,模型又会基于旧状态继续行动。
比较实用的办法是维护“基础摘要 + 最近变更”:
{
"baseVersion": "wb_1024",
"recentChanges": [
{
"tool": "setFormula",
"sheet": "销售明细",
"range": "H2:H3200",
"status": "success"
}
]
}
模型需要时再读取具体区域。这样既保留连续任务的状态,又不用每轮搬运完整工作簿。
隐私问题也会跟着变简单
减少上下文不只是省 Token。
如果用户只是要设置选区格式,服务端根本不需要看到单元格里的客户名称、手机号或合同金额。前端只上传选区坐标和格式需求,操作仍然可以完成。
这带来一个很实际的设计原则:
能在浏览器端确定性完成的任务,不要为了“让模型更懂”而上传无关业务数据。
上下文最小化,同时也是数据最小化。## 真正的上下文工程,是知道什么不该发
AI 应用早已不只是提示词工程。到了 Agent 阶段,决定效果的往往是上下文如何组织、何时加载、执行后如何更新。
对于表格场景,推荐从这四层开始:
工作簿地图
-> 当前任务摘要
-> 按需读取明细
-> 最近变更增量
工具也采用同样思路:先给入口,再按模块展开。
把整个工作簿和全部工具一次性塞给模型,开发最省事,但运行最昂贵。真正成熟的 AI 表格,应该让模型在每一步只看到“刚好够用”的信息。

这个系列后面会结合 SpreadJS 的活动表、选区和已使用区域,完整实现一次上下文采集,再演示工具模块如何渐进加载。对于正在做 Agent 的前端团队,这部分往往比提示词更值得花时间。
本项目基于 TypeScript/TSX 和 SpreadJS,README 已整理工具体系、MCP 配置、受控代码执行、快照与恢复等入口,适合边读代码边验证。本文相关看点:工作簿上下文、12 个模块网关和渐进式工具披露。
葡萄城是专业的软件开发技术和低代码平台提供商,聚焦软件开发技术,以“赋能开发者”为使命,致力于通过表格控件、低代码和BI等各类软件开发工具和服务,一站式满足开发者需求,帮助企业提升开发效率并创新开发模式。
更多推荐



所有评论(0)