3.5 高级特性:程序化工具调用
3.5.1 什么是程序化工具调用?
在标准的工具使用模式中,Claude 扮演的是一个“调度员”:它输出指令,代码执行指令。虽然这种模式简单清晰,但在面对复杂任务时,它通过 HTTP 请求往返的“乒乓”效应会导致显著的延迟。
2025 年,Anthropic 引入了 程序化工具调用。这是一种范式转变:Claude 不再仅仅输出单一的 JSON 指令,而是能够编写并在安全的沙箱容器中执行 Python 代码脚本。这使得 Claude 能够通过代码逻辑(循环、判断、变量传递)一次性编排多个工具调用,甚至直接在沙箱中处理数据。
支持的模型
程序化工具调用目前支持以下模型(均使用 code_execution_20260120 工具类型):
claude-opus-4-6
Opus 最新版
claude-sonnet-4-6
Sonnet 最新版
claude-sonnet-4-5-20250929
Sonnet 4.5
claude-opus-4-5-20251101
Opus 4.5
该功能通过 Claude API 和 Microsoft Foundry 提供。
3.5.2 架构对比:打破“乒乓”效应
以下通过一个场景来对比两种模式:“获取系统中所有活跃用户的名单,并为每个人生成一份月度报表。”
传统模式
Claude:
get_active_users()App: 返回 100 个用户的 JSON List(消耗大量 Token)。
Claude:
generate_report(user_id=1)App: 返回结果。
Claude:
generate_report(user_id=2)... (重复100次)
由于上下文窗口 (Context Window) 限制和网络延迟,这种任务在传统模式下几乎不可行。
程序化模式
Claude: 生成并执行如下 Python 代码:
App/Container: 执行整段代码。
App: 仅返回最终的一句话结果。
优势总结:
极低延迟:将 100 次网络往返压缩为 1 次。
节省 Token:中间数据(如那 100 个用户的详细信息)在代码空间中流转,无需进入 LLM 的上下文窗口。程序化调用的工具结果 不计入 输入/输出 Token——只有最终代码执行结果和 Claude 的回复才计费。
逻辑完备:支持
if-else、for循环和异常处理。
[!TIP] Token 效率:例如,直接调用 10 个工具大约消耗 10 倍于程序化调用后再返回摘要的 Token 量。
3.5.3 配置与启用
要启用此功能,需要告知 Claude 哪些工具允许被代码调用。
allowed_callers 字段
allowed_callers 字段在定义工具 Schema 时,新增 allowed_callers 属性:
allowed_callers 的可选值:
["direct"]
仅允许 Claude 标准模式调用(默认值)
["code_execution_20260120"]
仅允许从代码执行环境中调用
["direct", "code_execution_20260120"]
两种模式均可
[!TIP] 建议为每个工具只选择
['direct']或['code_execution_20260120']其中之一,这样能给 Claude 提供更明确的使用指引。
caller 响应字段
caller 响应字段每个 tool_use 响应块都包含一个 caller 字段,标识该工具是如何被调用的:
这对于在应用层区分处理直接调用与程序化调用非常有用。
容器环境
当 Claude 决定使用程序化工具时,它不仅会生成 tool_use,还会请求一个 code_execution 环境。
生命周期:每个 Session 默认创建一个新容器,并在闲置约 4.5 分钟后销毁。
状态保持:通过传递
container_id,可以让 Claude 在后续对话中访问之前定义的变量(如pd.DataFrame)。超时监控:当容器等待工具结果时,必须在容器过期前响应。可通过
expires_at字段监控剩余时间。如果容器过期,Claude 可能会将该工具调用视为超时并重试。
3.5.4 高级模式
程序化调用支持多种强大的代码模式,以下是典型场景。
批量处理
此模式将 N 次模型往返减少为 1 次,且大量中间数据无需进入上下文窗口。
提前终止
条件选择工具
数据过滤
3.5.5 设计适合程序化调用的工具
程序化调用的工具设计理念与传统模式有所不同。
返回结构化数据:工具最好返回 JSON 对象、列表或 Pandas DataFrame 兼容的数据,方便代码处理。避免返回“自然语言描述”。
Bad: “张三的年龄是30岁。”
Good:
{"name": "Zhang San", "age": 30}
提供详细的输出描述:由于 Claude 会在代码中反序列化工具结果,请清楚记录返回格式(JSON 结构、字段类型等)。
原子化 (Atomic):工具功能应尽量单一。组合逻辑交给 Claude 写代码去完成。
批量接口:虽然循环调用很快,但提供
batch_get_users([ids])这样的批量接口依然是性能优化的首选。保持响应简洁:仅返回必要数据,减少处理开销。
3.5.6 工具学习 (Tool Learning / Few-Shot)
对于极其复杂或非直观的工具,仅靠 description 可能不够。可以通过 Few-Shot Examples(少样本示例) 来“教会” Claude 如何编写正确的调用代码。
Anthropic 推荐使用 XML 格式提供示例:
将这部分内容包含在 system prompt 中,能显著提高一次成功率。
3.5.7 限制与注意事项
尽管功能强大,但目前仍存在边界:
功能不兼容项
结构化输出
设置了 strict: true 的工具不支持程序化调用
工具选择
无法通过 tool_choice 强制触发程序化调用
并行工具
disable_parallel_tool_use: true 与程序化调用不兼容
MCP 工具
通过 MCP Connector 提供的工具暂不支持程序化调用
响应格式限制
当回复程序化工具调用时,响应消息 必须仅包含 tool_result 块,不能夹带任何文本内容。这是一个严格的格式要求——如果包含了额外文本,会导致解析错误。
[!IMPORTANT] 此限制仅适用于程序化(代码执行)工具调用的回复。对于常规的客户端工具调用,仍然可以在
tool_result之后包含文本内容。
安全注意事项
虽然运行在沙箱中,但让 AI 写代码并执行总是伴随风险。建议对代码容器进行网络隔离,仅允许其访问白名单内的 API。
工具结果以字符串形式返回,可能包含代码片段或可执行命令。如果工具返回来自外部来源的数据,需注意代码注入风险。
3.5.8 何时使用程序化调用
处理大数据集,仅需聚合/摘要
单次工具调用且返回简单
涉及 3 个以上相互依赖的工具调用
需要即时用户反馈的工具
需要对工具结果进行过滤、排序或转换
极快操作(代码执行开销大于收益)
中间数据不应影响 Claude 推理的场景
-
跨多项目并行操作(如检查 50 个端点)
-
3.5.9 最佳实践清单
工具粒度
保持工具简单、原子化。避免“万能工具”。
数据格式
始终针对“机器读取”而非“人类阅读”优化工具返回值。
输出描述
详细记录工具返回的 JSON 结构和字段类型。
错误处理
在工具内部捕获异常并返回清晰的错误 JSON,让 Claude 的代码能 try-catch。
容器复用
发起多个相关请求时复用容器以保持状态。
监控
记录 Claude 生成的所有代码,这对于调试和安全审计至关重要。
当工具数量增长到数百个时,如何让 Claude 找到正确的工具?需要“工具搜索”。
➡️ 工具搜索与大规模管理
最后更新于
