Claude Code 接第三方模型,一个变量最多可节省 85% Tool Schema Token
CC 接第三方模型,一个变量最多可节省 85% Tool Schema Token
如果你接入过 Claude Code(以下简称 CC)或者自己实现过 Agent,大概率都会遇到一个问题:
Tool 太多了。
几十个工具还好,一旦接入 MCP Server,一个 Server 几百个 Tool,多个 Server 上千个 Tool,Prompt 很快就会被 Tool Schema 塞满。
很多人第一反应是:
能不能按需加载 Tool?
答案是可以,这就是 Anthropic 最近推出的 Tool Search + defer_loading。
最厉害的地方不是「动态加载」,而是:
- 动态加载 Tool
- 不破坏 Prompt Cache
- 不破坏 Strict Mode Grammar
- 整个过程只需要给 Tool 增加一个字段:
{
"defer_loading": true
}
官方数据显示,在大量 Tool 的场景下,最多可以减少 85% 的 Tool Schema Token。
本文就讲清楚它到底是怎么实现的。
传统方式为什么浪费 Token?
假设你的 Agent 接入了:
GitHub
Jira
Feishu
Notion
Docker
Kubernetes
...
最终 Prompt 可能长这样:
System
Tool:
GitHub.create_issue
Tool:
GitHub.merge_pr
Tool:
GitHub.close_issue
Tool:
Jira.create_ticket
Tool:
Docker.build
...
几百个 Tool Schema
即使这一轮用户只是问:
今天天气怎么样?
所有 Tool Schema 仍然会进入 Prompt。
不仅输入 Token 很高,Prompt Cache 一旦失效,还要重新处理全部 Tool。
Tool Search 的思路
Tool Search 并不是:
需要的时候再去请求 MCP Server。
实际上:
所有 Tool Definition 一开始就已经发送给 API。
例如:
tools = [
tool_search,
github_create_issue,
github_merge_pr,
jira_create_ticket,
docker_build,
...
]
不同的是:
除了少数必须常驻的 Tool 外,其它 Tool 都增加:
{
"defer_loading": true
}
例如:
{
"name":"github_create_issue",
"defer_loading":true
}
那 Tool 去哪里了?
这里很多人第一次都会误解。
实际上:
Tool 没有消失。
而是:
API 收到完整 Tool 集之后,会做三件事情:
全部 Tool
↓
建立 Tool Registry
↓
建立 Search Index
↓
建立 Grammar
也就是说:
API 已经知道:
- 所有 Tool
- 所有 Schema
- 所有 enum
- 所有参数
但是:
不会全部放进 Prompt。
真正发送给模型的 Prompt:
System
Tool:
tool_search
只有:
- Tool Search
- 非 defer 的 Tool
其它 Tool:
全部留在 API 内部。
动态加载是如何发生的?
假设用户:
创建一个 GitHub Issue。
模型一开始:
根本不知道:
github_create_issue
长什么样。
于是:
调用:
tool_search
例如:
Regex:
github.*
或者:
BM25:
create github issue
API:
在内部 Registry 中搜索:
↓
github_create_issue
github_close_issue
然后:
把匹配到的 Tool:
以:
tool_reference
追加到 Conversation。
例如:
Assistant
tool_reference
↓
完整 Tool Schema
随后:
模型:
终于知道:
这个 Tool:
长什么样。
然后:
正常调用:
github_create_issue
整个过程:
System Prompt 没有任何修改。
为什么不会破坏 Prompt Cache?
Prompt Cache 缓存的是:
Tools
↓
System
↓
Messages
这种 Prefix。
如果:
直接修改:
System Prompt:
缓存:
立即失效。
但是:
Tool Search:
没有:
修改 Prefix。
而是:
把:
tool_reference
追加到:
Conversation History。
也就是:
Messages
最后面。
因此:
前面的:
Tools
↓
System
Prefix:
完全没变。
Prompt Cache:
继续命中。
官方文档明确说明:
Discovered tools load as
tool_referenceblocks, preserving prefix cache.
因此:
即使:
动态发现新的 Tool,
Prompt Cache:
仍然保持有效。
为什么 Strict Mode 没有失效?
很多人看到这里都会有一个疑问:
Tool 都没放进 Prompt,Grammar 怎么知道?
答案就在于:
Grammar 和 Prompt 是两套完全独立的机制。
API:
收到全部 Tool 后:
第一件事情:
就是:
全部 Tool
↓
Grammar Construction
Grammar:
始终基于:
完整 Tool 集。
即使:
defer_loading=true
Tool:
没有进入 Prompt。
Grammar:
依然已经构建完成。
官方文档原话:
Grammar builds from the full toolset regardless of which tools are deferred.
因此:
Tool Search:
不会破坏:
Grammar Cache。
当前为什么还能保证参数合法?
Strict Mode:
使用的是:
Grammar Constrained Decoding。
解码时:
Decoder:
会根据当前 Grammar:
对非法 Token:
进行:
Logits Mask。
例如:
Schema:
mode
enum:
fast
slow
模型:
就不可能:
生成:
quick
Tool:
也是一样。
当:
当前上下文:
允许:
github_create_issue
那么:
其它:
未允许调用的 Tool:
对应 Token:
都会被:
Mask。
因此:
模型:
不可能:
生成:
不存在或者当前不可用的 Tool。
为什么能节省这么多 Token?
假设:
你有:
1000 Tool
传统方式:
Prompt:
每轮:
都需要:
1000 Tool Schema
Tool Search:
初始:
可能只有:
tool_search
+
5 个常驻 Tool
真正需要:
GitHub:
再:
动态:
加载:
GitHub Tool。
如果:
这一轮:
只使用:
10 个 Tool。
那么:
Prompt:
只需要:
10 Tool Schema
而不是:
1000 Tool Schema
对于大型 MCP Server,
官方表示:
最多可以减少:
85% Tool Schema Token。
如何开启?
非常简单。
只需要:
给需要延迟加载的 Tool:
增加:
{
"defer_loading": true
}
然后:
注册:
Tool Search Tool:
例如:
tool_search_tool_regex_20251119
或者:
tool_search_tool_bm25_20251119
即可。
无需修改:
Tool Schema。
无需修改:
业务代码。
哪些模型支持?
目前,这项能力需要模型支持 Tool Search 和 defer_loading。
已确认支持:
- Claude(Anthropic)
- GLM(支持
defer_loading与 Tool Search 能力)
未来随着更多厂商跟进,预计支持 OpenAI Compatible Tool Search 的第三方模型也会逐渐增加。
如果你的 Agent 接入的是大量 MCP Server,这几乎是目前降低 Tool Token 消耗、提升 Prompt Cache 命中率最直接、成本最低的一种方案。
参考文档
https://platform.claude.com/docs/en/agents-and-tools/tool-use/tool-search-tool#quick-start
https://platform.claude.com/docs/en/agents-and-tools/tool-use/tool-use-with-prompt-caching
更多推荐

所有评论(0)