MCP服务器工具schemas每次请求都完整发送255个工具占71929 tokens,Skills目录全部加载占110万tokens,两者都是可优化的结构性开销。
大家开始查第一张账单了。几乎没人发现还有第二张。
我说的意思是:打开你的 Agent 上下文,在你输入任何一个字符之前,数数已经加载了多少内容。这里有两项,它们来自两个不同的地方:
MCP 工具的 schema。每个已连接的服务器都会把其暴露的每个工具的完整 JSON 描述发送过来。
Agent 技能。你 skills 目录里的每一份 SKILL.md,都会整体加载进来。
我用 tiktoken(OpenAI 官方分词器)和 cl100k_base 编码测量了这两项。工具那边已经够糟了。技能这边更糟。而这两个问题可以用同一个思路解决。
连接足够多的 MCP 服务器,光是工具描述就会吃掉你上下文窗口的很大一块。我用 255 个工具的目录做了基准测量。渲染成完整的 JSON schema,总共 71,929 个 token。
而且这不是一次性成本。每次请求都会重新发送这份 manifest。在一个会话里问十几个问题,你就要付十几倍的账单。
原因在于结构。选一个工具只需要知道它的名字。你不需要完整的 schema 来决定要不要调用某个东西。但默认的链路在每次请求时都会预先把 schema 发过来,而且是每个工具都发。所以你为那些你基本不会打开的文档付了费。
技能这边更庞大,因为它本身就是更大的东西。工具是名字加 schema。技能是整篇文档:指令、示例、工作流程、检查清单。当把目录暴露为"读你需要的 SKILL.md"时,朴素实现就会把整个目录都读一遍。
在这台机器上,skills 目录里有 418 个技能。把所有 SKILL.md 拼接起来,总共 1,109,242 个 token。
这塞不进任何上下文窗口,所以大多数做法都是做了看起来很谨慎、但实际上并没有的事:加载一部分——凭 Agent 猜测它需要什么,每次请求付几千个 token,永远如此。你察觉不到,因为账单分散在很多看起来合理的细小决定里。
这个洞见一旦看清,就变得相当平淡无奇了:选择某样东西只需要知道它的名字。
你不需要工具的完整 schema 来决定要不要调用它。
你不需要技能的完整文本来决定要不要读它。
所以先暴露名字,按需再取正文。
工具。255 个工具只保留名字的索引只有 581 个 token。相比原来的 71,929,减少了 99.2%。完整的 schema 只在你真正调用一个工具时才到达。
技能。一个常驻指针,39 个 token,取代了整个目录。一次查询返回少数几个匹配的技能,这次查询花 501 个 token。你只在最终选中的技能上才读完整的 SKILL.md。思路相同,账单不同。
指针的全部职责就一句话:不要加载目录,而是请求匹配项,然后只读那些文件。
我把这个做成了 mcptoon,一个零依赖的 CLI。它纯用 Python 标准库,227KB,让每个服务器和每个技能都保持配置好且可寻址,同时把它们的完整文本挡在上下文窗口之外。mcptoon manifest 给你工具的仅名字视图。mcptoon skills resolve "<你想做的事>" 把最佳匹配的技能以 JSON 形式返回。没有预装任何东西,在你选择之前什么也不会加载。
别拿我的目录当你的。税赋随你接入的东西等比增长,修复方案也一样。
统计你实际携带的内容。加载你真正的工具列表和真正的 skills 目录,用 tiktoken 处理一遍,然后把完整内容与仅名字的视图比较。如果差距很大,你就有一张值得削减的账单。如果差距很小,就不必折腾。
测量才是关键所在。这也是几乎所有人都跳过的步骤——所以第二张账单长期无人察觉。
如果你只跑几个服务器和十几个技能,这些都不重要。税赋真实存在但很小,而网关又是需要维护的另一个东西。不要为了优化而优化。
我的经验法则:先审计,只有当测量结果表明你的上下文确实拥挤时,才考虑上名字索引层。
工具 schema 这边现在已经是一个已知问题。Anthropic 自己的工程文章提出了这个论点,Firecrawl 的基准测试也测量了同一任务:CLI 方式 1,365 个 token,MCP 方式 44,026 个 token,相差 32 倍。这个讨论正在进行。
技能这边则没有。为什么技能比工具消耗更大——因为技能是文档,而不是 schema。
所以我想在评论区得到一个答案:当你的 Agent 加载一个技能时,它加载的是指针,还是整个文件?如果你测量过这个数字,我很想看看,因为我怀疑大多数人在从未见到账单的情况下支付着第二张账单。
mcptoon 是开源的。按名字搜索。上面的数字是针对上述工具和技能目录的 tiktoken cl100k_base 测量结果。技能的数字反映的是一台机器上 418 个技能的目录,所以请把它当作一个量级参考,而不是一个常数。你自己运行 mcptoon status 会打印出你的数字。