Claude Code 学习站

工具分配与 tool_choice

考点 2.3 · Tool distribution & tool_choice · 所属域权重 18% · 工具设计与 MCP 集成

本页目录5

这个考点是什么

这个考点考察两件相关但不同的事——工具分配(给哪个 agent 配哪些工具、配多少)和 tool_choice(单次请求里如何控制 Claude 是否调用工具、调用哪一个)。

前者是架构设计阶段的取舍,后者是 Messages API 请求体里的一个具体字段,但两者经常在同一道场景题里绑在一起考,因为"配置不当的工具集"和"没用对的 tool_choice"是两种不同却容易被混为一谈的失败模式。

tool_choice 在 Anthropic Messages API 里只有四种取值:auto(默认,提供 tools 时 Claude 自行判断是否调用)、any(必须调用 tools 数组里的某个工具,但具体调用哪个由 Claude 自己选)、tool(配合 name 字段,强制调用指定的某一个工具)、none(禁止调用任何工具,未传 tools 时的默认行为)。

备考时最容易在 anytool 的边界上翻车,也容易被 OpenAI 的 required 语法带偏。

工具分配部分更偏架构判断:

  • 多 agent 系统里,职责单一的 agent(比如只负责综合信息的 synthesis agent)被塞进过多、过杂的工具,反而会降低工具选择的可靠性,诱发越界调用;

  • 同时 tool search tool 的 defer_loading 参数也是这条考点常考的细节——它只影响哪些工具定义进入模型上下文窗口,不影响请求体本身要发送的完整工具集。

为什么考

出题角度主要有两类。

一类是直接考 tool_choice 四档位的定义与默认值——auto 是提供 tools 时的默认,none 是不提供 tools 时的默认——常用"强制调用但不指定具体工具"这类描述让 auto/any/tool 互相当干扰项,并把 OpenAI 的 required 当强干扰项混入考察跨供应商术语混淆。

另一类是场景题,给出多 agent 系统里工具分配失衡的具体后果(如把系统内全部 18 个工具都配给专职的 synthesis agent、或近 400 个工具要不要全部发送),考察能否识别"最小权限"和"高频简单 / 低频复杂分层委派"这类设计原则,而不只是记参数名字。

核心辨析

  1. 1

    tool_choice 只有 auto/any/tool/none 四种类型,没有第五种

    auto 是提供 tools 时的默认值(Claude 自行判断要不要调用工具),none 是不提供 tools 时的默认行为(禁止调用任何工具)。记混默认值是这条考点最常见的失分点。

  2. 2

    anytool 都会强制发生一次工具调用,但强制的粒度不同

    any 只保证"调用 tools 数组里的某一个",具体调哪个仍由 Claude 自己决定;tool 必须配合 name 字段,把"调用哪一个"也锁死。题目里"必须调用但不关心调哪个" vs "必须调用指定的那一个"是区分这两者的标志句式。

  3. 3

    required 不是 Anthropic 的 tool_choice 类型,它是 OpenAI API 的命名。凡是选项里出现 {"type": "required"} 这类写法,基本可以判定为跨供应商术语混入的干扰项。

  4. 4

    tool_choice 和工具定义上的 strict: true 管的是两件正交的事

    前者决定"是否调用/调用哪个工具",后者(通过对 input_schema 做约束采样)决定"调用时的输入是否严格符合 JSON Schema"。需要同时保证"每次都必须调用指定工具"且"参数必须严格合规"的场景(如强制调用 create_refund 且输入必须符合 schema),两个机制要组合使用,单独设置任何一个都不够。

  5. 5

    工具分配要遵循最小权限

    给专职 agent(如只做综合的 synthesis agent)配置超出其职责范围的工具(全部 web 搜索/邮件/日历等),不会带来"更灵活",反而会降低工具选择可靠性,诱发它拿不该用的工具做不该做的事。

    合理做法通常是按调用频率和复杂度分层——高频简单需求给一个窄范围的专用工具就地解决,低频复杂需求仍通过协调者委派给专职 agent,而不是一刀切地扩大或收窄某个 agent 的工具集。

  6. 6

    工具搜索场景下,defer_loading: true 只影响该工具定义是否进入模型的上下文窗口,不影响该工具是否要出现在每次请求的 tools 数组里——完整定义仍必须每次都发送,且至少要有一个工具(通常是 search 工具本身)保持非 deferred 状态,否则请求会报错。

反模式对照

常见做法

tool_choice: {"type": "required"} 去强制 Claude 调用工具

正确做法

Anthropic 只支持 auto/any/tool/none 四种类型,强制调用某个工具但不指定具体是哪个用 {"type": "any"}

required 是 OpenAI 的语法,不存在于 Anthropic Messages API,是常见的跨供应商术语混淆。

常见做法

认为把 tool_choice 设成强制调用某个具体工具后,该工具的输入参数就自动严格符合 JSON Schema

正确做法

强制调用哪个工具由 tool_choice: {"type": "tool", "name": "..."} 负责,输入是否严格符合 schema 需要在工具定义上单独设置 strict: true

两个机制是正交的,只解决"调不调用/调哪个"不等于解决了"输入格式对不对",对精确性要求高的场景(如金额、退款单号)两者都要配置。

常见做法

给职责单一的专职 agent(如只做综合报告的 synthesis agent)配上系统里全部工具,理由是"更灵活、以防万一"

正确做法

按角色最小化配置工具集,只给该 agent 高频需要的窄范围工具;低频或复杂的需求仍通过协调者委派给对应的专职 agent

工具集越杂,模型工具选择的可靠性越差,容易出现专职 agent 越界调用不该用的工具(比如该做综合的 agent 转而自己发起新的网页搜索)。

常见做法

认为标记为 defer_loading: true 的工具可以不放进请求的 tools 数组,或以为存在某种外部工具注册表

正确做法

无论是否 defer_loading,所有工具的完整定义每次请求都要放进 tools 数组;defer_loading 只决定该工具是否进入模型的上下文窗口,且至少要有一个工具(通常是 search 工具本身)不能被 deferred

混淆了"要不要发送"和"是否进入模型上下文"这两件事,是 tool search tool 场景下最容易踩的坑。

练这个考点