DOCAI · 概念 · L2
tool_choice 怎么强制或禁止调用工具
请求级参数:控制模型可以、必须或禁止调用工具,以及是否必须调用指定工具。
它是什么
tool_choice 是请求里的一个参数,用来约束模型这次调用中如何使用你提供的工具。它不定义也不执行工具,只影响模型的选择空间。
工具定义回答「有哪些工具可用」,tool_choice 回答「这次必须用、可以用、还是不许用」。
怎么工作
各家命名不同,语义可以对齐成四档:
- 自动(auto):模型自行判断,可以直接回答,也可以调用工具。带工具时通常是默认值。
- 必须调用任一工具(Anthropic 的 any,OpenAI 的 required):必须至少调用一个工具,适合先取数再回答的流程。
- 必须调用指定工具:点名要求调用某个工具,适合第一步必须固定动作,比如先检索再总结。
- 禁止调用(none):不允许产生工具调用,模型只能用已有上下文作答。
Anthropic 的写法是对象,指定工具时要带工具名;OpenAI 的 Chat Completions 用字符串或带函数名的对象,Responses API 又略有差异。对接时以各家文档为准,别假设字段能原样透传。
强制调用会绕过模型判断
把 tool_choice 设成必须调用,等于取消了模型「这次不需要工具」的选项。模型为了满足约束,即使信息不足也会生成一次调用,参数只能靠猜;任务和工具不匹配时,它会硬选一个最接近的,或塞入无意义的参数。
强制调用适合做流程控制,不适合当质量保证。需要保证「先检索」这类顺序时可用;需要模型自己判断该不该查时,应该用 auto,并把工具描述写清楚。
和结构化输出的区别
结构化输出约束最终回答长什么样,比如必须符合某个 JSON Schema;工具调用约束模型可以请求哪个外部动作。
只想要 JSON,不该定义假工具骗模型调用,应该用结构化输出或 JSON 模式。反过来,需要执行查询、写文件、发请求时,才定义工具。用强制调用提交工具来收集结构化结果是常见绕路,它把执行语义和格式约束混在一起,错误处理也更麻烦。
不同厂商字段不兼容时
做适配层时写一张映射表,把内部语义映射到各家形状,不在业务代码里到处判断厂商:
| 语义 | Anthropic | OpenAI |
|---|---|---|
| 自动 | auto | auto |
| 必须调用任一工具 | any | required |
| 必须调用指定工具 | 指定工具名 | 指定函数名 |
| 禁止调用 | none | none |
另有三点:工具定义的字段名不同,参数结构在 Anthropic 叫 input_schema,在 OpenAI 叫 parameters;部分模型或思考模式对强制调用有限制;兼容接口通常沿用 OpenAI 的形状,但完整度不一,官方未说明的差异要自己测。
工具不触发时先查哪一层
按从外到内的顺序排查:
- 原始请求体里有没有 tools,字段名有没有被 SDK 或网关改写。
- tool_choice 是否被上层设成 none,或系统提示里写了不要调用工具。
- 响应里的结束原因是不是工具调用;解析代码有没有只读文本、丢掉工具调用块。
- 流式响应有没有处理工具调用的增量块,这是最常见漏点。
- 工具的参数结构是否合法,必填字段和枚举有没有写错。
- 最后才怀疑模型判断:任务是否真的需要工具,工具描述是否说清楚。
常见误解
- auto 就是一定调用工具:auto 只是允许,模型可以完全不调。
- none 会把工具定义删掉:定义仍在上下文里,照样占 token,只是禁止调用;也不保证模型不在文字里提工具名。
- 强制调用能提高准确率:它只保证调用发生,不保证调对。
- 各家字段可以直接复用:语义相近,形状不同,需要适配。
什么时候用得上
当流程要求第一步必须是某个工具,或者要临时禁止工具、只用已有上下文生成答案时,才需要设置 tool_choice;默认交给模型判断。
常见误解
很多人以为强制调用能让结果更准,其实 tool_choice 只保证「调用」这个动作发生,不保证调对工具或参数正确;信息不足时,模型会为了满足约束编造参数。