返回 文章 build CMS 文章

Anthropic 发布 Claude 开发者平台高级工具使用功能

Anthropic 发布三项高级工具使用功能,让 Claude 智能体更高效地发现、调用和正确使用工具。

ClaudeAnthropicAI智能体工具使用
成长分 / 100 76 综合收获、行动、留存与影响

Anthropic 发布 Claude 开发者平台高级工具使用功能
为什么值得读了解如何通过工具搜索工具将 token 使用量减少 85%,并显著提升工具选择准确性。

学习程序化工具调用如何让 Claude 通过代码编排工具,将上下文消耗从 200KB 降低到 1KB。

关键洞察
  1. 工具搜索工具通过按需发现工具,将 token 使用量减少 85%,并在 MCP 评估中显著提升准确性(Opus 4 从 49% 到 74%,Opus 4.5 从 79.5% 到 88.1%)。
  2. 程序化工具调用让 Claude 编写代码来编排多个工具,中间结果在代码执行环境中处理,只有最终结果返回给 Claude,大幅减少上下文消耗。
  3. 工具使用示例通过提供具体调用示例,帮助 Claude 理解使用模式,将复杂参数处理的准确率从 72% 提升到 90%。
转成行动

深入阅读

正文与原文对照

原文保真覆盖:全文原文字符:16864

获取开发者新闻通讯

产品更新、操作指南、社区聚焦等更多内容。每月发送至您的收件箱。

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

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

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

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

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

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

基于我们的经验,我们相信这些功能为您使用 Claude 构建应用开辟了新的可能性。

MCP 工具定义提供了重要的上下文,但随着更多服务器连接,这些 token 会累积。考虑一个五服务器设置:

这就是 58 个工具在对话甚至还未开始之前就消耗了大约 55K 个 token。添加更多服务器如 Jira(仅它本身就使用约 17K 个 token),您很快就会接近 100K+ 的 token 开销。在 Anthropic,我们见过工具定义在优化前消耗 134K 个 token。

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

notification-send-channel

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

传统方法:

使用工具搜索工具:

这在保持对完整工具体库访问的同时,将 token 使用量减少了 85%。内部测试显示,在处理大型工具体库时,MCP 评估的准确性有显著提升。启用工具搜索工具后,Opus 4 从 49% 提升至 74%,Opus 4.5 从 79.5% 提升至 88.1%。

工具搜索工具让 Claude 动态发现工具,而不是预先加载所有定义。你将所有工具定义提供给 API,但用 defer_loading: true 标记工具,使其可按需被发现。延迟加载的工具最初不会加载到 Claude 的上下文中。Claude 只会看到工具搜索工具本身,以及任何带有 defer_loading: false 的工具(你最关键、最常用的工具)。

当 Claude 需要特定能力时,它会搜索相关工具。工具搜索工具返回匹配工具的引用,这些引用会在 Claude 的上下文中展开为完整定义。

例如,如果 Claude 需要与 GitHub 交互,它会搜索 "github",只有 github.createPullRequestgithub.listIssues 会被加载——而不是你来自 Slack、Jira 和 Google Drive 的其他 50 多个工具。

这样,Claude 可以访问你的完整工具库,同时只需为它实际需要的工具支付 token 成本。

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

实现:

{
"tools": [
// 包含一个工具搜索工具(regex、BM25 或自定义)
{"type": "tool_search_tool_regex_20251119", "name": "tool_search_tool_regex"},
// 将工具标记为按需发现
{
"name": "github.createPullRequest",
"description": "创建拉取请求",
"input_schema": {...},
"defer_loading": true
}
// ... 还有数百个带有 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 开发者平台开箱即用地提供了基于正则表达式和基于 BM25 的搜索工具,但你也可以使用嵌入或其他策略实现自定义搜索工具。

与任何架构决策一样,启用工具搜索工具涉及权衡。该功能在工具调用之前增加了一个搜索步骤,因此当上下文节省和准确性提升超过额外延迟时,它能带来最佳的投资回报率。

适用场景:

不太适用场景:

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

程序化工具调用使 Claude 能够通过代码而非单个 API 往返来编排工具。Claude 不再一次请求一个工具并将每个结果返回到其上下文,而是编写代码来调用多个工具、处理它们的输出,并控制哪些信息实际进入其上下文窗口。

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

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

你有三个可用工具:

get_team_members(department)

  • 返回包含 ID 和级别的团队成员列表get_expenses(user_id, quarter)

  • 返回用户的费用明细项get_budget_by_level(level)

  • 返回员工级别的预算限额传统方法

使用程序化工具调用

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

以下是 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 的结果。

效率提升非常显著:

生产工作流涉及杂乱的数据、条件逻辑以及需要扩展的操作。程序化工具调用让 Claude 能够以编程方式处理这种复杂性,同时将注意力集中在可操作的结果上,而不是原始数据处理。

将 code_execution 添加到工具中,并将 allowed_callers 设置为选择加入的工具以进行程序化执行:

{
"tools": [
{
"type": "code_execution_20250825",
"name": "code_execution"
},
{
"name": "get_team_members",
"description": "获取某个部门的所有成员...",
"input_schema": {...},
"allowed_callers": ["code_execution_20250825"] # 选择启用程序化工具调用
},
{
"name": "get_expenses",
...
},
{
"name": "get_budget_by_level",
...
}
]
}

API 将这些工具定义转换为 Claude 可以调用的 Python 函数。

Claude 不再逐个请求工具,而是生成 Python 代码:

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

当代码调用 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 的上下文中处理。这个请求-响应循环会针对代码中的每次工具调用重复进行。

当代码运行完成后,只有代码的结果会返回给 Claude:

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

这就是 Claude 所看到的全部内容,而不是处理过程中经过的 2000 多个费用行项目。

程序化工具调用会在你的工作流中增加一个代码执行步骤。当 token 节省、延迟改善和准确性提升都很显著时,这一额外开销是值得的。

在以下情况下最有益:

在以下情况下益处较少:

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"]
}
}

模式定义了什么是有效的,但留下了关键问题未解答:

due_date

使用 "2024-11-06"、"Nov 6, 2024" 还是 "2024-11-06T00:00:00Z"?reporter.id

是 UUID、"USR-12345" 还是仅 "12345"?reporter.contact

escalation.level

escalation.sla_hours

与优先级有何关系?这些歧义可能导致工具调用格式错误和参数使用不一致。

工具使用示例让你直接在工具定义中提供示例工具调用。不再仅依赖模式,而是向 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 学会了:

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

工具使用示例会向你的工具定义中添加 token,因此当准确率的提升超过额外成本时,它们才最有价值。

最有益的情况:

create_ticket

对比 create_incident

不太有益的情况:

构建执行真实世界操作的智能体意味着要同时处理规模、复杂性和精确性。这三个功能协同工作,以解决工具使用工作流中的不同瓶颈。以下是如何有效地将它们组合起来。

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

这种聚焦的方法让你能够解决限制智能体性能的特定约束,而不是一开始就增加复杂性。

然后根据需要叠加其他功能。它们是互补的:工具搜索工具确保找到正确的工具,程序化工具调用确保高效执行,工具使用示例确保正确调用。

工具搜索会匹配名称和描述,因此清晰、描述性的定义能提高发现准确率。

// 好
{
"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 知道有哪些可用内容:

你可以使用 Slack 消息、Google Drive 文件管理、
Jira 工单跟踪和 GitHub 仓库操作的工具。使用工具搜索
来查找具体功能。

将你最常用的三到五个工具始终保持加载,其余工具延迟加载。这样既能保证常用操作的即时可用,又能按需发现其他所有工具。

由于 Claude 会编写代码来解析工具输出,因此要清晰地记录返回格式。这有助于 Claude 编写正确的解析逻辑:

{
"name": "get_orders",
"description": "检索客户的订单。
返回:
订单对象列表,每个对象包含:
- id (str):订单标识符
- total (float):以美元计的订单总额
- status (str):'pending'、'shipped'、'delivered' 之一
- items (list):{sku, quantity, price} 的数组
- created_at (str):ISO 8601 时间戳"
}

请参阅下文,了解可从程序化编排中受益的选择性启用工具:

为行为清晰度编写示例:

这些功能处于测试阶段。要启用它们,请添加 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 开发者平台团队。本工作建立在 Chris Gorgolewski、Daniel Jiang、Jeremy Fox 和 Mike Lambert 的基础研究之上。我们还从整个 AI 生态系统中汲取了灵感,包括 Joel Pobar 的 LLMVMCloudflare 的 Code ModeCode Execution as MCP。特别感谢 Andy Schumeister、Hamish Kerr、Keir Bradwell、Matt Bleifer 和 Molly Vorwerck 的支持。

产品更新、操作指南、社区聚焦等。每月发送到你的收件箱。