结构化 Tool Calling:让 AI 别再直接碰表格数据

用户输入一句“把销售额低于 10 万的行标红”,模型生成几行 JavaScript,页面执行,单元格变色。录成十几秒的视频,效果很好。
但只要把 Demo 放进真实业务,问题马上就来了:
-
用户说的“销售额”到底在哪一列?
-
当前有 6 张工作表,应该改哪一张?
-
“标红”是改字体、背景色,还是加条件格式?
-
如果模型把表头也改了,怎么撤销?
-
如果选区里有合并单元格、公式和受保护区域,谁来兜底?
这时会发现,AI 表格最难的部分并不是模型理解不了中文,而是我们把“理解意图”和“执行操作”混成了一件事。
模型擅长猜,代码必须确定
大模型适合处理模糊输入。它可以判断“环比下降明显”大概率是要做数据比较,也能从“帮我把这块整理一下”推测出用户可能需要排序、格式化或补公式。
但表格写入不是一道开放题。
一次真实操作至少要确定:
{
"sheetName": "华东区",
"range": "B2:G38",
"rule": {
"column": "销售额",
"operator": "lessThan",
"value": 100000
},
"style": {
"backColor": "#FDE2E2"
}
}
这些参数一旦落到执行层,就不应该再靠模型临场发挥。更稳妥的做法是:模型只负责选择工具并生成结构化参数,浏览器里的代码负责校验和执行。
链路大致是这样:
自然语言
-> 读取当前工作簿上下文
-> 模型选择工具
-> 参数校验
-> 浏览器执行 SpreadJS 操作
-> 返回执行结果
-> 模型继续或结束
关键变化只有一句话:模型不直接碰表格对象。

为什么要把操作做成“小工具”
假设我们提供一个万能工具:
runSpreadsheetCode(code: string)
它当然灵活。模型想改值、设公式、插图表,都可以生成一段代码。但问题也很明显:参数无法提前校验,执行范围不透明,错误很难复现,更谈不上权限控制。
另一种方式是把高频动作拆成边界清晰的工具:
setCellValues({
sheetName,
range,
values
})
setRangeStyle({
sheetName,
range,
style
})
insertFormula({
sheetName,
range,
formula
})
这看起来没有“万能代码执行”聪明,却更接近成熟软件的做法。
每个工具都可以独立回答几个问题:
-
参数是否合法?
-
会影响多少个单元格?
-
是否会覆盖已有内容?
-
是否需要用户确认?
-
执行失败能否回滚?
工具越明确,模型犯错时越容易定位。是意图识别错了、参数生成错了,还是前端执行错了,一眼就能分开。
表格上下文也不能一股脑发给模型
很多人做到这里,会把整个工作簿序列化后传给模型。原型阶段确实省事,但一张稍大的业务表就会暴露问题:上下文变长、响应变慢、费用上涨,模型还容易被无关数据干扰。
更实用的上下文通常只包含:
-
当前活动工作表
-
当前选区
-
使用区域的行列规模
-
表头和少量样本
-
公式、数据类型等摘要
-
最近一次操作结果
SpreadJS 本身可以获取活动工作表、当前选区和已使用区域。真正需要设计的不是“怎么把所有数据拿出来”,而是“这一轮任务最少需要哪些数据”。
例如用户已经选中 D2:D50,又说“把这一列改成人民币格式”,那么活动表、选区和列数据类型已经足够。再把其他 10 张工作表发给模型,只是在增加噪声。
一个容易被忽略的细节:结果要回传
工具执行完不能只返回 success: true。
模型需要知道实际发生了什么:
{
"ok": true,
"sheetName": "华东区",
"affectedRange": "D2:D50",
"changedCells": 49,
"skippedCells": 0
}
如果存在受保护单元格,还应该告诉模型跳过了哪些区域。这样模型才能给用户一个靠谱的总结,或者继续调用下一步工具。
这也是为什么 AI Agent 不只是“聊天框加一个表格”。它本质上是一套有状态的执行系统。
Demo 和可用产品之间,差的是工程边界
让模型生成一段 SpreadJS API 调用并不难。真正需要花时间的是:
-
给模型什么上下文;
-
暴露哪些工具;
-
每个工具如何校验;
-
哪些操作要确认;
-
执行结果如何回传;
-
做错后如何恢复。
这几件事听起来不如“自然语言生成图表”吸睛,却决定了 AI 表格能不能从演示走进业务系统。
模型负责理解,代码负责确定性执行。这个边界一旦立住,后面的安全、调试和扩展才有基础。

我把这条链路拆成了一套 SpreadJS AI Agent 实战内容,从工作簿上下文、工具封装一直讲到确认、回滚和调试。后续会继续把其中容易踩坑的部分单独展开,感兴趣可以关注这个系列。
本项目基于 TypeScript/TSX 和 SpreadJS,README 已整理工具体系、MCP 配置、受控代码执行、快照与恢复等入口,适合边读代码边验证。本文相关看点:工作簿上下文、12 个模块网关和渐进式工具披露。
更多推荐




所有评论(0)