随着 Agent 能力增强,工具数量正在快速膨胀。
一个简单的聊天 Agent 可能只有几个工具:
search() calculator() weather()但进入真实生产环境后,一个企业级 Agent 往往需要接入:
- GitHub MCP
- Slack MCP
- Jira MCP
- 数据库 MCP
- 浏览器 MCP
- 云服务 MCP
- 内部业务系统 MCP
最终可能拥有数百甚至上千个工具。
问题来了:
这些工具的 schema 会占据大量上下文窗口。
Anthropic 官方提出的 Tool Search,就是为了解决这个问题。
它可以让 Claude 在大量工具环境下减少超过 85% 的工具相关 token 消耗。
但它真正优秀的地方,不只是“少放一些工具描述”,而是在上下文、Prompt Cache、约束解码三个层面同时优化。
传统 Agent:所有工具全部进入 Context
传统 Tool Calling 模式:
Request: system prompt + tools: tool_1 schema tool_2 schema tool_3 schema ... tool_1000 schema + conversation模型每次请求都会看到完整工具定义。
例如:
{"name":"database_query","description":"Execute SQL query","input_schema":{"properties":{"operation":{"enum":["select","insert","update"]}}}}这些 schema 不只是文本。
它们承担三个作用:
- 告诉模型有哪些工具
- 告诉模型参数格式
- 提供工具调用约束
当工具数量增长:
1000 tools ↓ 几十万 tokens会产生:
- Context 占用增加
- Prefill 成本增加
- KV Cache 增大
- Prompt Cache 容易失效
- 模型选择工具难度增加
Tool Search 的核心:工具定义仍然存在,但不进入模型上下文
很多人第一次理解 Tool Search 会误解:
Anthropic 是不是不发送这些工具了?
不是。
实际上:
请求中仍然包含:
tools:[github_search,mysql_query,slack_send,...]完整工具定义仍然发送给 Anthropic API。
但是:
API 会把工具分成两部分:
tools array | | +----------------+ | Tool Search Index | | Context Builder对于:
defer_loading:true的工具:
不会直接进入模型上下文。
例如:
原来:
System Prompt github schema mysql schema slack schema 1000 tools Conversation变成:
System Prompt Tool Search Conversation模型一开始根本看不到大量工具 schema。
找到工具后,API 如何加载?
用户:
查询 GitHub issue
Claude:
我需要 GitHub issue 工具调用:
tool_search("github issue")Tool Search 返回:
github_search_issue然后 API 自动插入:
tool_reference展开成:
github_search_issue 完整 schema进入后续 conversation。
于是模型下一步才看到:
{"name":"github_search_issue","parameters":{...}}然后调用工具。
最关键的问题:Prompt Cache 会不会被破坏?
这是很多 Agent 架构容易踩坑的地方。
如果简单实现:
第一次: System + 所有工具 第二次: System + 不同工具集合那么:
Prompt Cache 前缀直接失效。
因为缓存要求:
prefix token 完全一致Anthropic 的设计:
Cached Prefix: System Prompt + Tool Search Tool + 固定工具 --------------------- Dynamic Context: tool_reference 展开后的工具 schema Conversation动态工具加载发生在 prefix 后面。
因此:
缓存前缀保持稳定 ↓ Prompt Cache 继续生效这也是为什么 Tool Search 不是简单的“工具 RAG”。
另一个隐藏问题:工具 schema 还负责约束解码
很多人只关注 token。
但 Tool Schema 还有一个重要作用:
Constrained Decoding(约束解码)。
例如:
工具:
{"operation":{"enum":["select","insert","delete"]}}模型生成:
{"operation":Decoder 可以限制:
允许:
select insert delete禁止:
hello abc random流程:
JSON Schema ↓ Grammar ↓ Logits Mask ↓ Decoder那么问题来了:
如果 deferred tool 不在 context 中,
Claude 怎么知道 enum?
答案:
Tool Search 并没有移除工具 schema。
完整 tools array 仍然用于:
1. Tool Search Index 2. Strict Tool Grammar 3. Constrained Decoding也就是说:
同一个 schema 有三条路径:
Tool Schema | +------------+-------------+ | | | Search Context Decoder Index Loading Grammar这就是 Anthropic 设计强大的地方:
它不是:
删除工具 schema而是:
延迟 schema 进入模型上下文为什么不是所有模型厂商都能直接复制?
这里有一个容易忽略的问题。
很多人看到 Tool Search 后,会想:
我是不是自己写一个 tool router,把工具检索出来?
这并不完全等价。
因为 Anthropic 有 API 层支持:
完整 tools array ↓ 服务器内部: - 建索引 - 管理 tool_reference - 构建 grammar - 保持 cache prefix如果模型厂商没有类似能力,简单做:
Agent: 每轮动态修改 tools 只发送当前需要工具可能产生反效果。
例如:
第一次:
System Tool A Tool B第二次:
System Tool C Tool D结果:
Prompt Cache miss每轮都重新 prefill。
甚至:
为了减少:
tool token反而增加:
cache miss成本最终:
token下降 但 latency 上升 成本增加Tool Search 的本质:不是减少工具,而是分离三种职责
优秀 Agent 架构应该把工具 schema 分成三个用途:
Tool Schema | +------------+------------+ | | | Search Index Context Decoder 找工具 给模型看 约束生成传统方式:
一个 schema 三个任务全部塞进 ContextTool Search:
一个 schema 三个系统分别使用对 Coding Agent 的启发
未来 Coding Agent 的工具数量只会越来越多。
例如:
Filesystem MCP Git MCP Browser MCP Database MCP Cloud MCP Issue MCP CI/CD MCP如果全部进入 Context:
工具 schema 很快成为主要 token 消耗。
更合理的架构:
System Prompt | | Prompt Cache | Tool Search Index | User Intent | Retrieve Tool | Load Schema | Call Tool总结
Claude Tool Search 看似只是一个:
“减少工具 token 的功能”
但实际上解决的是 Agent 工程中的三个核心问题:
| 问题 | 传统方式 | Tool Search |
|---|---|---|
| 工具 token | 全部加载 | 按需加载 |
| Prompt Cache | 容易失效 | 保持 prefix 稳定 |
| 约束解码 | 依赖 context schema | API 保留完整 schema |
所以它减少 85% 工具 token 的真正原因不是删除工具,而是:
让工具 schema 不再同时承担 Context、搜索、解码三个职责,而是在 API 层进行分离。
这也是为什么类似设计不能简单复制到所有模型。如果底层 API 不支持 Tool Search、tool_reference 和 schema grammar 管理,盲目动态修改工具列表,很可能导致 Prompt Cache 频繁失效,最终优化变成反优化。