做产品 PMaker 首页
搜索
跟随系统
颜色主题
空格的键盘
工具按任务切分,不按接口切分API 包装40 个端点就是 40 个工具选不准,改不动任务语义工具按任务重新切分与命名选得准,用得对契约声明风险、超时、幂等、输出裁剪错得起,恢复得了把模型推断不出来的东西全写进契约

工具按任务切分,不按接口切分;模型推断不出来的东西要写进契约。

工具是契约,不是 API 包装

面向任务语义设计工具,把 schema、风险、超时、幂等和输出裁剪写进契约,让模型选得对、错得起、恢复得了。

面向 Agent 的任务语义设计工具,而不是一对一包装现有 API。后端有 40 个 REST 端点,不代表 Agent 就该有 40 个工具:模型在 6 个任务语义清晰的工具里选对的概率,远高于在 40 个名字相近的端点里选对的概率。而且工具描述常驻上下文,工具越多,每个工具分到的注意力越少。

工具是模型与确定性系统之间的契约

所谓契约,是把模型从代码里推断不出来的东西显式声明出来:name、version、description、inputSchema、outputSchema、annotations(readOnly、destructive、idempotent、openWorld)、riskLevel、approvalPolicy、timeoutMs、retryPolicy、resultPolicy。缺任何一项,模型或 Runtime 就只能靠猜。

漏掉 idempotent,一次重试可能在生产环境造成重复扣款;漏掉 openWorld,模型不知道这个工具会访问公网,也就不知道返回值里可能混进不可信内容;漏掉 timeoutMs,Runtime 不知道该在什么时候接管。这些都不是文档问题,是运行时的分支条件。

readOnly 那一栏最容易被当成合规字段,其实它是运行时开关。感知工具不改外部世界,于是结果可以安全缓存(相同查询直接复用),多次调用可以放心并行(同时读五个文件、并发发起三个搜索)。执行工具没有这种自由,顺序和副作用都得严格控制 ai-agent-book。你少声明一次 readOnly,就等于主动放弃这两项收益。

描述决定选择准确率

差:search: 搜索数据
好:supplier.search:按归一化后的产品需求检索内部供应商记录。
    在公开网络检索之前使用。最多返回 20 条候选,包含 ID、命中字段和来源证据。
    只读,不会联系供应商。

好描述要回答七件事:做什么、何时用、何时不要用、输入字段的含义、返回什么、有什么副作用、失败后怎么恢复。前三条决定模型会不会选中它,后四条决定它能不能把参数填对、把结果用对。

「何时不要用」最常被省掉,而它恰恰是避免工具重叠的关键——两个描述都很泛的工具摆在一起,模型没有别的依据,只能猜。

schema 表达不了隐式约定。时间戳要秒还是毫秒、过滤条件怎么嵌套、空数组是「不过滤」还是「清空」——这类约定写在描述里比写在类型定义里有效。更省字的写法是给每个工具附 1–5 个真实调用示例;书里给的量级是,一些基准上工具调用准确率从约 72% 提到约 90% ai-agent-book

参数会在链路里被静默改写

有一类失败模式只在真实链路上暴露。Cursor 某个版本的编辑工具接收 old_stringnew_string 做精确匹配替换,而参数传递层会把中文弯引号(\u201c\u201d)静默换成英文直引号。读取工具原样返回弯引号,模型照着传,工具回「未找到匹配」;模型看不见中间那次替换,只能反复重试、反复失败 ai-agent-book。写入方向更糟:本意写入弯引号,落盘成了直引号,再读回来发现内容「不对」,模型还以为自己写错了。

所以契约里要多写一项:参数从模型到执行会经过哪些改写——引号归一化、Unicode 规范化、空白折叠、路径分隔符、换行风格。这一项不能在 schema 层测出来:schema 测试全绿而链路仍在改你的字节,是最难查的一类缺陷,因为报错发生在离病因很远的地方。

输出必须裁剪,不然就是在烧上下文

输出要结构化、有界。禁止返回原始大 HTML、完整数据库行和无界日志;长日志、测试输出、进程列表和 Diff 要做确定性压缩,同时保留退出码、失败位置、关键错误、统计和 ArtifactRef。

Anthropic 用 16 个并行 Claude 编译 C 编译器时踩过这个坑:测试 harness 打印几千字节的无用输出,直接污染上下文窗口;agent 被丢进全新容器、没有任何上下文,又要花大量时间重新定位。他们的解法是重写 harness——每个测试最多打印几行,重要信息写进文件;日志要能被 grep,有错就写 ERROR 并把原因放在同一行;预计算汇总统计,避免每个 agent 重复算一遍。anthropic-c-compiler

错误要交给该处理它的一方

Error Contract 只有一条分界线:预期内的失败(参数不合法、目标不存在、配额不足)作为结构化错误数据返回给 Agent,让它自己决策;认证失败、权限不足、数据损坏、Runtime 缺陷和未知异常,由 Runtime 终止或中断执行,绝不把整段 exception 灌进上下文。

错误对象至少带 code、category、message、retryable、safeForModel、suggestedActions。safeForModel 是闸门,决定这条信息能不能进模型上下文。没有它,一次数据库栈回溯就能吃掉半个窗口的预算,而模型从中得不到任何可行动的信息。

工具也要写测试

每个工具至少覆盖八项 Tool Evals:正确选择工具、不该调用时不调用、参数正确率、对错误结果的恢复、Token 效率、描述变更后的回归、危险参数是否被 Guardrail 拦下、重试是否造成重复副作用。anthropic-evals

后两项是安全问题,不是质量问题。漏掉它们,你第一次发现缺口的地方会是生产事故。

代价与自检

代价是前期工作量:每个工具都要写清 schema、风险、超时和压缩逻辑,还要维护 evals。工具数量少、任务稳定的场景回报最高;一次性脚本和探索性原型不值得这么投入。

三个问题可以自查:你的工具里有没有一对一照搬 REST 端点的?它们的描述写了「何时不要用」吗?一个工具失败时,返回给模型的是结构化错误还是一整段栈?

参考资料

  1. Building a C compiler with a team of parallel Claudes
  2. Demystifying evals for AI agents
  3. 《AI Agents in Depth》第四章 工具