跳到正文
原文
Anthropic:Engineering·· 2025-11-24精选AI 评分63

Introducing advanced tool use on the Claude Developer Platform

Introducing advanced tool use on the Claude Developer PlatformNov 24, 2025

文章要点
  • 1Anthropic 在 Claude 开发者平台发布三项 beta 功能,覆盖工具按需搜索、代码编排调用与调用示例
  • 2官方内测显示 Tool Search Tool 节省 85% token,Opus 4 在 MCP 评测准确率从 49% 升至 74%
  • 3官方内测显示 Programmatic Tool Calling 使复杂研究任务平均 token 从 43,588 降至 27,297,减少 37%
  • 4Tool Use Examples 内测将复杂参数处理准确率从 72% 提升至 90%,用于消除格式与参数歧义
决策要点

工具定义挤占上下文和逐次推理往返的问题被拆成按需加载、代码中转与示例约束,属于多工具智能体的平台级工程升级。

  • 影响:接入多服务器 MCP 或工具数上百的智能体可降低 token 开销与误调用率;三项功能均处 beta,全部效果数字来自官方内测;引入检索与代码执行步骤会带来额外延迟。
  • 参考:可考虑先盘点现有智能体的工具定义 token 占用,超过 1 万 token 或工具超过 10 个时试点 Tool Search Tool;多步工具链与大批量数据场景值得测试代码编排;参数易错的工具可补 1 至 5 个示例。
  • 依据:上下文占用与准确率数字均为 Anthropic 官方内测口径,暂无独立验证;三项功能以 beta 提供,需启用 advanced-tool-use-2025-11-20 标头。
正文 · AI 翻译

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

要构建高效的智能体,它们需要能够使用无限制的工具库,而不必将每个定义都预先塞进上下文中。我们关于在 MCP 中使用代码执行的博客文章曾讨论过,在智能体读取请求之前,工具结果和定义有时就会消耗超过 50,000 个 token。智能体应该按需发现和加载工具,只保留与当前任务相关的内容。

智能体还需要具备从代码中调用工具的能力。使用自然语言工具调用时,每次调用都需要完整的推理过程,而且无论有用与否,中间结果都会堆积在上下文中。代码天然适合编排逻辑,例如循环、条件判断和数据转换。智能体需要能够根据手头的任务,在代码执行和推理之间灵活选择。

智能体还需要从示例中学习正确的工具用法,而不仅仅是模式定义。JSON 模式定义了结构上有效的内容,但无法表达使用模式:何时包含可选参数、哪些组合有意义,或者你的 API 期望遵循什么惯例。

今天,我们发布了三项功能来实现这一目标:

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

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

根据我们的经验,我们相信这些功能为您使用 Claude 进行构建开辟了新的可能性。

Tool Search Tool

挑战

MCP 工具定义提供了重要的上下文,但随着连接的服务器增多,这些 token 会不断累积。以一个五服务器配置为例:

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

这 58 个工具在对话尚未开始时就消耗了约 55K token。如果再加上 Jira 等更多服务器(仅 Jira 一个就占用约 17K token),开销很快就会逼近 100K+ token。在 Anthropic,我们见过工具定义在优化前消耗 134K token 的情况。

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

我们的解决方案

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

Tool Search Tool diagram
与 Claude 传统方法的 122,800 相比,Tool Search Tool 保留了 191,300 个 token 的上下文。

传统方法:

  • 所有工具定义预先全部加载(50 多个 MCP 工具约占用 72K token)
  • 对话历史和系统提示词争夺剩余空间
  • 总上下文消耗:开始任何工作之前约 77K token

使用 Tool Search Tool 后:

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

这相当于在保持对完整工具库访问的同时,token 使用量减少了 85%。内部测试显示,在大型工具库下工作时,MCP 评估的准确率有显著提升。启用 Tool Search Tool 后,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.createPullRequest 和 github.listIssues 被加载——而不是你来自 Slack、Jira 和 Google Drive 的其他 50 多个工具。

这样,Claude 既能访问你的完整工具库,又只需为实际需要的工具支付 token 成本。

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

实现方式:

{
  "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 服务器,你可以延迟加载整个服务器,同时保持特定高频使用的工具处于加载状态:

{
  "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 也涉及权衡。该功能在工具调用之前增加了一个搜索步骤,因此当节省的上下文和准确率提升能够抵消额外延迟时,它的投资回报率最高。

适用场景:

  • 工具定义消耗 >10K token
  • 遇到工具选择准确率问题
  • 构建带多个服务器的 MCP 驱动系统
  • 可用工具达到 10 个以上

不太适用的情况:

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

Programmatic Tool Calling

面临的挑战

随着工作流变得更加复杂,传统的工具调用会产生两个根本性问题:

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

我们的解决方案

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

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

示例:预算合规检查

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

你可以使用三个工具:

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

传统方法:

  • 获取团队成员 → 20 人
  • 为每个人获取其第三季度费用 → 20 次工具调用,每次返回 50-100 条明细项(航班、酒店、餐费、收据)
  • 按员工级别获取预算上限
  • 所有这些都会进入 Claude 的上下文:2,000+ 条费用明细项(50 KB 以上)
  • Claude 手动汇总每个人的费用,查找其预算,并将费用与预算上限进行比较
  • 更多次往返模型,上下文消耗巨大

使用 Programmatic Tool Calling:

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

Programmatic tool calling flow
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 降至 27,297 个 token,在复杂研究任务上减少了 37%。
  • 降低延迟:每次 API 往返都需要模型推理(几百毫秒到几秒)。当 Claude 在单个代码块中编排 20+ 次工具调用时,你可以省去 19 次以上的推理过程。API 处理工具执行,无需每次都返回模型。
  • 准确度提升:通过编写显式的编排逻辑,Claude 比在自然语言中周旋于多个工具结果时出错更少。内部知识检索从 25.6% 提升至 28.5%;GIA 基准测试从 46.5% 提升至 51.2%。

生产工作流涉及杂乱的数据、条件逻辑以及需要规模化扩展的操作。Programmatic Tool Calling 让 Claude 以编程方式处理这种复杂性,同时专注于可操作的结果,而非原始数据处理。

Programmatic Tool Calling 的工作原理

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

在 tools 中添加 code_execution,并设置 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 看到的全部内容,而不是过程中处理的 2000 多条费用明细行。

何时使用 Programmatic Tool Calling

Programmatic Tool Calling 会为你的工作流增加一个代码执行步骤。当 token 节省、延迟改善和准确度提升非常可观时,这部分额外开销是值得的。

最适用的情况:

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

不太适用的情况:

  • 进行简单的单一工具调用
  • 处理 Claude 应当查看并推理所有中间结果的任务
  • 运行返回小响应的快速查询

Tool Use Examples

挑战

JSON Schema 擅长定义结构——类型、必填字段、允许的枚举值——但无法表达使用模式:何时包含可选参数、哪些组合有意义,或者你的 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"]
  }
}

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

  • 格式歧义:due_date 应该使用 "2024-11-06"、"Nov 6, 2024",还是 "2024-11-06T00:00:00Z"?
  • ID 约定:reporter.id 是 UUID、"USR-12345",还是直接 "12345"?
  • 嵌套结构使用:Claude 何时应填充 reporter.contact?
  • 参数关联:escalation.level 和 escalation.sla_hours 与优先级有什么关系?

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

我们的解决方案

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

{
    "name": "create_ticket",
    "input_schema": { /* same schema as above */ },
    "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
  • 嵌套结构模式:如何构造包含嵌套 contact 对象的 reporter 对象
  • 可选参数关联:严重 bug 包含完整联系信息 + 带 SLA 严格要求的升级流程;功能请求包含报告人但没有联系方式/升级流程;内部任务只有标题

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

何时使用 Tool Use Examples

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

最有益的情况:

  • 复杂的嵌套结构,其中合法的 JSON 并不意味着正确的用法
  • 具有许多可选参数且包含模式很重要的工具
  • 具有架构中未体现的领域特定约定的 API
  • 相似的工具,示例可以澄清该使用哪一个(例如 create_ticket 与 create_incident)

收益较小的情况:

  • 用法显而易见的简单单参数工具
  • Claude 已经能够理解的 URL 或电子邮件等标准格式
  • 由 JSON Schema 约束能更好处理的验证问题

最佳实践

构建能执行真实操作的智能体意味着要同时应对规模、复杂性和精度。这三项功能协同工作,解决工具使用工作流中的不同瓶颈。以下是如何有效组合它们的方法。

策略性地分层使用功能

并非每个智能体在给定任务中都需要使用全部三项功能。从你最大的瓶颈入手:

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

这种聚焦的方法让你能够解决限制智能体性能的具体约束,而不是预先增加复杂性。

然后根据需要叠加其他功能。它们是互补的: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"
}

添加系统提示指导,让 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 请求头并包含你需要的工具:

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 示例,请参阅我们的:

这些特性使工具使用从简单的函数调用迈向智能编排。当智能体处理跨越数十个工具和大规模数据集的更复杂工作流时,动态发现、高效执行和可靠调用便成为基础。

我们期待看到你构建的作品。

致谢

本文由 Bin Wu 撰写,Adam Jones、Artur Renault、Henry Tay、Jake Noble、Noah Picard、Sam Jiang 以及 Claude Developer Platform 团队亦有贡献。这项工作建立在 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 的支持。

来源:Anthropic:Engineering · anthropic.com