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 相比传统方式保留了 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 -- 代码化工具调用¶
问题¶
传统工具调用有两个根本缺陷:中间结果污染上下文,以及每次调用都需要完整推理。 具体来说:
- 上下文污染 -- 分析一个 10MB 的日志文件意味着整个文件内容进入上下文,即使 Claude 只需要一个错误频率统计
- 推理开销 -- 每次工具调用都需要完整的模型推理;一个五步工作流就意味着五次推理加上逐个解析结果
解决方案¶
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 让 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 为例,字段包括 title、priority、labels、reporter(含嵌套的 contact)、due_date、escalation 等。Schema 留下了诸多疑问:
due_date的格式是什么?reporter.id遵循什么 ID 约定?- 什么时候需要填
reporter.contact嵌套结构? escalation.level和escalation.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。