跳到主要内容

工具定义设计

工具定义放在请求的什么位置?​

  • 字段: 请求顶层的 tools 数组,不在 messages 列表内;
  • 内容: 每个工具的名称、功能描述与参数 schema(type: "function" + function 对象);
  • 静态性: 属于开发者事先注册的元数据,与用户这次问了什么无关;
  • 前缀地位: 与系统提示词一起构成上下文最前面的静态前缀,随请求由服务商一起缓存;
  • 规模现实: 示例中只列相关工具是为了请求体短,真实 Agent 往往一次挂上几十个工具;

好的工具定义包含哪些要素?​

  • 定位: 工具定义是给新员工的操作手册,好的描述让从未用过该工具的人能立即正确使用并避免常见错误;
  • 使用边界: 明确写出禁止用法,如 “NEVER invoke grep or rg as a Bash command”;
  • 具体示例: 给出参数取值范例,如 timezone: 'America/New_York';
  • 性能提示: 引导批量化调用,如 “Batch your tool calls together”;
  • 协作关系: 说明与其他工具的先后依赖,如 “Use the Read tool at least once before editing”;
  • 设计视角: 从 Agent 视角而非程序员视角设计接口(ACI),命名与参数要直观,容易误用的地方从设计上让错误无法发生(见 Harness 工程);
  • 证据: 移除描述性文本后工具调用错误率增加 45%(见 业务规则与 Few-shot 示例);
  • 展开: 完整设计原则与最佳实践见第四章;

工具定义如何做渐进式披露?​

  • 问题: 工具数量膨胀时,把全部 schema 放进系统提示词既消耗大量 token,也干扰模型注意力;
  • OpenAI Responses API: 提供 tool_search 工具与 defer_loading: true 标记,模型通过 tool_search_call → tool_search_output 按需加载完整 schema;
  • Anthropic: 对应机制为 Tool Search(tool_reference blocks);Claude Code 对 MCP 工具默认延迟加载,会话启动时只注入工具名称与服务器说明;
  • Codex CLI: tool_search(BM25 检索)不是可选特性而是默认开启的架构;
  • 共同思路: 遵循 Skills 的渐进式披露——静态前缀只保留名称与简述,完整 schema 在模型按需请求后追加到上下文末尾,成为轨迹的一部分;
  • 缓存原理: 因果注意力决定每个 token 的隐状态只依赖自身与之前的 token,末尾追加不会改变任何已缓存 token 的 K、V;
  • 代价: 新增 schema 只需在首次出现时计算一次(一次性的缓存写入),此后并入不断增长的“前缀”,后续轮次持续命中;
  • 性质: 不是“预编译”,而是“只增不改”的追加式注入;
  • 常见误解: “追加到末尾”只发生在工具被发现的那一轮;此后该 schema 块固定在轨迹原位置,后续新消息追加在它之后,它成为普通历史消息;
  • 能力约束: 模型必须在训练中见过“工具定义出现在对话中间”这种模式,目前只有较新模型(GPT-5.4+、Claude 4.5+ 系列)支持,自托管的开源模型需要专门训练;
  • 展开: 工具太多的完整讨论见第四章;