解决 MCP 工具数过多导致的 token 浪费和模型决策变差问题,通过核心工具直接暴露 + 搜索式工具发现实现高效缩放。
我构建了一个 MCP server,让 AI Agent 可以使用我自己的 WhatsApp:搜索聊天记录、发送消息、转写语音消息。所有服务都由我自行托管,因此消息历史永远不会离开我的设备。但最后发现,最有意思的问题其实与 WhatsApp 毫无关系,而是工具数量。
无论请求是否会用到某个工具,MCP 都会在每次请求时,把每个工具的定义注入模型的上下文。我的 server 最终增长到了 96 个工具。也就是说,在模型开始做任何事情之前,上下文中就已经塞进了大约 2 万个 token。
token 成本确实很烦人,但这并不是真正的问题。当我一次性把全部 96 个工具交给模型时,它选择正确工具的能力反而变差了,而不是变好。选项越多,出错的空间就越大。
最直观的做法是删掉一些工具,但这会损失能力。所以,我采用了另一种方式:直接提供一小组高频核心工具,同时让其余长尾工具仍可通过搜索触达。
现在,模型可以看到 29 个核心工具,以及两个元工具:
find_tool(query) 会对完整的 96 个工具库进行排序,并返回工具名称、描述和参数签名。call_tool(name, arguments) 则可以调用其中任意一个工具。常驻上下文的成本从约 2 万个 token 降到了约 8 千个,而且没有移除任何能力——所有工具都只隔着一次搜索。默认采用词法检索(IDF + 词干提取 + 同义词映射表);如果配置了 provider key,还会融合 embedding 检索结果。
call_tool 会在进程内部完成分发,绕过通常会在工具调用时执行的 middleware 链。因此,它必须重新执行这条链原本应该完成的工作:针对每个工具的 scope 权限检查和审计日志记录。如果跳过这一步,你的检索层就会悄无声息地变成绕过 scope 的通道和审计盲区。一个绕过授权机制的工具路由器,比没有路由器更加糟糕。
“感觉变好了”并不是一个数字。我准备了一个小型标注评测集(从自然语言任务到标准工具,使用确定性标签),用于衡量检索能否找到正确的工具。面对对抗性措辞时,词法检索的 recall@8 上限约为 75%;混合检索可以把它推得更高。这个评测集规模很小,而且是我自己制作的,所以应该把结果视为一种方向参考,而不是严格证明。
如果你正在把 LLM 接入一个大型 API,那么工具列表本身就是一个需要优先考虑的设计问题,而不是事后才来处理的细节。提供一组核心工具,让其余工具可以被搜索到;在分发路径中完整复刻你的授权机制;并用具体指标衡量检索效果。
代码、评测工具和设计说明见项目仓库。
至于后续操作,你可以考虑屏蔽此人和/或举报滥用行为。