使用本地大语言模型 (LLM) 的开发者发现,单个 Multi-Channel-Protocol (MCP) 服务器甚至在用户输入提示词之前,就会耗尽整个上下文窗口。他们必须在功能受限的工具描述和中断的对话流之间做出选择。
为什么 Token 膨胀对本地 LLM 至关重要
MCP 通过向模型提供每个工具的描述,让 LLM 能够调用外部工具——API、脚本或文件系统实用程序。拥有 128k Token 窗口的云端模型可以吸收许多工具定义,并仍为用户对话留出空间。而运行在本地、拥有 8k Token 窗口的 70 亿参数模型,在加载几个工具后就会耗尽空间。这种权衡是残酷的:简短、廉价的描述会导致调用路由错误;而冗长、详细的描述则会消耗掉聊天所需的预算。
导致这一现状的连锁反应
MCP 的设计初衷是用单一的模型驱动接口取代针对多种数据源的自定义集成代码。大多数 MCP 服务器实际上是围绕 REST 端点构建的薄封装,这些端点是为人类操作员设计的,而非机器。当这些封装进入本地 LLM 会话时,模型在决定调用哪一个工具之前,必须阅读每个工具的名称、参数和使用说明。微小的上下文窗口将这种“描述开销”变成了结构性的瓶颈。
谁是赢家,谁是输家
- 构建端侧助手的开发者失去了灵活性。他们要么修剪工具目录,面临频繁失败的风险;要么接受臃肿的提示词,从而导致用户输入被截断。
- 终端用户会遇到助手选择错误工具或因上下文已满而拒绝执行时的不稳定行为。
- 工具提供商获得了一个统一的入口点。
这不仅仅是体验变差的问题,它还引发了安全担忧。当 MCP 代理可以读取任何本地文件时,权限模型就坍塌成了“全有或全无”。如果没有沙箱机制,配置错误的工具可能会暴露整个文件系统。
开发者正在如何应对
社区中主要存在三种权宜之计:
- 精简描述 – 将工具元数据削减到最低限度。这释放了 Token,但增加了模型选错端点的概率,导致开发者必须捕获并重试错误。
- 动态加载 – 仅加载与当前对话相关的工具子集。一个轻量级的调度器会根据用户意图决定注入哪组工具。这减少了闲置 Token 的使用,但增加了延迟和代码复杂度。
- 限制活跃服务器 – 限制每个会话中的 MCP 服务器数量,迫使开发者优先考虑最核心的集成。这使提示词大小保持在可控范围内,但牺牲了能力的广度。
这些解决方案都不是万灵丹。削减描述会损害可靠性;动态加载增加了一个减慢响应速度的决策层;限制服务器则迫使开发者在支持哪些数据源方面做出艰难的选择。
随 Token 问题而来的安全风险
本地代理通常以不受限制的文件系统访问权限运行。MCP 协议在“读取此文件夹”和“读取一切”之间没有提供粒度控制。一些团队构建了网关层来解决全权限问题,但这增加了更多复杂性。这些网关缓解了“完全控制”的问题,但也增加了代码库。
为小模型设计工具
大型云端模型可以从错误的描述中恢复,因此开发者有时会忽视精确工具定义的需求。对于本地模型,请遵循以下原则:
- 功能单一 – 每个工具应该只做一件事。一个既能“搜索”又能“写入文件”的工具会干扰无法追踪重叠职责的模型。
- 命名明确 – 避免使用像 “process” 或 “handle” 这样通用的名称。名称应传达确切的操作,以减轻模型的认知负担。
- 清晰、简洁的描述 – 仅包含模型做出决策真正需要的参数。使用一致的格式,以便模型能够快速识别模式。
不同观点:该协议仍有价值
尽管存在摩擦,MCP 仍然具有吸引力,因为它抽象掉了样板代码。单一的模型驱动接口可以连接到数十种服务,而无需为每种服务编写自定义适配器。能够负担得起云端规模模型的团队认为 Token 膨胀不是问题,便利性超过了开销。挑战在于如何将这种便利性转化为受限的端侧 LLM 世界。
总结
如果你正在构建端侧助手,请将 MCP 工具描述视为一种稀缺资源。通过精简、动态加载以及设计作用域较窄的工具,来为实际对话保留足够的上下文窗口空间。与此同时,即便会多消耗一些 token,也要通过引入权限层来防范隐含的“全权限”安全模型。你所达成的平衡,将决定你的本地 LLM 表现得像是一个得力的助手,还是一个蹩脚的聊天机器人。
