本文由 cooliang 根据排班 Agent 的实际开发经历编写,AI 协助润色。
在排班应用不断迭代的过程中,Agent 能够使用的 Tool 从最初的十几个排班操作,逐渐扩展到 Excel 读取、表格分析、排班导入,以及更完整的表格操作。
随着功能边界不断扩大,Tool 的数量也随之快速增长。到了现在,它已经不再是一个可以继续通过全量 Function Calling 忽略的问题。无论从上下文成本、调用性能,还是模型选择工具的准确率来看,都需要对 Agent 获取和使用 Tool 的方式进行优化。
这并不是为了追求更复杂的 Agent 架构,而是功能持续迭代后,原有方案已经逐渐无法适应新的工具规模。
回过头看,这个过程也恰好对应了大量 Tool 应用中一条相对成熟的技术演变路线:
全量 Function Calling
→ Tool Set / Namespace
→ Tool Search
→ Capability Registry
不过,理解完整的技术路线,并不意味着要把其中所有方案都应用到当前项目中。对我的排班应用来说,目前真正需要解决的是 Tool 数量增长后的供给问题。Tool Set 加上小范围 Tool Search 已经足够,而 Capability Registry 更多是对后续技术演变的了解,并不是当前阶段需要建设的能力。
最开始,只有排班操作 Tool
应用最初的目标比较明确:让 Agent 帮助用户完成创建排班、修改班次、查询排班和检查冲突等操作。
那时只有十几个 Tool,彼此的边界也比较清楚。把所有 Function Definition 直接提供给模型,简单而有效。模型不难理解每个 Tool 的用途,全量加载产生的成本也可以忽略。
在这个阶段,并不需要 Tool Set,更不需要 Tool Search。用最直接的 Function Calling 完成功能,反而最符合当时的实际需要。
真正的变化,是从 Excel 导入排班表开始的。
Excel 导入带来了第一轮扩充
实际使用中,很多用户已经有以 Excel 形式存在的排班表。他们不会因为开始使用新的排班应用,就完全改变原有工作习惯。因此,Agent 不仅要能操作排班数据,还需要理解已有的 Excel 文件。
为了支持这个场景,我陆续增加了读取工作簿、获取工作表、读取单元格区域、分析表头、识别医生和日期、校验班次等 Tool。
Tool 的数量开始增加,但更早暴露出来的问题其实不是“工具太多”,而是“工具太细”。
如果每一个读取和分析动作都被设计成独立 Tool,那么导入一张排班表,就可能需要模型不断循环调用:
读取工作簿
→ 获取工作表
→ 读取表头
→ 判断医生列
→ 判断日期列
→ 读取排班区域
→ 校验医生
→ 校验班次
→ 转换数据
→ 写入排班
如果读取能力继续细化到单元格级别,模型甚至可能逐个区域、逐个单元格读取数据。
一次 Tool Call 并不只是一次普通的函数调用。它通常意味着模型生成调用参数、应用执行 Tool、结果返回模型,然后模型再次判断下一步。调用循环一旦增加,延迟、Token 消耗和中途失败的概率都会随之上升。
这个阶段让我意识到两个经常被混在一起的问题:
Tool Definition 太多,和完成一个任务所需的 Tool Call 太多,并不是同一个问题。
前者关注模型一次需要理解多少工具,后者关注一个任务需要经过多少轮调用。Tool Search 可以减少模型一次看到的 Tool Definition,却不会自动减少完成任务所需的调用次数。
先解决工具颗粒度
针对 Excel 导入中的调用次数问题,我没有立刻引入更复杂的 Tool Search,而是先调整 Tool 的颗粒度。
“读取并分析一张排班表”本身已经是一个相对稳定的任务,没有必要让模型每次都从最底层的 Excel 操作开始组合。于是,我把一组经常一起出现的操作,收敛成了 Excel 导入相关的工具集,例如:
检查 Excel 文件
分析排班工作表
预览排班导入结果
确认并导入排班
工具内部可以完成表头识别、日期解析、医生匹配、班次转换和基础校验。模型只需要理解用户想导入什么,以及如何处理识别结果,而不需要逐个单元格操作。
这次优化主要解决的是 Tool Call 次数问题,也让我对 Tool 的颗粒度有了更实际的理解:Tool 并不是越原子越好。
过于原子的 Tool 虽然灵活,却会把大量机械步骤交给模型;过于高阶的 Tool 又可能限制特殊场景。对我来说,更合适的方式是同时保留两种能力:高阶 Tool 覆盖稳定、常见的导入流程,底层 Tool 则处理格式特殊或者识别失败的情况。
从导入表格走向控制表格
随着应用继续发展,Agent 对表格的需求已经不再局限于读取和导入。
我希望它能够进一步控制表格本身,例如创建工作表、读取和写入区域、插入行列、调整列宽、设置样式、合并单元格、冻结表头、添加公式、设置条件格式和创建图表。
Tool 的范围由此从“排班操作加 Excel 导入”,扩展成了更完整的表格操作能力。Tool 也不再是十几个的量级。
如果继续把所有 Function Definition 全量提供给模型,那么即使用户只是说“把二线排班区域的列宽调宽一些”,模型也可能同时看到排班、导入、公式、图表、结构修改和格式设置等大量无关工具。
这会带来两个直接问题。
一个是成本。每个 Tool 都包含名称、描述和参数 Schema。工具越多,模型每次请求需要读取的内容就越多。
另一个是性能和准确率。表格工具之间往往存在一定程度的语义重叠,模型同时看到的候选工具越多,选择和生成参数的难度也越高。
到了这个阶段,我需要迭代的已经不只是单个 Tool 的设计,而是如何把越来越多的 Tool 更合适地提供给模型。
当前的选择:Tool Set 加小范围 Tool Search
从更完整的技术发展来看,大量 Tool 的供给已经有一条相对成熟的演变路线:从全量 Function Calling,到 Tool Set 和 Namespace,再到 Tool Search;当工具进一步发展为跨团队、可动态安装和独立治理的能力生态时,还可能出现 Capability Registry。
但这并不意味着一个应用必须把整条路线全部走完。
结合排班应用目前的情况,我认为更合适的方案是 Tool Set 加上小范围的 Tool Search。
首先按照能力领域对 Tool 进行分组:
排班操作
Excel 排班导入
表格读取
表格数据写入
表格结构修改
表格格式设置
表格图表
Agent 可以根据当前页面、用户任务和操作对象,先确定大致需要哪个 Tool Set。
例如,用户正在导入已有排班文件时,优先提供 Excel 导入和排班相关 Tool;用户要求调整当前表格样式时,则提供表格读取和格式设置相关 Tool。
如果某个 Tool Set 内部的工具仍然较多,再通过 Tool Search 查找和加载少量具体 Function。
可以把两者的关系简单理解为:
Tool Set 先缩小范围,Tool Search 再从范围内找到当前真正需要的工具。
Tool Set 提供稳定、可控的领域边界,Tool Search 则减少领域内部不必要的 Tool Schema 加载。这样既不需要每次加载全部 Tool Definition,也不需要建立一个复杂的全局能力发现系统。
Capability Registry 是对后续演变的了解
Capability Registry 是我在了解 Tool 技术演变时关注到的方向,但它不是排班应用目前已经采用,或者准备立即采用的方案。
它更适合 Tool 由不同团队或第三方提供、可以在运行期间安装和卸载、不同租户拥有不同能力,或者需要独立版本、发布审核、信誉和兼容性治理的环境。
而我的排班应用目前使用的 Tool 主要由应用自身提供,随代码一起发布,也没有动态安装和第三方工具市场。此时建设完整的 Capability Registry,需要额外增加注册、发布、版本和治理等基础设施,但实际收益并不明显。
了解 Capability Registry 的价值,在于理解未来 Tool 体系可能如何发展,而不是因为它处于技术路线的后面,就认为现在必须采用。
同样,复杂的 Tool 编排也不是当前需要优先解决的问题。现阶段的重点仍然是:如何把快速增长的 Tool Function,以更低的成本、更高的准确率和更安全的方式提供给模型。
对当前应用来说,Tool Set 和部分 Tool Search 已经足以解决主要问题。继续向上增加复杂度,反而可能让系统承担超过当前需求的设计成本。
技术演变不是功能清单
回顾排班应用的 Tool 变化,它经历了几个很自然的阶段:
只有少量排班 Tool
→ 增加 Excel 读取和分析 Tool
→ 因颗粒度过细导致 Tool Call 循环增加
→ 聚合成 Excel 排班导入工具集
→ 扩展到更完整的表格操作能力
→ 开始使用 Tool Set 和部分 Tool Search
每一次变化,都是由当时真正出现的问题推动的。
调用次数过多,就先调整 Tool 颗粒度;Tool Definition 太多,就通过 Tool Set 和 Tool Search 减少暴露范围;只有未来真正出现动态安装、多团队发布和复杂版本治理时,Capability Registry 才会成为值得建设的基础设施。
成熟的方案并不是采用最多的技术,而是在当前阶段选择足够解决问题的那一层。
对于现在的排班 Agent,这一层就是:
用 Tool Set 建立清晰的能力边界,再用小范围 Tool Search 按需提供具体工具。它保留了继续扩展的空间,也避免了过度设计。
