Claude 开发者平台高级工具使用详解
Claude 开发者平台高级工具使用详解
原文链接: https://www.anthropic.com/engineering/advanced-tool-use
发布日期: 2025年11月24日
我们在 Claude 开发者平台上添加了三个新的 beta 功能,让 Claude 能够动态发现、学习和执行工具。本文将详细介绍它们的工作原理。
引言
AI 代理的未来是模型能够无缝地与数百甚至数千个工具协同工作。想象一个 IDE 助手,它可以集成 git 操作、文件操作、包管理器、测试框架和部署管道。或者一个运维协调器,它可以同时连接 Slack、GitHub、Google Drive、Jira、公司数据库以及数十个 MCP 服务器。
要构建有效的代理,它们需要能够使用无限的工具库,而不是预先将所有工具定义塞入上下文。我们关于使用 MCP 进行代码执行的博客文章讨论过,工具结果和定义有时会在代理读取请求之前就消耗 50,000+ 个 token。代理应该按需发现和加载工具,只保留与当前任务相关的内容。
代理还需要能够从代码中调用工具。使用自然语言工具调用时,每次调用都需要完整的推理过程,中间结果会在上下文中堆积,无论它们是否有用。代码天然适合编排逻辑,例如循环、条件判断和数据转换。代理需要根据手头任务灵活选择代码执行还是推理。
代理还需要从示例中学习正确的工具使用方式,而不仅仅是从 schema 定义中学习。JSON schema 定义了什么是结构上有效的,但无法表达使用模式:何时包含可选参数、哪些组合有意义,或者你的 API 期望什么约定。
今天,我们发布了三个使这一切成为可能的功能:
-
• Tool Search Tool(工具搜索工具):允许 Claude 使用搜索工具访问数千个工具,而不消耗其上下文窗口 -
• Programmatic Tool Calling(编程式工具调用):允许 Claude 在代码执行环境中调用工具,减少对模型上下文窗口的影响 -
• Tool Use Examples(工具使用示例):提供一个通用标准来演示如何有效使用给定工具
在内部测试中,我们发现这些功能帮助我们构建了使用传统工具使用模式无法实现的东西。例如,Claude for Excel 使用编程式工具调用来读取和修改包含数千行的电子表格,而不会使模型的上下文窗口过载。
基于我们的经验,我们相信这些功能为你使用 Claude 构建应用开辟了新的可能性。
💡 三大功能概览
Tool Search Tool(工具搜索工具)
挑战
MCP 工具定义提供了重要的上下文信息,但随着更多服务器连接,这些 token 会快速累积。考虑一个五服务器配置:
-
• GitHub:35 个工具(约 26K tokens) -
• Slack:11 个工具(约 21K tokens) -
• Sentry:5 个工具(约 3K tokens) -
• Grafana:5 个工具(约 3K tokens) -
• Splunk:2 个工具(约 2K tokens)
这是 58 个工具,在对话开始之前就消耗了大约 55K tokens。再加上像 Jira(仅其自身就使用约 17K tokens)这样的服务器,你很快就会接近 100K+ token 的开销。在 Anthropic,我们见过优化前工具定义消耗 134K tokens 的情况。
但 token 成本不是唯一的问题。最常见的失败是错误的工具选择和不正确的参数,特别是当工具名称相似时,比如 notification-send-user 与 notification-send-channel。
💡 Token 消耗对比
|
|
|
|
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 总计 | 58 | ~55K |
我们的解决方案
Tool Search Tool 不是预先加载所有工具定义,而是按需发现工具。Claude 只看到它当前任务实际需要的工具。

Tool Search Tool 保留了 191,300 tokens 的上下文,而 Claude 传统方法为 122,800 tokens。
传统方法:
-
• 所有工具定义预先加载(50+ 个 MCP 工具约 72K tokens) -
• 对话历史和系统提示词争夺剩余空间 -
• 总上下文消耗:在任何工作开始之前约 77K tokens
使用 Tool Search Tool:
-
• 只预先加载 Tool Search Tool(约 500 tokens) -
• 按需发现工具(3-5 个相关工具,约 3K tokens) -
• 总上下文消耗:约 8.7K tokens,保留 95% 的上下文窗口
这代表了 85% 的 token 使用量减少,同时保持对完整工具库的访问。内部测试显示,在处理大型工具库时,MCP 评估的准确性有显著提升。Opus 4 从 49% 提升到 74%,Opus 4.5 从 79.5% 提升到 88.1%(启用 Tool Search Tool 后)。
💡 传统方法 vs Tool Search Tool
|
|
|
|
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
85% |
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 成本。
Prompt 缓存说明: Tool Search Tool 不会破坏 prompt 缓存,因为延迟加载的工具完全被排除在初始 prompt 之外。它们只在 Claude 搜索后才添加到上下文中,所以你的系统提示词和核心工具定义仍然可缓存。
💡 Tool Search Tool 工作流程
是
否
实现方式:
{ "tools": [ // 包含一个工具搜索工具(regex、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 // 保持最常用的工具已加载 } }}
Claude 开发者平台提供了开箱即用的基于正则表达式和 BM25 的搜索工具,但你也可以使用嵌入向量或其他策略实现自定义搜索工具。
何时使用 Tool Search Tool
像任何架构决策一样,启用 Tool Search Tool 需要权衡取舍。该功能在工具调用之前添加了一个搜索步骤,因此当上下文节省和准确性提升超过额外延迟时,它能提供最佳投资回报。
适用场景:
-
• 工具定义消耗 >10K tokens -
• 遇到工具选择准确性问题 -
• 构建具有多个服务器的 MCP 驱动系统 -
• 可用工具超过 10 个
收益较小的场景:
-
• 小型工具库(<10 个工具) -
• 所有工具在每个会话中都频繁使用 -
• 工具定义紧凑
💡 Tool Search Tool 适用性判断
是
否
是
否
是
否
是
否
Programmatic Tool Calling(编程式工具调用)
挑战
传统工具调用随着工作流变得更复杂会产生两个基本问题:
-
• 中间结果的上下文污染:当 Claude 分析一个 10MB 的日志文件来寻找错误模式时,整个文件都会进入其上下文窗口,尽管 Claude 只需要错误频率的摘要。当跨多个表获取客户数据时,每条记录都会在上下文中累积,无论是否相关。这些中间结果消耗大量 token 预算,可能将重要信息完全推出上下文窗口。 -
• 推理开销和手动综合:每次工具调用都需要完整的模型推理过程。收到结果后,Claude 必须”目视”数据以提取相关信息,推理各部分如何组合在一起,并决定下一步做什么——所有这些都通过自然语言处理完成。一个五步工具工作流意味着五次推理过程,加上 Claude 解析每个结果、比较值和综合结论。这既慢又容易出错。
我们的解决方案
编程式工具调用使 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 手动汇总每个人的费用,查找其预算,将费用与预算限制进行比较 -
• 更多的模型往返,显著的上下文消耗
使用编程式工具调用:
Claude 不再将每个工具结果返回给自己,而是编写一个 Python 脚本来编排整个工作流。脚本在代码执行工具(沙箱环境)中运行,当需要工具结果时暂停。当你通过 API 返回工具结果时,它们由脚本处理,而不是被模型消费。脚本继续执行,Claude 只看到最终输出。

编程式工具调用使 Claude 能够通过代码而非单独的 API 往返来编排工具,支持并行工具执行。
以下是 Claude 针对预算合规任务的编排代码:
team = await get_team_members("engineering")# 为每个唯一级别获取预算levels = list(set(m["level"] for m in team))budget_results = await asyncio.gather(*[ get_budget_by_level(level) for level in levels])# 创建查找字典:{"junior": budget1, "senior": budget2, ...}budgets = {level: budget for level, budget in zip(levels, budget_results)}# 并行获取所有费用expenses = await asyncio.gather(*[ get_expenses(m["id"], "Q3") for m in team])# 找出超出差旅预算的员工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 tokens,在复杂研究任务上减少了 37%。 -
• 延迟减少:每次 API 往返都需要模型推理(数百毫秒到几秒)。当 Claude 在单个代码块中编排 20+ 个工具调用时,你消除了 19+ 次推理过程。API 处理工具执行而无需每次都返回模型。 -
• 准确性提升:通过编写显式编排逻辑,Claude 比用自然语言处理多个工具结果时犯更少的错误。内部知识检索从 25.6% 提升到 28.5%;GIA 基准测试从 46.5% 提升到 51.2%。
生产工作流涉及混乱的数据、条件逻辑和需要扩展的操作。编程式工具调用让 Claude 以编程方式处理这些复杂性,同时将其注意力集中在可操作的结果上,而不是原始数据处理。
💡 传统方法 vs 编程式工具调用对比
|
|
|
|
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
编程式工具调用的工作原理
1. 将工具标记为可从代码调用
将 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"] // 选择性启用编程式工具调用 }, { "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..." // 上面的代码示例 }}
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" }}
你提供结果,它在代码执行环境中处理而不是在 Claude 的上下文中。这个请求-响应循环对代码中的每个工具调用重复。
4. 只有最终输出进入上下文
当代码执行完成时,只有代码的结果返回给 Claude:
{ "type": "code_execution_tool_result", "tool_use_id": "srvtoolu_abc", "content": { "stdout": "[{\"name\": \"Alice\", \"spent\": 12500, \"limit\": 10000}...]" }}
这就是 Claude 看到的全部,而不是处理过程中的 2000+ 个费用明细项。
💡 编程式工具调用执行流程
是
否
何时使用编程式工具调用
编程式工具调用为你的工作流添加了代码执行步骤。当 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如何与优先级关联?
这些歧义可能导致格式错误的工具调用和不一致的参数使用。
我们的解决方案
工具使用示例让你直接在工具定义中提供示例工具调用。与其只依赖 schema,你可以向 Claude 展示具体的使用模式:
{ "name": "create_ticket", "input_schema": { /* 与上面相同的 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 -
• 嵌套结构模式:如何构建带有嵌套 contact 对象的 reporter 对象 -
• 可选参数关联:关键 bug 有完整的联系信息 + 紧急 SLA 的升级;功能请求有 reporter 但没有 contact/escalation;内部任务只有标题
在我们自己的内部测试中,工具使用示例在复杂参数处理上将准确率从 72% 提升到 90%。
💡 示例覆盖的不同场景
|
|
|
|
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
何时使用工具使用示例
工具使用示例会向你的工具定义添加 token,所以当准确性提升超过额外成本时,它们最有价值。
最有益的场景:
-
• 复杂的嵌套结构,其中有效的 JSON 并不意味着正确的使用 -
• 具有许多可选参数且包含模式很重要的工具 -
• 具有 schema 中未捕获的领域特定约定的 API -
• 示例有助于澄清使用哪个的相似工具(例如 create_ticketvscreate_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
工具搜索根据名称和描述匹配,所以清晰、描述性的定义提高发现准确性。
// 好的例子{ "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."}// 差的例子{ "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 个示例 -
• 聚焦于歧义(只在正确使用从 schema 看不明显时添加示例)
💡 最佳实践总结
|
|
|
|
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
开始使用
这些功能以 beta 版本提供。要启用它们,添加 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"}, # 你的带有 defer_loading、allowed_callers 和 input_examples 的工具 ])
有关详细的 API 文档和 SDK 示例,请参阅我们的:
-
• Tool Search Tool 的文档和 cookbook -
• Programmatic Tool Calling 的文档和 cookbook -
• Tool Use Examples 的文档
这些功能将工具使用从简单的函数调用推向智能编排。随着代理处理跨越数十个工具和大型数据集的更复杂工作流,动态发现、高效执行和可靠调用成为基础。
我们很期待看到你构建什么。
致谢
由 Bin Wu 撰写,Adam Jones、Artur Renault、Henry Tay、Jake Noble、Nathan McCandlish、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 的支持。
📝 总结
核心要点
-
1. Tool Search Tool 通过按需发现工具实现 85% 的 token 节省,同时显著提升工具选择准确性(Opus 4.5 从 79.5% 提升到 88.1%) -
2. Programmatic Tool Calling 让 Claude 用代码编排工具调用,中间结果不进入上下文,实现 37% 的 token 减少和更高的执行准确性 -
3. Tool Use Examples 通过具体示例教会 Claude 正确的参数格式和使用模式,将复杂参数处理准确率从 72% 提升到 90% -
4. 三个功能互补:Tool Search Tool 确保找到正确工具,Programmatic Tool Calling 确保高效执行,Tool Use Examples 确保正确调用 -
5. 根据主要瓶颈选择性使用功能,而非一次性启用所有功能
原文作者: Bin Wu 及 Claude Developer Platform 团队
夜雨聆风