跳到主要内容

MCP Server 蔓延:无人监管的无边界工具表面

· 阅读需 10 分钟
Tian Pan
Software Engineer

Model Context Protocol (MCP) 正如其初衷所愿:它让赋予智能体(agent)新能力变得几乎零成本。接入日历服务器、数据库服务器、公司内部服务器,或是厂商现今发布的 30,000 个工具目录中的任何一个,都只是一个配置更改,而不是一个开发项目。这种无摩擦感是其特性,但也是问题所在。

正因为添加工具的成本极低,每个团队都在添加工具。数据团队接入了仓库服务器。支持团队添加了工单服务器。有人为了某次性任务连接了文件系统服务器后就再也没移除。这些决策本身都没有错。但没有任何一个决策者对这些工具的“总和”负责——即你的智能体在每次请求中携带的聚合工具表面(tool surface)。工具列表已变成了一个具有实际持有成本的依赖图,而在大多数组织中,这是唯一一个无人负责的依赖图。

结果就是蔓延:工具目录单调递增,无人审查,每季度成本都在上涨,并悄悄地让智能体变得更糟。这就是无人负责的表面,它理应受到和你对待 API 表面以及 npm 树同等程度的审视。

无论是否运行,列表中的每个工具都在计费

蔓延的第一项成本是团队最容易低估的,因为它并不出现在他们习惯关注的地方。一个你从未调用过的工具,依然会在每一轮对话中消耗你的成本。

每个连接的 MCP 工具都会将其名称、描述、JSON schema、字段文档和枚举值贡献到模型的上下文(context)中。估算值因工具复杂度而异,但单个工具通常会消耗 500 到 1,400 个 token 的纯定义。将这一数字乘以一个中等连接密度的智能体,数值会迅速攀升:一项对实际部署的调查发现,在处理第一条用户消息之前,81 个工具就已经消耗了超过 20,000 个 token。其他测量的配置情况更糟——三个服务器在 200,000 token 的窗口中烧掉了 143,000 个,仅为实际对话、检索文档和推理留下了大约四分之一的上下文空间。

这里被打破的直觉是,人们认为能力披露(capability disclosure)是一次性的设置成本。事实并非如此。智能体在进行的每一步规划中,工具定义都会被重新发送。一个运行八个推理步(reasoning hops)来完成任务的智能体,要支付八次全额的能力披露费用。token 成本随连接服务器的数量呈线性增长,而第八个服务器带来的边际用户价值却趋于平缓。这更像是一种税收,而非投资。

它还破坏了一些更细微的东西:你的提示词缓存(prompt cache)。缓存断点(Cache breakpoints)需要稳定的前缀。当工具披露块位于该前缀中间,且某个团队添加或删除了一个服务器时,该点下游的缓存键就会失效。你的命中率会下降,而没有人会将其与上周那个“无害”的集成联系起来。

更多工具不会让智能体优雅降级——而是会毁掉它

如果 token 税就是全部问题,你大可以通过更大的上下文窗口来解决。更棘手的问题是,蔓延会攻击准确性,而且这种攻击是断崖式的,而非渐进式的。

当研究人员针对臃肿的目录测量工具选择准确性时,准确度并没有“礼貌地”侵蚀,而是直接崩溃了——随着工具集的增加,准确率从约 43% 下降到 14% 以下,退化了三倍。对照测试显示了同样的断崖:在 10 个工具时,选择几乎完美;在 20 个工具时,强大的模型仍能拿到 20 分中的 19 分;而在大约 100 个以上工具时,无论大模型还是小模型都彻底失败了。超过某个阈值后,模型并不会随着每个新工具的加入而稍微变差,而是会直接失效。

其机制与导致长提示词偏离任务的指令遵循(instruction-following)退化相同。模型的注意力是有限的,而你正将其分散到数百个描述相似的选项中。它开始混淆工具间的参数,更糟的是,还会臆造不存在的工具名称。

蔓延通过引入冲突使得这一问题变得异常严峻。对近 1,500 个 MCP 服务器的调查发现了 775 个工具名称冲突:search 这个名称出现在 32 个不同的服务器中,而 get_userexecute_query 各出现了 11 次。精确匹配冲突只是冰山一角——语义上的近乎重复(如 "find_customer" 与 "lookup_contact" 与 "get_account")对选择的干扰同样严重,而且永远不会触发名称冲突检查。当你的智能体选错了 search 时,下游评估(eval)会归咎于模型。但模型并不是问题所在,工具目录才是。

加载中…
References:Let's stay in touch and Follow me for more thoughts and updates