MCP 工具按需加载能省多少上下文
文章对比一次注入 32 个 MCP 工具定义与按需搜索加载,报告后者减少了 92.7% 的输入 token。实验使用特定模型和隔离环境,摘录尚未展示完整成绩及任务成功率变化。
AI 深度解读
MCP 接得越多,AI 编程助手就越好用吗?这篇实验提醒我们:工具还没调用,工具的 JSON Schema 就可能先占掉大段上下文;工具名称相近,还会让模型选错入口。作者把「每轮塞入全部工具定义」改成「先搜索,再加载需要的定义」,累计输入 token 减少了 92.7%。
这个结果值得看,但不能直接当成所有 MCP 项目的收益承诺。实验同时减少了工具定义、过滤了干扰工具,两组最终也都通过了全部测试。真正可借鉴的,是工具如何进入上下文,以及如何验证这套机制有效。
工具还没执行,为什么已经产生了成本
模型调用工具之前,需要知道工具叫什么、什么时候用、参数怎么填。JSON Schema 就是这份说明书。接入多个 MCP 服务后,说明书也会不断增加。
作者称,详细定义平均每个工具约占 700 到 800 tokens。如果把 32 个工具定义全部放进提示词,即使任务只需要其中两个,其余定义也会一起进入模型输入。
工具定义只提供给模型阅读,也会消耗上下文和输入 token。
实验中的 Mode A 名为 MonolithicSchema,每轮都注入全部 32 个工具定义。第一轮输入达到 25,646 tokens,之后两轮分别是 26,397 和 27,730,累计 79,773。
这里需要区分统计口径:这些是整轮输入量,不是单独测出的 Schema 大小。作者将主要开销归因于工具定义,但所给正文没有展示逐项拆分,不能把全部输入都算成工具说明书。
另一项成本来自误选。工具列表里既有正式入口,也有名称相近的旧版和预发布入口。模型第一轮调用了 verify_legacy_v1_router,第二轮又调用了 patch_staging_mirror_files,直到第三轮才调用 submit_remediation_bundle。
说明书越多,未必越容易找到正确按钮。
按需加载省下的,不只有说明书
Mode B 名为 ProgressiveToolSearch。它第一轮只提供一个约 120 tokens 的元工具 search_tools,让模型先表达需求:
search_tools(query="remediation")
这次搜索调用生成了 22 个输出 tokens,随后只加载任务需要的两个正式工具定义。32 个候选工具中,28 个无关工具、2 个旧版或预发布干扰工具被排除。
这里的「渐进式工具披露」,可以理解为先查目录,再拿到对应说明书。模型不用一开始就阅读整个工具仓库。
作者据此建议在搜索处理器中执行 status == "PRODUCTION_ACTIVE" 过滤,让不该使用的入口根本不进入上下文。按需加载解决信息量问题,状态过滤解决候选资格问题,两者作用不同。
实验任务是修复由 router.py、remediator.py、dossier.py 组成的三模块云事件分诊与 SLA 补救流水线。Mode B 第一轮搜索,第二轮通过 submit_remediation_bundle 一次提交三个文件;Mode A 则经历了两次干扰工具误调用。
因此,收益不能全部归功于「少加载了几个 Schema」。搜索同时改变了模型能看到的候选集合,也缩短了完成任务所需的轮数。
多一次搜索,为什么反而快了
作者给出的结果如下:
| 指标 | 全量注入 | 按需搜索 |
|---|---|---|
| 第一轮输入 tokens | 25,646 | 2,544 |
| 累计输入 tokens | 79,773 | 5,844 |
| 干扰工具误调用 | 2 次 | 0 次 |
| API 成本 | $0.0737 | $0.0112 |
| 执行时间 | 37.00 秒 | 19.06 秒 |
| 隐藏测试通过数 | 20/20 | 20/20 |
第一轮输入减少 90.1%,累计输入减少 92.7%,相当于缩减到原来的约 1/13.65。API 成本下降 84.8%,耗时下降 48.5%,速度约为原来的 1.94 倍。
多一次搜索会增加往返,但总耗时还取决于模型要处理多少输入、是否选错工具,以及需要补救多少轮。这次实验中,额外搜索带来的开销,小于减少输入和误调用所节省的时间。
两组在隐藏评测 labjudge14 中都通过了 20 个用例,所以这里观察到的是完成同一任务的效率差异,没有体现最终测试通过率的提升。
实验编号为 E14,候选编号 C010,在作者的 41 种模式中排名第 5。运行使用 gemini-3.8-flash,参数为 thinkingLevel: LOW;环境是 Proxmox VM218,配置包括 0 NICs、virtio-serial QGA 中继和 systemd UID 分离。
原文用 Claude Code 的 ENABLE_TOOL_SEARCH=auto 描述所测模式,但公开的模型配置是 Gemini。这份结果支持按需发现工具的设计思路,不能直接视为 Claude Code 在相同条件下的实测收益。
我的判断
我赞成把「工具发现」单独设计。尤其当仓库里保留了历史工具、测试入口和名称相似的操作时,把它们全部交给模型判断,会增加不必要的选择负担。在搜索层维护状态,比指望模型每次读懂弃用说明更可靠。
不过,这份实验把两项改动绑在了一起:减少 Schema,以及过滤干扰工具。若要判断各自贡献,还需要增加一组「全量注入,但事先排除旧版和预发布工具」的对照。
原文展示的是一次运行 e14-20261028-vm218-01,分析了 seq 0..4 共 5 次 LLM 调用,没有提供重复运行次数、波动范围或其他模型的结果。92.7% 是这次配置下的观测值。
作者提出「不要预先注入超过 10 个完整工具定义」,并建议工具超过 10–15 个时切换方案,但没有给出逐步增加工具数量的对照数据。这个门槛属于经验之谈。工具描述长度、名称区分度和任务复杂度,都可能改变转折点。
按需加载也依赖搜索质量。搜索漏掉必要工具,或者状态标记过期,模型就可能拿不到正确入口。对于数量少、用途明确的工具集,直接注入仍然简单;工具多且按业务分组明显时,搜索或预先选择工具子集才更有吸引力。
能拿来做什么
- 给日常 AI 编程助手做一次工具盘点,记录每轮注入多少定义、占多少输入 tokens,以及旧版和测试工具是否仍在候选列表中。
- 如果在 Node 中实现 MCP 搜索或分发层,可以先提供
search_tools,再按任务加载定义;同时在处理器里执行正式状态过滤,不只依赖工具名称里的提示。 - 用自己的代表性任务对比全量注入和按需加载,统一模型与参数,至少记录累计输入、误调用、总耗时和测试结果,区分节省成本与提高正确率。
- 评估
ENABLE_TOOL_SEARCH=auto或search_tools/call_mcp_tool分发方案时,把「搜不到必要工具」也列入检查范围,确认搜索结果能覆盖任务所需能力。