我最近对两个功能相同的MCP进行了测试,结果发现其中一个性能非常差。因此,我想分享导致这种情况的糟糕MCP设计模式。
一切始于我为一个待办事项应用程序编写的MCP服务器(MCP-A)。后来,该应用程序正式发布了自己的MCP服务器(MCP-B)。这两个MCP具有相同的功能,并且都调用相同的后端API。
实验设置如下:
- 两个MCP服务器连接到同一个待办事项账户,并在每次测试后重置。
- 40个测试提示,以模拟这些MCP的典型用例。
- 测试使用相同的模型、系统提示和代理框架进行。
以下是结果:
| 指标 | MCP-A | MCP-B | 差距 |
| ------------------- | ----------- | ----------- | ----- |
| 工具描述长度 | 11,464 | 3,682 | — |
| 通过率 | 36/40 (90%) | 36/40 (90%) | 相同 |
| 总输入标记 | 637,244 | 3,174,329 | 4.98× |
| 总输出标记 | 17,301 | 23,238 | 1.34× |
| 总代理步骤 | 122 | 157 | 1.29× |
| 总时间 | 597秒 | 676秒 | 1.13× |
结果显示,MCP-B完成40个测试用例比MCP-A多用了35个ReAct循环,这意味着输出标记多了30%。我检查了日志,发现根本原因是查询工具设计不佳。
以`search tool`为例,它的工作是查找待办事项列表中的待办项。在MCP-B中,该工具返回如下内容:
{
"id": "6a1916b48f08cb3a4c857ed0",
"title": "买些杂货",
"url": "https://todo.example.com/tasks/6a1916b48f08cb3a4c857ed0"
}
但其他CRUD操作需要`project_id`,而`search_tool`并没有返回它。因此,代理必须调用另一个工具`get_task_by_id`。另一方面,MCP-A的query_tasks在一次调用中返回了执行下一个操作所需的所有信息:
任务1:
ID: 6a19143e8f084a8c8101612f
标题: 买些杂货
项目ID: 6a1914378f084a8c810160a9
开始日期: 2025-07-19 10:00:00
优先级: 中
状态: 活动
未过滤的API数据被转存到上下文窗口中。
如果MCP将未经处理的纯API结果返回给代理的上下文,代理的上下文窗口将快速累积。
以MCP-B的`create_task`工具为例。它的工作是创建一个待办事项。该工具返回如下内容:
{
"id": "6a180de78f086bdead0608be",
"projectId": "inbox125587327",
.....
"createdTime": "2026-05-28T09:41:59+0000",
"modifiedTime": "2026-05-28T09:41:59+0000",
"focusSummaries": null
}
这些600多个字符对代理的任务毫无意义,但仍然被转存到代理的上下文中。另一方面,MCP-A的create_tasks进行了过滤和格式化。这一小改动在输入标记的使用上产生了巨大的差异。
另一个问题是工具数量。工具越多,模型可选择的候选集就越大,这直接增加了决策的难度。在MCP-A中,47个工具被压缩到14个,使用更少的工具覆盖相同的功能。
因此,我对良好的MCP工具设计有以下几点总结:
- 在设计工具时,考虑代理接下来需要什么,而不仅仅是它当前所要求的内容。返回足够的上下文,以便代理能够在不进行另一次往返的情况下采取下一步行动。
- 工具过多会增加模型的决策负担。因此,最好在MCP中尽量减少工具的数量,确保它们的功能不重叠。
- 当你的MCP将数据返回给LLM时,尽量保持其对LLM友好,即易于阅读。你可以从API响应中过滤掉不必要的字段并格式化数据,而不是直接传递原始JSON。
以上所有测试都是通过MCP-Eval进行的。这是一个MCP服务器基准测试工具。如果你想检查你的MCP性能,可以随时查看这个工具。
https://github.com/Code-MonkeyZhang/mcp-eval
返回首页
最新
问题:我经常保存关于餐馆、活动、快闪店和其他事情的Instagram Reels/TikToks,但总是因为它们被埋在我的收藏中而忘记了。
解决方案:我开发了Cork。你可以直接将Reel或TikTok发送到Cork,而无需离开应用程序,Cork会自动提取Reel中的信息并将其保存到地图和日历中。
然而,我发现自己很难获得关注,而我的竞争对手却获得了关注和资金。我坚信我的应用程序在性能上超过所有已知的竞争对手(他们的应用在流行创作者的Reel上表现不佳,而我的却成功)。
我不是来寻求同情或做广告的,但我很好奇,为什么一些团队在有足够的人员(员工+资金)情况下,仍然无法解决一个相对简单的问题,而我这个两人团队却在一个月内做到了。
总结:在我看来,我的应用在原始性能上优于竞争对手。为什么一个拥有人员和资金的团队却无法做到一个两人团队在一个月内完成的事情?
几个月前,我以为在浏览器中显示音频波形只是一个周末项目。<p>我错了。<p>第一个原型在处理短音频片段时运行良好,但当我尝试加载几个小时长的录音时,一切都崩溃了。<p>内存使用量激增。<p>用户界面变得无响应。<p>缩放操作非常痛苦。<p>甚至生成波形峰值所需的时间也超出了预期。<p>让我最惊讶的是,真正的挑战并不是解码音频,而是高效地渲染和管理大量的时间线数据。<p>我最终尝试了 Web Workers、IndexedDB 缓存、虚拟化渲染和渐进加载策略,只为保持浏览器的响应性。<p>对于那些构建过基于浏览器的音频工具的人:<p>你遇到的最困难的性能瓶颈是什么?<p>是解码、渲染、内存管理,还是完全不同的东西?