Claude Developer Platform 的高级工具使用能力¶
- 原文链接:https://www.anthropic.com/engineering/advanced-tool-use [54]
- 发布时间:2025-11-24
- 作者:Bin Wu
我们新增了三项 beta 能力,让 Claude 可以动态发现、学习并执行工具。[54]
未来的 AI 代理需要在数百甚至数千个工具之间无缝工作:IDE 助手要集成 git、文件操作、包管理、测试与部署;运维协调者要同时连接 Slack、GitHub、Google Drive、Jira、公司数据库以及多个 MCP server。[54]
要构建有效代理,它们必须在不把全部工具定义塞进上下文的前提下,仍然能使用大型工具库。我们在《Code execution with MCP》中提到,工具结果与定义可能在代理读到用户请求之前就消耗 50,000+ token。代理应该按需发现并加载工具,只保留当前任务所需的内容。[54]
代理也需要能从代码里调用工具。用自然语言调用工具时,每次调用都需要完整推理回合,而且中间结果会不断堆进上下文,不管是否有用。代码更适合做编排逻辑,比如循环、条件与数据变换。代理应能根据任务选择“写代码调用工具”还是“直接推理调用”。[54]
代理还需要从示例里学习正确的用法,而不仅是 schema 定义。JSON schema 只能描述结构合法性,却无法表达使用习惯:什么时候传可选参数、哪些组合合理、API 的约定格式是什么。[54]
今天,我们发布三项新能力:
- Tool Search Tool:让 Claude 通过搜索发现工具,不必把所有工具定义装入上下文
- Programmatic Tool Calling:让 Claude 在代码执行环境里调用工具,减少上下文污染
- Tool Use Examples:提供通用的工具调用示例格式,帮助 Claude 学会正确用法
内部测试表明,这些能力可以支撑以前做不到的系统。例如 Claude for Excel 使用 Programmatic Tool Calling 读写超大表格,而不会淹没上下文。[54]
基于这些经验,我们认为你可以用 Claude 构建出新的能力边界。[54]
Tool Search Tool¶
挑战¶
MCP 工具定义提供必要上下文,但随着 server 增多,这些 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。我们在内部看到工具定义能在优化前占用 134K token。[54]
成本不是唯一问题。最常见失败来自 选错工具 或 参数错误,尤其当工具名相近时,例如 notification-send-user 与 notification-send-channel。[54]
解决方案¶
Tool Search Tool 不再预先加载所有工具定义,而是按需发现:Claude 只看到当前任务所需的工具。[54]

图注:Tool Search Tool 相比传统方式可保留更多上下文 token。[54]
传统方式:
- 全部工具定义预加载(50+ MCP 工具约 72K tokens)
- 对话历史与系统提示争夺剩余空间
- 工作开始前上下文消耗约 77K tokens
使用 Tool Search Tool:
- 仅加载 Tool Search Tool 本身(约 500 tokens)
- 按需发现工具(3–5 个相关工具,约 3K tokens)
- 总上下文消耗约 8.7K tokens,可保留 95% 窗口
这意味着 token 使用减少 85%,同时仍可访问完整工具库。内部测试显示,在大型工具库上 MCP 评测准确率显著提升:Opus 4 从 49% 提升到 74%,Opus 4.5 从 79.5% 提升到 88.1%。[54]
Tool Search Tool 如何工作¶
你向 API 提供全部工具定义,但对需要按需加载的工具标记 defer_loading: true。Claude 初始只看到 Tool Search Tool 以及 defer_loading: false 的常用工具。当 Claude 需要能力时,先搜索工具,系统再把匹配工具的完整定义展开进上下文。[54]
例如 Claude 需要 GitHub 功能,会搜索 “github”,只展开 github.createPullRequest 和 github.listIssues,而不是把 Slack、Jira、Google Drive 的几十个工具都加载进来。[54]
提示缓存说明:延迟加载的工具不会出现在初始 prompt 中,因此不会影响 prompt cache;只有在搜索后才进入上下文。[54]
实现示例:
{
"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 server,也可整体延迟加载,并保留少量高频工具常驻:
{
"type": "mcp_toolset",
"mcp_server_name": "google-drive",
"default_config": {"defer_loading": true},
"configs": {
"search_files": {
"defer_loading": false
}
}
}
Claude Developer Platform 内置 regex 与 BM25 搜索工具,也可自行实现嵌入向量或其他策略的搜索工具。[54]
什么时候使用 Tool Search Tool¶
Tool Search Tool 会增加一个搜索步骤,所以只有在节省的上下文与准确率提升足以抵消额外延迟时才值得用。[54]
适用场景:
- 工具定义消耗 >10K tokens
- 工具选择准确率存在问题
- MCP 系统连接多个 server
- 可用工具数量 >10
不那么适合:
- 工具库很小(<10 工具)
- 每次会话都会频繁使用所有工具
- 工具定义很短
Programmatic Tool Calling¶
挑战¶
随着流程复杂度提升,传统工具调用会暴露两类根本问题:[54]
- 中间结果污染上下文:例如分析 10MB 日志,整个日志进入上下文,尽管 Claude 只需要错误频率摘要;或多表拉取客户数据时,每条记录都进入上下文。中间结果会消耗大量 token,把重要信息挤出窗口。
- 推理开销与手动合成:每次工具调用都需要一次模型推理。五个工具工作流意味着五次推理 + Claude 用自然语言“看数据、比较、合成”。这既慢又容易错。
解决方案¶
Programmatic Tool Calling 让 Claude 用代码编排工具,而不是逐次 API 往返。Claude 写代码调用多个工具、处理输出,并控制真正进入上下文的信息。[54]
Claude 擅长写代码,把编排逻辑写在 Python 里能得到更可靠的控制流:循环、条件、变换与错误处理都在代码中显式表达,而不是隐含在推理中。[54]
示例:预算合规检查¶
任务:找出“Q3 出差预算超标的团队成员”。工具包括:
get_team_members(department):返回成员列表、ID、级别get_expenses(user_id, quarter):返回该用户的费用明细get_budget_by_level(level):返回该级别预算
传统方式:
- 拉取 20 个成员
- 对每个人拉取 Q3 费用(20 次调用,50–100 行明细)
- 拉取预算
- 2,000+ 行费用明细进入上下文(50KB+)
- Claude 手动汇总、比较、推理
- 多次往返,token 消耗巨大
Programmatic Tool Calling:
Claude 写 Python 脚本在 Code Execution 环境编排整个流程。工具结果进入脚本而非上下文,Claude 只看到最终输出。[54]
示例代码:
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–3 个超标人员。2,000+ 明细与中间求和不会影响上下文,从 200KB 原始数据降到约 1KB。[54]
效率提升:
- Token 节省:复杂研究任务平均 token 从 43,588 降到 27,297,减少 37%。
- 延迟降低:多次工具调用由一次代码执行替代,消除大量推理往返。
- 准确率提升:显式编排减少错误,内部检索准确率从 25.6% 提升到 28.5%;GIA 基准从 46.5% 提升到 51.2%。[54]
生产场景数据杂乱、逻辑复杂,Programmatic Tool Calling 让 Claude 用程序化方式处理复杂度,同时保持上下文聚焦在可执行结果。[54]

图注:Programmatic Tool Calling 通过代码编排工具调用,支持并行执行,减少模型推理回合。[54]
Programmatic Tool Calling 如何工作¶
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 会把工具定义转换为 Python 函数供 Claude 调用。[54]
2. Claude 生成编排代码¶
Claude 不再逐次调用工具,而是生成 Python 代码:
{
"type": "server_tool_use",
"id": "srvtoolu_abc",
"name": "code_execution",
"input": {
"code": "team = get_team_members('engineering')\n..."
}
}
3. 工具在不进入上下文的情况下执行¶
当代码调用 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 上下文。[54]
4. 只有最终输出进入上下文¶
{
"type": "code_execution_tool_result",
"tool_use_id": "srvtoolu_abc",
"content": {
"stdout": "[{\"name\": \"Alice\", \"spent\": 12500, \"limit\": 10000}...]"
}
}
Claude 只看到最终输出,而不是 2,000+ 中间明细。[54]
什么时候使用 Programmatic Tool Calling¶
它会增加一次代码执行步骤,因此只有当 token 节省、延迟改善和准确率提升足够大时才值得用。[54]
适用场景:
- 处理大数据集,只需聚合或摘要
- 多步工作流(3+ 依赖工具调用)
- 在 Claude 看到数据前进行过滤/排序/变换
- 中间数据不应影响 Claude 推理
- 需要并行处理多个项目(如检查 50 个端点)
不适合:
- 单一工具调用即可完成
- Claude 需要看到全部中间结果
- 快速查询、响应很小
Tool Use Examples¶
挑战¶
JSON Schema 擅长描述结构,但无法表达使用模式:何时传可选参数、哪些组合合理、API 约定的格式是什么。[54]
例如一个工单 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”? - 嵌套结构何时使用:什么时候填
reporter.contact? - 参数关联:
escalation.level与escalation.sla_hours与优先级关系如何?
这些歧义会导致工具调用格式错误或参数使用不一致。[54]
解决方案¶
Tool Use Examples 允许你在工具定义里提供示例调用,让 Claude 学会正确用法。[54]
{
"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
- 嵌套结构模式:如何构造 reporter 及其 contact
- 参数关联:严重 bug 会包含完整联系信息 + escalation;功能请求则没有 escalation;内部任务只有标题
内部测试中,工具示例把复杂参数准确率从 72% 提升到 90%。[54]
什么时候使用 Tool Use Examples¶
Tool Use Examples 会增加工具定义 token,因此只有准确率收益大于成本时才值得用。[54]
适用场景:
- 嵌套结构复杂,合法 JSON 仍不代表正确用法
- 可选参数多,包含模式很重要
- Schema 无法覆盖的领域约定
- 相似工具需要示例区分(如
create_ticketvscreate_incident)
不适合:
- 只有单一参数的简单工具
- URL/email 等标准格式(模型已懂)
- 更适合用 schema 约束的验证问题
最佳实践¶
构建能执行真实动作的代理,必须同时处理规模、复杂度与精度。三个能力分别解决不同瓶颈,应组合使用。[54]
分层使用能力¶
先找最大瓶颈:
- 工具定义导致上下文膨胀 → Tool Search Tool
- 大量中间结果污染上下文 → Programmatic Tool Calling
- 参数错误、调用格式不对 → Tool Use Examples
先解决限制性能的那一项,再逐步叠加其他能力。三者互补:Tool Search Tool 确保“找得到”,Programmatic Tool Calling 确保“执行高效”,Tool Use Examples 确保“调用正确”。[54]
用 Tool Search Tool 提升发现率¶
搜索基于名字与描述匹配,因此要写清晰、具体的定义:[54]
// 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.
保持 3–5 个最常用工具常驻,其余按需加载,兼顾即时性与节省上下文。[54]
用 Programmatic Tool Calling 确保执行正确¶
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"
}
适合 programmatic 编排的工具包括:
- 可并行执行的工具
- 可安全重试的操作(幂等)[54]
用 Tool Use Examples 提升参数准确性¶
编写示例时:
- 用真实感数据(真实城市名、合理价格)
- 展示最小、部分与完整三种模式
- 保持简洁(每个工具 1–5 个示例)
- 重点覆盖“容易歧义”的部分[54]
Getting started¶
这些功能目前处于 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 示例见:
这些能力把工具使用从“简单函数调用”推向“智能编排”。随着代理需要处理更复杂的工作流、更多工具与更大数据集,动态发现、高效执行与可靠调用将成为基础能力。我们期待看到你基于 Claude 构建的系统。[54]
致谢¶
作者 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 的基础研究,并从 LLMVM、Cloudflare Code Mode 与 Code Execution as MCP 等项目获得启发。感谢 Andy Schumeister、Hamish Kerr、Keir Bradwell、Matt Bleifer、Molly Vorwerck 的支持。[54]