摘要

1) 一句话摘要 编程式工具调用允许 Claude 在代码执行沙盒中通过编写 Python 代码自动、批量地调用工具并处理中间结果,从而显著降低多步工作流的延迟和 Token 消耗。

2) 关键要点

  • 核心机制:Claude 在沙盒中运行代码调用工具,API 暂停并等待用户返回结果后继续执行,中间处理过程和结果不会加载到 Claude 的上下文窗口中。
  • 模型兼容性:支持 Claude 4.5 和 4.6 系列的 Opus 与 Sonnet 模型(需指定工具版本 code_execution_20260120),可通过 API 和 Microsoft Foundry 使用。
  • 配置与调用:通过在工具定义中配置 allowed_callers 字段(如 ["code_execution_20260120"])启用;响应中的 caller 字段会标识调用来源。
  • 容器生命周期:执行容器在约 4.5 分钟无活动后过期,支持通过传递容器 ID 在请求间重用容器以保持状态。
  • Token 与成本效率:编程式调用的中间工具结果不计入输入/输出 Token 用量,仅对最终代码执行结果和 Claude 的响应计费,定价与常规代码执行相同。
  • 适用场景:非常适合大规模数据过滤/汇总、包含 3 个以上依赖调用的多步工作流、条件逻辑以及批量循环处理。
  • 功能限制:目前不支持结构化输出(strict: true)、强制工具选择(tool_choice)、禁用并行工具调用以及 MCP 连接器提供的工具。
  • 响应格式要求:在响应挂起的编程式工具调用时,消息必须包含 tool_result 块,严禁包含任何文本内容。

3) 风险与缺口

  • 数据隐私例外:此功能受零数据保留 (ZDR) 协议的约束,数据将根据标准保留策略进行保留。
  • 超时风险:如果工具响应时间过长导致容器过期(约 4.5 分钟),代码执行将收到 TimeoutError
  • 代码注入风险:如果自定义工具返回来自外部数据源的数据或接受用户输入,且该输出在执行环境中被解释或作为代码执行,则存在代码注入风险。

正文

工具基础设施

编程式工具调用(Programmatic tool calling)允许 Claude 编写代码,在代码执行容器内以编程方式调用您的工具,而不需要每次调用工具时都通过模型进行往返交互。这降低了多工具工作流的延迟,并通过允许 Claude 在数据到达模型上下文窗口之前对其进行过滤或处理,从而减少了 Token 消耗。在测试多步网络研究和复杂信息检索的智能体搜索基准测试(如 BrowseCompDeepSearchQA)中,在基础搜索工具之上添加编程式工具调用是全面释放智能体性能的关键因素。

这种差异在实际工作流中会迅速放大。假设要检查 20 名员工的预算合规性:传统方法需要 20 次独立的模型往返交互,在此过程中会将数千个费用明细项拉入上下文中。使用编程式工具调用,只需一个脚本即可运行所有 20 次查询,过滤结果,并仅返回超出额度的员工,将 Claude 需要推理的内容从数百 KB 缩减到寥寥几行。

要深入了解编程式工具调用所解决的推理和上下文成本问题,请参阅高级工具使用

此功能需要启用代码执行(code execution)工具。

此功能零数据保留 (ZDR) 协议的约束。数据将根据该功能的标准保留策略进行保留。

模型兼容性

编程式工具调用可用于以下模型:

模型工具版本
Claude Opus 4.6 (claude-opus-4-6)code_execution_20260120
Claude Sonnet 4.6 (claude-sonnet-4-6)code_execution_20260120
Claude Sonnet 4.5 (claude-sonnet-4-5-20250929)code_execution_20260120
Claude Opus 4.5 (claude-opus-4-5-20251101)code_execution_20260120

编程式工具调用可通过 Claude API 和 Microsoft Foundry 使用。

快速入门

以下是一个简单的示例,展示了 Claude 如何以编程方式多次查询数据库并汇总结果:

编程式工具调用如何工作

当您将工具配置为可从代码执行中调用,且 Claude 决定使用该工具时:

  1. Claude 编写将工具作为函数调用的 Python 代码,其中可能包含多个工具调用以及预处理/后处理逻辑
  2. Claude 通过代码执行在一个沙盒容器中运行此代码
  3. 当工具函数被调用时,代码执行暂停,API 返回一个 tool_use
  4. 您提供工具结果,代码执行继续(中间结果不会加载到 Claude 的上下文窗口中)
  5. 一旦所有代码执行完成,Claude 接收最终输出并继续处理任务

这种方法特别适用于:

  • 大规模数据处理:在工具结果到达 Claude 上下文之前对其进行过滤或汇总
  • 多步工作流:通过串行或循环调用工具来节省 Token 和延迟,而无需在工具调用之间对 Claude 进行采样
  • 条件逻辑:根据中间工具结果做出决策

自定义工具会被转换为异步 Python 函数以支持并行工具调用。当 Claude 编写调用您工具的代码时,它会使用 await(例如,result = await query_database("<sql>"))并自动包含适当的异步包装函数。

为清晰起见,本文档的代码示例中省略了异步包装器。

核心概念

allowed_callers 字段

allowed_callers 字段指定了哪些上下文可以调用工具:

可选值:

  • ["direct"] - 只有 Claude 可以直接调用此工具(如果省略,则为默认值)
  • ["code_execution_20260120"] - 只能从代码执行内部调用
  • ["direct", "code_execution_20260120"] - 既可以直接调用,也可以从代码执行中调用

建议为每个工具选择 ["direct"]["code_execution_20260120"],而不是同时启用两者,因为这能为 Claude 提供更清晰的指导,告诉它如何最好地使用该工具。

响应中的 caller 字段

每个工具调用块都包含一个 caller 字段,指示它是如何被调用的:

直接调用(传统工具使用):

编程式调用:

tool_id 引用了进行编程式调用的代码执行工具。

容器生命周期

编程式工具调用使用与代码执行相同的容器:

  • 容器创建:除非您重用现有容器,否则会为每个会话创建一个新容器
  • 过期:容器在约 4.5 分钟不活动后过期(可能会有变动)
  • 容器 ID:通过 container 字段在响应中返回
  • 重用:传递容器 ID 以在请求之间保持状态

当以编程方式调用工具且容器正在等待您的工具结果时,您必须在容器过期之前做出响应。请监控 expires_at 字段。如果容器过期,Claude 可能会将该工具调用视为超时并重试。

示例工作流

以下是完整的编程式工具调用流程的工作原理:

第 1 步:初始请求

发送包含代码执行和允许编程式调用的工具的请求。要启用编程式调用,请在工具定义中添加 allowed_callers 字段。

在工具描述中提供有关工具输出格式的详细说明。如果您指定该工具返回 JSON,Claude 将尝试在代码中反序列化并处理该结果。您提供的输出 schema 细节越丰富,Claude 就越能以编程方式处理响应。

第 2 步:带有工具调用的 API 响应

Claude 编写调用您工具的代码。API 暂停并返回:

第 3 步:提供工具结果

包含完整的对话历史记录以及您的工具结果:

第 4 步:下一个工具调用或完成

代码执行继续并处理结果。如果需要额外的工具调用,请重复第 3 步,直到满足所有工具调用。

第 5 步:最终响应

一旦代码执行完成,Claude 将提供最终响应:

高级模式

使用循环进行批处理

Claude 可以编写高效处理多个项目的代码:

这种模式:

  • 将模型往返交互从 N 次(每个区域一次)减少到 1 次
  • 在返回给 Claude 之前以编程方式处理大型结果集
  • 通过仅返回汇总结论而不是原始数据来节省 Token

提前终止

一旦满足成功标准,Claude 就可以停止处理:

条件工具选择

数据过滤

响应格式

编程式工具调用

当代码执行调用工具时:

工具结果处理

您的工具结果将被传回正在运行的代码:

代码执行完成

当所有工具调用都得到满足且代码完成时:

错误处理

常见错误

错误描述解决方案
invalid_tool_input工具输入与 schema 不匹配验证工具的 input_schema
tool_not_allowed工具不允许请求的调用者类型检查 allowed_callers 是否包含正确的上下文
missing_beta_header未提供所需的 beta 标头在请求中添加所需的 beta 标头

工具调用期间容器过期

如果您的工具响应时间过长,代码执行将收到 TimeoutError。Claude 会在 stderr 中看到此错误,并且通常会重试:

为防止超时:

  • 监控响应中的 expires_at 字段
  • 为您的工具执行实施超时机制
  • 考虑将耗时的操作分解为更小的块

工具执行错误

如果您的工具返回错误:

Claude 的代码将收到此错误并可以进行适当处理。

约束与限制

功能不兼容

  • 结构化输出:编程式调用不支持带有 strict: true 的工具
  • 工具选择:您无法通过 tool_choice 强制对特定工具进行编程式调用
  • 并行工具使用:编程式调用不支持 disable_parallel_tool_use: true

工具限制

以下工具目前无法以编程方式调用,但可能会在未来的版本中添加支持:

消息格式限制

响应编程式工具调用时,有严格的格式要求:

仅包含工具结果的响应:如果有等待结果的挂起编程式工具调用,您的响应消息必须包含 tool_result 块。您不能包含任何文本内容,即使在工具结果之后也不行。

此限制仅适用于响应编程式(代码执行)工具调用。对于常规的客户端工具调用,您可以在工具结果之后包含文本内容。

速率限制

编程式工具调用受与常规工具调用相同的速率限制约束。来自代码执行的每次工具调用都算作一次单独的调用。

在使用前验证工具结果

在实现将被以编程方式调用的自定义工具时:

  • 工具结果以字符串形式返回:它们可以包含任何内容,包括可能被执行环境处理的代码片段或可执行命令。
  • 验证外部工具结果:如果您的工具返回来自外部数据源的数据或接受用户输入,请注意,如果输出将被解释或作为代码执行,则存在代码注入风险。

Token 效率

编程式工具调用可以显著减少 Token 消耗:

  • 编程式调用的工具结果不会添加到 Claude 的上下文中 - 只有最终的代码输出会被添加
  • 中间处理在代码中进行 - 过滤、汇总等操作不会消耗模型 Token
  • 在一次代码执行中进行多次工具调用 - 与单独的模型轮次相比,减少了开销

例如,直接调用 10 个工具所消耗的 Token 大约是以编程方式调用它们并返回摘要的 10 倍。

用量与定价

编程式工具调用使用与代码执行相同的定价。有关详细信息,请参阅代码执行定价

编程式工具调用的 Token 计数:来自编程式调用的工具结果不计入您的输入/输出 Token 用量。只有最终的代码执行结果和 Claude 的响应才会计费。

最佳实践

工具设计

  • 提供详细的输出描述:由于 Claude 会在代码中反序列化工具结果,请清楚地记录格式(JSON 结构、字段类型等)
  • 返回结构化数据:JSON 或其他易于解析的格式最适合编程式处理
  • 保持响应简洁:仅返回必要的数据以最小化处理开销

何时使用编程式调用

理想的用例:

  • 处理大型数据集,且您只需要汇总或摘要时
  • 具有 3 个以上依赖工具调用的多步工作流
  • 需要对工具结果进行过滤、排序或转换的操作
  • 中间数据不应影响 Claude 推理的任务
  • 跨多个项目的并行操作(例如,检查 50 个端点)

不太理想的用例:

  • 具有简单响应的单一工具调用
  • 需要即时用户反馈的工具
  • 非常快速的操作,其中代码执行的开销会超过其带来的好处

性能优化

  • 在发出多个相关请求时重用容器以保持状态
  • 尽可能在一次代码执行中批量处理类似操作

故障排除

常见问题

“Tool not allowed”(工具不允许)错误

  • 验证您的工具定义是否包含 "allowed_callers": ["code_execution_20260120"]

容器过期

  • 确保您在容器的生命周期内(约 4.5 分钟)响应工具调用
  • 监控响应中的 expires_at 字段
  • 考虑实现更快的工具执行

工具结果未正确解析

  • 确保您的工具返回 Claude 可以反序列化的字符串数据
  • 在您的工具描述中提供清晰的输出格式文档

调试技巧

  1. 记录所有工具调用和结果以跟踪流程
  2. 检查 caller 字段以确认是否为编程式调用
  3. 监控容器 ID以确保正确重用
  4. 在启用编程式调用之前独立测试工具

为什么编程式工具调用有效

Claude 的训练包含了对代码的广泛接触,使其能够有效地推理和链接函数调用。当工具在代码执行环境中作为可调用函数呈现时,Claude 可以利用这一优势来:

  • 自然地推理工具组合:像编写任何 Python 代码一样自然地链接操作并处理依赖关系
  • 高效处理大型结果:过滤大型工具输出,仅提取相关数据,或在将摘要返回到上下文窗口之前将中间结果写入文件
  • 显著降低延迟:消除在多步工作流中每次工具调用之间重新采样 Claude 的开销

这种方法允许 Claude 以编程方式处理数据,而不是将所有内容加载到对话上下文中,从而实现了传统工具使用无法实现的工作流(例如处理超过 100 万个 Token 的文件)。

替代实现方案

编程式工具调用是一种可泛化的模式,可以在 Anthropic 托管的代码执行之外实现。以下是这些方法的概述:

客户端直接执行

为 Claude 提供一个代码执行工具,并描述该环境中可用的函数。当 Claude 使用代码调用该工具时,您的应用程序会在定义了这些函数的本地执行它。

优点:

  • 易于实现,只需极少的架构重构
  • 对环境和指令拥有完全控制权

缺点:

  • 在沙盒外部执行不受信任的代码
  • 工具调用可能成为代码注入的媒介

适用场景: 您的应用程序可以安全地执行任意代码,您想要一个简单的解决方案,并且 Anthropic 的托管产品不符合您的需求。

自管理沙盒执行

从 Claude 的角度来看方法相同,但代码在具有安全限制(例如,无网络出口)的沙盒容器中运行。如果您的工具需要外部资源,您将需要一个协议来在沙盒外部执行工具调用。

优点:

  • 在您自己的基础设施上进行安全的编程式工具调用
  • 对执行环境拥有完全控制权

缺点:

  • 构建和维护复杂
  • 需要管理基础设施和进程间通信

适用场景: 安全性至关重要,且 Anthropic 的托管解决方案不符合您的要求。

Anthropic 托管执行

Anthropic 的编程式工具调用是沙盒执行的托管版本,具有专为 Claude 优化的预设 Python 环境。Anthropic 负责容器管理、代码执行和安全的工具调用通信。

优点:

  • 默认安全可靠
  • 易于启用,只需极少的配置
  • 针对 Claude 优化的环境和指令

如果您使用的是 Claude API,请考虑使用 Anthropic 的托管解决方案。

本页面对您有帮助吗?

关联主题