Anthropic Engineering Blog 中文翻译

create: 2025-11-24
update: 2026-08-10
author: thinkycx
title: 【译】Claude 开发者平台的高级工具使用
description: Anthropic 发布了三项高级工具使用特性:Tool Search Tool(按需发现工具,减少 85% token 占用)、Programmatic Tool Calling(通过代码编排工具调用,仅将最终结果写入上下文)、Tool Use Examples(通过示例教会模型正确的参数用法)。这三项特性共同解决了 Agent 在大规模工具库场景下的上下文膨胀、调用效率和参数准确性问题。
category: translation
tags: anthropic, engineering, translation, tool-use

Claude 开发者平台的高级工具使用

原文发布于 2025 年 11 月 24 日,作者 Bin Wu,Adam Jones、Artur Renault、Henry Tay、Jake Noble、Noah Picard、Sam Jiang 及 Claude 开发者平台团队参与贡献。

引言

AI Agent 的未来需要无缝对接成百上千个工具,而传统的"全量加载"方式已触及瓶颈。 Anthropic 发布了三项 beta 特性,让 Claude 能够"动态发现、学习并执行工具"。

想象一下现实场景:IDE 助手需要集成 git、文件操作、包管理器、测试框架和部署流水线;运维协调器需要连接 Slack、GitHub、Google Drive、Jira 以及数十个 MCP 服务器。这些场景面临三个核心挑战:

挑战 解决方案
Agent 需要与海量工具库协作,但无法一次性加载所有定义 Tool Search Tool -- 按需搜索发现工具
Agent 需要通过代码调用工具,而非每次调用都做一轮完整推理 Programmatic Tool Calling -- 在代码执行环境中调用工具
Agent 需要从示例中学习正确的工具用法,而不仅是 schema 定义 Tool Use Examples -- 提供示例演示正确用法

"Claude for Excel 利用 Programmatic Tool Calling 读取和修改数千行的电子表格,而不会撑爆上下文窗口。"


Tool Search Tool -- 按需搜索工具

问题

工具定义消耗的 token 远超想象,多 MCP 服务器场景下对话还没开始上下文就已经快满了。 以一个五服务器配置为例:

服务器 工具数 消耗 Token
GitHub 35 ~26K
Slack 11 ~21K
Sentry 5 ~3K
Grafana 5 ~3K
Splunk 2 ~2K

总计 58 个工具,对话开始前就消耗了约 55K token。如果再加上 Jira(~17K token),整体开销就奔 100K+ 去了。Anthropic 甚至"见过优化前工具定义消耗 134K token 的情况"。

最常见的失败模式是:工具选择错误和参数拼写错误——尤其是存在名称相似的工具时。

解决方案

不再预加载所有工具定义,而是让 Claude 按需搜索发现工具。

Tool Search Tool 工作流

Tool Search Tool 相比传统方式保留了 191,300 token 的上下文空间(传统方式仅保留 122,800)。

对比维度 传统方式 Tool Search Tool
初始加载 全量工具定义(50+ MCP 工具约 72K token) 仅加载搜索工具本身(约 500 token)
工具获取 全部预加载 按需发现(每次 3-5 个相关工具,约 3K token)
总上下文消耗 ~77K token ~8.7K token
上下文利用率 工作开始前已占用大量空间 保留 95% 上下文窗口

这意味着 85% 的 token 节省。内部测试结果:

模型 传统方式准确率 Tool Search Tool 准确率
Opus 4 49% 74%
Opus 4.5 79.5% 88.1%

工作原理

通过 defer_loading: true 标记工具为"可按需发现",Claude 只看到搜索工具本身加上未标记延迟加载的工具。

基本实现:

{
  "tools": [
    // 包含一个搜索工具(支持正则、BM25 或自定义实现)
    {"type": "tool_search_tool_regex_20251119", "name": "tool_search_tool_regex"},

    // 将工具标记为按需发现
    {
      "name": "github.createPullRequest",
      "description": "Create a pull request",
      "input_schema": {...},
      "defer_loading": true
    }
    // ... 更多标记了 defer_loading: true 的工具
  ]
}

对于 MCP 服务器,可以整体延迟加载某个服务器,同时保持特定工具始终加载:

{
  "type": "mcp_toolset",
  "mcp_server_name": "google-drive",
  "default_config": {"defer_loading": true},
  "configs": {
    "search_files": {
      "defer_loading": false
    }
  }
}

平台内置了正则和 BM25 两种搜索实现,也支持基于 embedding 的自定义实现。

Prompt 缓存说明: 延迟加载的工具完全不出现在初始 prompt 中,因此系统 prompt 和核心工具定义始终可被缓存。

适用场景

推荐使用 不太需要
工具定义消耗 >10K token 工具库较小(<10 个工具)
工具选择准确率出现问题 每次会话几乎所有工具都会用到
基于 MCP 的多服务器系统 工具定义本身非常精简
可用工具 10+ 个

Programmatic Tool Calling -- 代码化工具调用

问题

传统工具调用有两个根本缺陷:中间结果污染上下文,以及每次调用都需要完整推理。 具体来说:

  1. 上下文污染 -- 分析一个 10MB 的日志文件意味着整个文件内容进入上下文,即使 Claude 只需要一个错误频率统计
  2. 推理开销 -- 每次工具调用都需要完整的模型推理;一个五步工作流就意味着五次推理加上逐个解析结果

解决方案

Programmatic Tool Calling 让 Claude 通过编写 Python 代码来编排工具调用,只将最终结果写入上下文。

示例:预算合规性检查

任务:"哪些团队成员超出了 Q3 差旅预算?"

涉及三个工具:get_team_members(department)get_expenses(user_id, quarter)get_budget_by_level(level)

对比维度 传统方式 Programmatic Tool Calling
获取团队 1 次调用 1 次调用
获取费用 20 次调用,每次返回 50-100 行项目 并行获取,结果在代码中处理
上下文影响 2,000+ 费用项全部进入上下文(50KB+) 仅最终违规列表进入上下文(~1KB)
推理次数 多轮往返 单次代码块

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))

上下文只收到最终结果 -- 从 200KB 原始数据压缩到约 1KB。

效率提升数据:

指标 提升幅度
Token 消耗 平均从 43,588 降至 27,297(复杂研究任务降低 37%)
延迟 在编排 20+ 工具调用时消除 19+ 次推理
准确率(知识检索) 从 25.6% 提升至 28.5%
准确率(GIA 基准) 从 46.5% 提升至 51.2%

工作原理

1. 标记工具为"可通过代码调用"

{
  "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"]
    },
    {
      "name": "get_expenses",
      ...
    },
    {
      "name": "get_budget_by_level",
      ...
    }
  ]
}

2. Claude 编写编排代码

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

3. 工具在代码执行环境中运行,不触及 Claude 的上下文

工具请求包含 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"
  }
}

结果在代码执行环境中被处理,不会进入 Claude 的上下文。

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

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

适用场景

推荐使用 不太需要
处理大数据集,只需聚合/摘要结果 简单的单工具调用
多步工作流(3+ 个依赖工具调用) Claude 需要对所有中间结果进行推理的任务
在 Claude 看到结果前需要过滤/排序/转换 返回数据量小的快速查询
中间数据不应影响 Claude 推理的任务
对多个项目的并行操作

Tool Use Examples -- 工具使用示例

问题

JSON Schema 定义了结构,却无法表达使用模式——模型不知道"什么时候填什么值"。 以一个工单 API 为例,字段包括 titleprioritylabelsreporter(含嵌套的 contact)、due_dateescalation 等。Schema 留下了诸多疑问:

  • due_date 的格式是什么?
  • reporter.id 遵循什么 ID 约定?
  • 什么时候需要填 reporter.contact 嵌套结构?
  • escalation.levelescalation.sla_hours 与 priority 之间有什么关联?

解决方案

通过在工具定义中直接提供示例调用,让模型从实际用法中学习参数规范和使用模式。

{
    "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": "[email protected]",
            "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 需要完整 contact + escalation(紧凑 SLA);功能请求只需 reporter 不需要 contact/escalation;内部任务只填 title

内部测试表明,"工具使用示例将复杂参数处理的准确率从 72% 提升至 90%"。

适用场景

推荐使用 不太需要
复杂嵌套结构(合法 JSON 不等于正确用法) 简单的单参数工具
多可选参数且填写模式有讲究的工具 Claude 已经熟悉的标准格式
有领域特定约定但 schema 无法表达的 API 用 JSON Schema 约束即可解决的验证问题
名称相似的工具需要通过示例区分

最佳实践

按优先级分层应用特性

从最大的瓶颈入手,逐步叠加。

瓶颈 对应方案
工具定义导致上下文膨胀 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"
}

其他建议:
- 在系统 prompt 中描述可用能力的类别
- 保持 3-5 个最常用工具始终加载,其余延迟加载

Programmatic Tool Calling 的设置建议

清晰记录工具的返回格式,让代码能正确处理结果。

{
    "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 的设置建议

示例要真实、多样、精练。

  • 使用真实数据(真实城市名、合理价格)
  • 展示多样性:最简、部分填写、完整填写三种模式
  • 保持精练:每个工具 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
    ]
)

相关文档:


致谢

本工作建立在 Chris Gorgolewski、Daniel Jiang、Jeremy Fox 和 Mike Lambert 的基础研究之上。灵感来源于 Joel Pobar 的 LLMVM、Cloudflare 的 Code Mode 以及 Code Execution as MCP。感谢 Andy Schumeister、Hamish Kerr、Keir Bradwell、Matt Bleifer 和 Molly Vorwerck。