原文: English original · Anthropic/OpenAI 官方

Claude Developer Platform 高级工具使用功能介绍

发布于 2025 年 11 月 24 日

我们新增了三项 beta 功能,让 Claude 能够动态发现、学习并执行工具。下面介绍它们的工作方式。

AI agents 的未来,是模型能够在数百甚至数千个工具之间无缝工作。比如,一个 IDE 助手可以集成 git 操作、文件操作、包管理器、测试框架和部署流水线;一个运维协调员可以同时连接 Slack、GitHub、Google Drive、Jira、公司数据库以及几十个 MCP servers。

要构建有效的 agents,就需要让它们使用规模不受限制的工具库,而不是一开始就把每个工具定义都塞进上下文。我们在关于用 MCP 进行代码执行的文章中讨论过,工具结果和定义有时会在 agent 读取请求之前就消耗 50,000+ tokens。agents 应该按需发现和加载工具,只保留当前任务相关的内容。

agents 还需要能够从代码中调用工具。使用自然语言工具调用时,每次调用都需要完整的一轮推理,中间结果无论是否有用,都会堆进上下文。代码天然适合表达编排逻辑,例如循环、条件和数据转换。agents 需要根据手头任务,在代码执行和模型推理之间灵活选择。

agents 也需要从示例中学习正确的工具用法,而不能只依赖模式定义。JSON 模式能定义结构上什么是有效的,但无法表达使用模式:什么时候应该包含可选参数,哪些组合有意义,或者你的 API 期望遵循什么约定。

今天,我们发布三项功能,让这些能力成为可能:

  • Tool Search Tool:允许 Claude 使用搜索工具访问数千个工具,而不消耗它的上下文窗口
  • Programmatic Tool Calling:允许 Claude 在代码执行环境中调用工具,降低对模型上下文窗口的影响
  • Tool Use Examples:提供一种通用标准,用来展示如何有效使用某个给定工具

在内部测试中,我们发现这些功能帮助我们构建出了传统工具使用模式下无法实现的东西。例如,Claude for Excel 使用 Programmatic Tool Calling 读取和修改包含数千行数据的电子表格,而不会让模型上下文窗口过载。

基于我们的经验,我们相信这些功能会为你用 Claude 构建的内容打开新的可能性。

Tool Search Tool

挑战

MCP 工具定义提供了重要上下文,但连接的 servers 越多,这些 tokens 就越会累积。以一个连接五个 servers 的配置为例:

  • GitHub:35 个工具(约 26K tokens)
  • Slack:11 个工具(约 21K tokens)
  • Sentry:5 个工具(约 3K tokens)
  • Grafana:5 个工具(约 3K tokens)
  • Splunk:2 个工具(约 2K tokens)

这 58 个工具在对话开始前就会消耗大约 55K tokens。再加上 Jira 这样的 servers(仅 Jira 就会使用约 17K tokens),很快就会接近 100K+ tokens 的开销。在 Anthropic,我们见过优化前工具定义消耗 134K tokens 的情况。

但 token 成本并不是唯一问题。最常见的失败是选错工具和参数不正确,尤其是当工具名称相似时,比如 notification-send-usernotification-send-channel

我们的方案

Tool Search Tool 不再预先加载所有工具定义,而是按需发现工具。Claude 只会看到当前任务真正需要的工具。

图片:Tool Search Tool 图示

与 Claude 传统方法只能保留 122,800 tokens 上下文相比,Tool Search Tool 可以保留 191,300 tokens 上下文。

传统方法:

  • 预先加载所有工具定义(50+ 个 MCP 工具约 72K tokens)
  • 对话历史和 system prompt 争夺剩余空间
  • 总上下文消耗:任何工作开始前约 77K tokens

使用 Tool Search Tool:

  • 预先只加载 Tool Search Tool(约 500 tokens)
  • 按需发现工具(3-5 个相关工具,约 3K tokens)
  • 总上下文消耗:约 8.7K tokens,保留 95% 的上下文窗口

这意味着 token 使用量减少 85%,同时仍可访问完整工具库。内部测试显示,在处理大型工具库时,启用 Tool Search Tool 能显著提升 MCP 评测准确率。Opus 4 从 49% 提升到 74%,Opus 4.5 从 79.5% 提升到 88.1%。

Tool Search Tool 如何工作

Tool Search Tool 让 Claude 动态发现工具,而不是预先加载所有定义。你向 API 提供全部工具定义,但用 defer_loading: true 标记工具,使它们可以按需发现。延迟加载的工具最初不会加载进 Claude 的上下文。Claude 一开始只会看到 Tool Search Tool 本身,以及任何 defer_loading: false 的工具,也就是你最关键、最常用的工具。

当 Claude 需要特定能力时,它会搜索相关工具。Tool Search Tool 会返回匹配工具的引用,然后这些引用会在 Claude 的上下文中展开成完整定义。

例如,如果 Claude 需要与 GitHub 交互,它会搜索 “github”,然后只有 github.createPullRequestgithub.listIssues 会被加载,而不是 Slack、Jira 和 Google Drive 中其他 50+ 个工具。

这样,Claude 可以访问完整工具库,同时只为实际需要的工具支付 token 成本。

Prompt cache 说明:Tool Search Tool 不会破坏 prompt cache,因为延迟加载的工具会完全排除在初始 prompt 之外。它们只会在 Claude 搜索之后才被加入上下文,因此你的 system prompt 和核心工具定义仍然可以缓存。

实现方式:

{
  "tools": [
    // Include a tool search tool (regex, BM25, or custom)
    {"type": "tool_search_tool_regex_20251119", "name": "tool_search_tool_regex"},

    // Mark tools for on-demand discovery
    {
      "name": "github.createPullRequest",
      "description": "Create a pull request",
      "input_schema": {...},
      "defer_loading": true
    }
    // ... hundreds more deferred tools with defer_loading: true
  ]
}

对于 MCP servers,你可以延迟加载整个 server,同时让特定高频工具保持已加载:

{
  "type": "mcp_toolset",
  "mcp_server_name": "google-drive",
  "default_config": {"defer_loading": true}, # defer loading the entire server
  "configs": {
    "search_files": {
      "defer_loading": false
    }  // Keep most used tool loaded
  }
}

Claude Developer Platform 开箱提供基于正则和基于 BM25 的搜索工具,但你也可以使用 embeddings 或其他策略实现自定义搜索工具。

何时使用 Tool Search Tool

和任何架构决策一样,启用 Tool Search Tool 涉及权衡。这个功能会在工具调用前增加一个搜索步骤,因此当上下文节省和准确率提升超过额外延迟时,它的 ROI 最好。

适合使用的情况:

  • 工具定义消耗 >10K tokens
  • 遇到工具选择准确率问题
  • 构建由 MCP 驱动、连接多个 servers 的系统
  • 可用工具数量达到 10+ 个

收益较小的情况:

  • 小型工具库(<10 个工具)
  • 每次会话都频繁使用所有工具
  • 工具定义很紧凑

Programmatic Tool Calling

挑战

随着任务流程变得更复杂,传统工具调用会产生两个根本问题:

  • 中间结果造成上下文污染:当 Claude 分析一个 10MB 日志文件以寻找错误模式时,整个文件都会进入它的上下文窗口,尽管 Claude 只需要错误频率摘要。当跨多张表获取客户数据时,每条记录都会在上下文中累积,无论是否相关。这些中间结果会消耗大量 token 预算,甚至可能把重要信息完全挤出上下文窗口。
  • 推理开销和手工综合:每个工具调用都需要完整的一轮模型推理。收到结果后,Claude 必须“目测”数据来提取相关信息,推理各部分如何拼接,并决定下一步怎么做,而这一切都通过自然语言处理完成。一个五工具流程意味着五轮推理,再加上 Claude 解析每个结果、比较值并综合结论。这既慢又容易出错。

我们的方案

Programmatic Tool Calling 让 Claude 通过代码编排工具,而不是通过一次次单独的 API 往返来完成调用。Claude 不再一次请求一个工具、再把每个结果返回到上下文,而是编写代码调用多个工具、处理它们的输出,并控制哪些信息真正进入它的上下文窗口。

Claude 擅长编写代码。让它用 Python 表达编排逻辑,而不是通过自然语言工具调用来表达,你可以获得更可靠、更精确的控制流。循环、条件、数据转换和错误处理都会在代码中显式呈现,而不是隐含在 Claude 的推理中。

示例:预算合规检查

考虑一个常见业务任务:“哪些团队成员超出了 Q3 差旅预算?”

你有三个可用工具:

  • get_team_members(department) - 返回包含 ID 和级别的团队成员列表
  • get_expenses(user_id, quarter) - 返回某个用户的费用明细项
  • get_budget_by_level(level) - 返回某个员工级别的预算上限

传统方法:

  • 获取团队成员 → 20 人
  • 对每个人获取他们的 Q3 费用 → 20 次工具调用,每次返回 50-100 条明细项(机票、酒店、餐饮、收据)
  • 按员工级别获取预算上限
  • 所有这些都会进入 Claude 的上下文:2,000+ 条费用明细项(50 KB+)
  • Claude 手工汇总每个人的费用,查询他们的预算,将费用与预算上限比较
  • 需要更多模型往返,并显著消耗上下文

使用 Programmatic Tool Calling:

Claude 不再让每个工具结果都返回给自己,而是编写一个 Python 脚本来编排整个流程。该脚本在 Code Execution 工具(一个沙盒环境)中运行,需要你的工具结果时会暂停。当你通过 API 返回工具结果时,它们会由脚本处理,而不是被模型消耗。脚本继续执行,Claude 只看到最终输出。

图片:Programmatic tool calling 流程

Programmatic Tool Calling 让 Claude 通过代码而不是单独的 API 往返来编排工具,从而支持并行执行工具。

下面是 Claude 为预算合规任务编写的编排代码:

team = await get_team_members("engineering")
# Fetch budgets for each unique level
levels = list(set(m["level"] for m in team))
budget_results = await asyncio.gather(*[
    get_budget_by_level(level) for level in levels
])

# Create a lookup dictionary: {"junior": budget1, "senior": budget2, ...}
budgets = {level: budget for level, budget in zip(levels, budget_results)}

# Fetch all expenses in parallel
expenses = await asyncio.gather(*[
    get_expenses(m["id"], "Q3") for m in team
])
# Find employees who exceeded their travel budget
exceeded = []
for member, exp in zip(team, expenses):
    budget = budgets[member["level"]]
    total = sum(e["amount"] for e in exp)
    if total > budget["travel_limit"]:
        exceeded.append({
            "name": member["name"],
            "spent": total,
            "limit": budget["travel_limit"]
        })

print(json.dumps(exceeded))

Claude 的上下文只接收最终结果:超出预算的两三个人。2,000+ 条明细项、中间汇总和预算查询都不会影响 Claude 的上下文,将消耗从 200KB 原始费用数据降低到仅 1KB 结果。

效率收益很可观:

  • Token 节省:通过让中间结果不进入 Claude 的上下文,PTC 显著降低 token 消耗。在复杂研究任务中,平均使用量从 43,588 tokens 降到 27,297 tokens,减少 37%。
  • 延迟降低:每次 API 往返都需要模型推理(数百毫秒到数秒)。当 Claude 在一个代码块中编排 20+ 次工具调用时,你就消除了 19+ 轮推理。API 会处理工具执行,不必每次都返回模型。
  • 准确率提升:通过编写显式编排逻辑,Claude 比用自然语言同时处理多个工具结果时犯错更少。内部知识检索从 25.6% 提升到 28.5%;GIA 基准从 46.5% 提升到 51.2%。

生产级流程会涉及混乱数据、条件逻辑以及需要扩展的操作。Programmatic Tool Calling 让 Claude 能以编程方式处理这种复杂性,同时把注意力放在可执行结果上,而不是原始数据处理上。

Programmatic Tool Calling 如何工作

1. 将工具标记为可从代码调用

code_execution 加到 tools 中,并设置 allowed_callers,让工具选择加入程序化执行:

{
  "tools": [
    {
      "type": "code_execution_20250825",
      "name": "code_execution"
    },
    {
      "name": "get_team_members",
      "description": "Get all members of a department...",
      "input_schema": {...},
      "allowed_callers": ["code_execution_20250825"] # opt-in to programmatic tool calling
    },
    {
      "name": "get_expenses",
      ...
    },
    {
      "name": "get_budget_by_level",
      ...
    }
  ]
}

API 会把这些工具定义转换成 Claude 可以调用的 Python 函数。

2. Claude 编写编排代码

Claude 不再一次请求一个工具,而是生成 Python 代码:

{
  "type": "server_tool_use",
  "id": "srvtoolu_abc",
  "name": "code_execution",
  "input": {
    "code": "team = get_team_members('engineering')\n..." # the code example above
  }
}

3. 工具执行时不进入 Claude 的上下文

当代码调用 get_expenses() 时,你会收到一个包含 caller 字段的工具请求:

{
  "type": "tool_use",
  "id": "toolu_xyz",
  "name": "get_expenses",
  "input": {"user_id": "emp_123", "quarter": "Q3"},
  "caller": {
    "type": "code_execution_20250825",
    "tool_id": "srvtoolu_abc"
  }
}

你提供结果,结果会在 Code Execution 环境中被处理,而不是进入 Claude 的上下文。代码中的每次工具调用都会重复这个请求-响应循环。

4. 只有最终输出进入上下文

代码运行结束时,只有代码结果会返回给 Claude:

{
  "type": "code_execution_tool_result",
  "tool_use_id": "srvtoolu_abc",
  "content": {
    "stdout": "[{\"name\": \"Alice\", \"spent\": 12500, \"limit\": 10000}...]"
  }
}

这就是 Claude 看到的全部内容,而不是过程中处理的 2,000+ 条费用明细项。

何时使用 Programmatic Tool Calling

Programmatic Tool Calling 会在你的流程中增加一个代码执行步骤。当 token 节省、延迟改善和准确率提升都很可观时,这个额外开销是值得的。

最有收益的情况:

  • 处理大型数据集,而你只需要聚合结果或摘要
  • 运行包含三个或更多依赖工具调用的多步骤流程
  • 在 Claude 看到工具结果之前,对其进行过滤、排序或转换
  • 处理中间数据不应影响 Claude 推理的任务
  • 针对许多项目运行并行操作(例如检查 50 个端点)

收益较小的情况:

  • 发起简单的单工具调用
  • 处理 Claude 应该看到并推理所有中间结果的任务
  • 运行返回很小的快速查询

Tool Use Examples

挑战

JSON 模式擅长定义结构:类型、必需字段、允许的枚举值,但它无法表达使用模式:什么时候包含可选参数,哪些组合有意义,或者你的 API 期望遵循什么约定。

考虑一个支持工单 API:

{
  "name": "create_ticket",
  "input_schema": {
    "properties": {
      "title": {"type": "string"},
      "priority": {"enum": ["low", "medium", "high", "critical"]},
      "labels": {"type": "array", "items": {"type": "string"}},
      "reporter": {
        "type": "object",
        "properties": {
          "id": {"type": "string"},
          "name": {"type": "string"},
          "contact": {
            "type": "object",
            "properties": {
              "email": {"type": "string"},
              "phone": {"type": "string"}
            }
          }
        }
      },
      "due_date": {"type": "string"},
      "escalation": {
        "type": "object",
        "properties": {
          "level": {"type": "integer"},
          "notify_manager": {"type": "boolean"},
          "sla_hours": {"type": "integer"}
        }
      }
    },
    "required": ["title"]
  }
}

这个模式定义了什么是有效的,但留下了一些关键问题没有回答:

  • 格式歧义:due_date 应该使用 “2024-11-06”、“Nov 6, 2024”,还是 “2024-11-06T00:00:00Z”?
  • ID 约定:reporter.id 是 UUID、“USR-12345”,还是只是 “12345”?
  • 嵌套结构用法:Claude 什么时候应该填充 reporter.contact
  • 参数相关性:escalation.levelescalation.sla_hours 如何与优先级相关?

这些歧义可能导致格式错误的工具调用和不一致的参数使用。

我们的方案

Tool Use Examples 让你可以直接在工具定义中提供示例工具调用。你不再只依赖模式,而是向 Claude 展示具体使用模式:

{
  "name": "create_ticket",
  "input_schema": { /* 与上方相同的模式 */ },
  "input_examples": [
    {
      "title": "Login page returns 500 error",
      "priority": "critical",
      "labels": ["bug", "authentication", "production"],
      "reporter": {
        "id": "USR-12345",
        "name": "Jane Smith",
        "contact": {
          "email": "jane@acme.com",
          "phone": "+1-555-0123"
        }
      },
      "due_date": "2024-11-06",
      "escalation": {
        "level": 2,
        "notify_manager": true,
        "sla_hours": 4
      }
    },
    {
      "title": "Add dark mode support",
      "labels": ["feature-request", "ui"],
      "reporter": {
        "id": "USR-67890",
        "name": "Alex Chen"
      }
    },
    {
      "title": "Update API documentation"
    }
  ]
}

通过这三个示例,Claude 学到:

  • 格式约定:日期使用 YYYY-MM-DD,用户 ID 遵循 USR-XXXXX,标签使用 kebab-case
  • 嵌套结构模式:如何构造 reporter 对象及其嵌套的 contact 对象
  • 可选参数相关性:严重 bug 会包含完整联系信息和严格 SLA 的升级设置;功能请求会包含 reporter 但没有 contact/escalation;内部任务只有 title

在我们自己的内部测试中,工具使用示例将复杂参数处理的准确率从 72% 提升到 90%。

何时使用 Tool Use Examples

Tool Use Examples 会给你的工具定义增加 tokens,因此当准确率提升超过额外成本时,它们最有价值。

最有收益的情况:

  • 复杂嵌套结构中,有效 JSON 并不意味着正确用法
  • 工具有许多可选参数,而且包含模式很重要
  • API 有模式无法捕捉的领域特定约定
  • 对于相似工具,示例可以澄清应该使用哪一个(例如 create_ticketcreate_incident

收益较小的情况:

  • 用法明显的简单单参数工具
  • Claude 已经理解的标准格式,例如 URL 或 email
  • 更适合由 JSON 模式约束处理的验证问题

最佳实践

构建能在真实世界中采取行动的 agents,意味着要同时处理规模、复杂性和精确性。这三项功能共同解决工具使用流程中的不同瓶颈。下面介绍如何有效组合它们。

有策略地叠加功能

不是每个 agent 在给定任务中都需要使用全部三项功能。先从你最大的瓶颈开始:

  • 工具定义造成上下文膨胀 → Tool Search Tool
  • 大型中间结果污染上下文 → Programmatic Tool Calling
  • 参数错误和格式错误的调用 → Tool Use Examples

这种聚焦的方法让你能够解决限制 agent 性能的具体约束,而不是一开始就增加复杂性。

然后根据需要叠加其他功能。它们是互补的:Tool Search Tool 确保找到正确工具,Programmatic Tool Calling 确保高效执行,Tool Use Examples 确保正确调用。

设置 Tool Search Tool 以改善发现

工具搜索会匹配名称和描述,因此清晰、描述性强的定义可以提高发现准确率。

// Good
{
  "name": "search_customer_orders",
  "description": "Search for customer orders by date range, status, or total amount. Returns order details including items, shipping, and payment info."
}

// Bad
{
  "name": "query_db_orders",
  "description": "Execute order query"
}

添加 system prompt 指导,让 Claude 知道有哪些可用能力:

You have access to tools for Slack messaging, Google Drive file management,
Jira ticket tracking, and GitHub repository operations. Use the tool search
to find specific capabilities.

让三到五个最常用工具始终保持加载,其余工具延迟加载。这样能在常见操作的即时访问与其他一切能力的按需发现之间取得平衡。

设置 Programmatic Tool Calling 以确保正确执行

由于 Claude 会编写代码来解析工具输出,因此要清楚记录返回格式。这有助于 Claude 编写正确的解析逻辑:

{
  "name": "get_orders",
  "description": "Retrieve orders for a customer.
Returns:
  List of order objects, each containing:
  - id (str): Order identifier
  - total (float): Order total in USD
  - status (str): One of 'pending', 'shipped', 'delivered'
  - items (list): Array of {sku, quantity, price}
  - created_at (str): ISO 8601 timestamp"
}

下面这些工具适合选择加入程序化编排:

  • 可以并行运行的工具(独立操作)
  • 可以安全重试的操作(幂等)

设置 Tool Use Examples 以提升参数准确率

为行为清晰度设计示例:

  • 使用真实数据(真实城市名、可信价格,而不是 “string” 或 “value”)
  • 展示多样性,包括最小、部分和完整规格模式
  • 保持简洁:每个工具 1-5 个示例
  • 聚焦歧义(只有当正确用法无法从模式中明显看出时才添加示例)

开始使用

这些功能目前处于 beta。要启用它们,请添加 beta header,并包含你需要的工具:

client.beta.messages.create(
    betas=["advanced-tool-use-2025-11-20"],
    model="claude-sonnet-4-5-20250929",
    max_tokens=4096,
    tools=[
        {"type": "tool_search_tool_regex_20251119", "name": "tool_search_tool_regex"},
        {"type": "code_execution_20250825", "name": "code_execution"},
        # Your tools with defer_loading, allowed_callers, and input_examples
    ]
)

有关详细 API 文档和 SDK 示例,请参阅:

  • Tool Search Tool 文档和 cookbook
  • Programmatic Tool Calling 文档和 cookbook
  • Tool Use Examples 文档

这些功能把工具使用从简单的函数调用推进到智能编排。随着 agents 处理跨越几十个工具和大型数据集的更复杂流程,动态发现、高效执行和可靠调用会成为基础能力。

我们期待看到你构建的成果。

致谢

本文由 Bin Wu 撰写,Adam Jones、Artur Renault、Henry Tay、Jake Noble、Noah Picard、Sam Jiang 和 Claude Developer Platform team 参与贡献。这项工作建立在 Chris Gorgolewski、Daniel Jiang、Jeremy Fox 和 Mike Lambert 的基础研究之上。我们也从整个 AI 生态中获得了灵感,包括 Joel Pobar 的 LLMVM、Cloudflare 的 Code Mode 和 Code Execution as MCP。

特别感谢 Andy Schumeister、Hamish Kerr、Keir Bradwell、Matt Bleifer 和 Molly Vorwerck 的支持。