最初发布于 tengli.dev
当我在 mcpgrade 中添加由大语言模型驱动的评估功能时,第一次实际运行产生的结果令人震惊:context7 —— 一个静态评分完美的服务器 —— 在工具选择上的失败率高达 62%。在一个展示其双工具目录的模型面前,它在 8 个任务中有 5 个选择了“错误”的工具。
如果我发布了那个数据,那将是错误的。不是轻微的错误,而是系统性、不公平的错误。本文讲述了我如何发现这一问题,因为这种故障模式普遍存在于人们当前构建的大多数智能体基准测试中。
设置
mcpgrade 的 --eval 模式工作原理如下:它读取服务器的工具目录,合成真实的单步任务(例如“找到讨论该事件的 Slack 频道”),向模型展示完整目录,并衡量三项指标 —— 是否选择了正确的工具、是否填充了有效的参数,以及是否正确拒绝了没有工具可以处理的任务。
第一轮测试在三个真实服务器上进行,成本约为十二美分,结果如下:
| 服务器 | 静态评分 | 工具选择 | 参数 | 拒绝 |
|---|---|---|---|---|
| context7(2 个工具) | 100 | 38% | 100% | 100% |
| server-memory(9 个工具) | 81 | 93% | 100% | 100% |
| server-slack(8 个工具) | 97 | 54% | 100% | 100% |
两个拥有优秀静态评分的服务器,在实际测试中似乎表现糟糕。要么是静态分析毫无价值,要么是评估系统出了问题。
评估系统出了问题
每一次“失误”都追溯到一个原因。Slack 的 post_message 需要一个 thread_ts(线程时间戳)—— 这是一个只能从对 get_channel_history 的先前调用中获得的值。context7 的 get-library-docs 需要一个来自 resolve-library-id 的库 ID。这些是流水线式工具:它们所需的参数由其他工具生成。
我的任务合成器并不知道这一点。它生成了诸如“回复关于中断的线程”之类的任务 —— 却没有提供线程时间戳。模型相当合理地首先选择了 get_channel_history(以查找线程),或者选择了拒绝。我的评分器将这两种选择都标记为错误。
模型并没有困惑。模型是正确的。基准测试将正确的多步推理判定为失败 —— 而 memory 服务器 93% 的得分早已揭示了真相:它的工具是单步的,所以得分良好。
修复方法是在合成提示词中加入一个约束条件:每个任务必须为每个必需参数嵌入具体的值。 “在 #incidents 频道回复线程 1721581200.123456” —— 现在,单次选择成为一个公平的问题。第二轮结果:context7 从 38% 升至 100%,slack 从 54% 升至 100%。
如果你的智能体基准测试显示一个能力强大的模型在真实用户能顺利使用的工具上失败,请检查你是否在针对多步工具提出单步问题。根据我的经验,大多数自制的“工具选择准确率”数据都存在这个 bug,从而悄悄地抬高了它们的失败率。
第三轮:是否具有区分度?
一个给所有人都打 100 分的基准测试只是装饰品。因此,第三轮将修复后的评估系统指向 firecrawl —— 拥有 26 个工具,在我对 36 个服务器的扫描 中静态评分最低。如果评估系统在衡量真实的东西,那么一个混乱的目录应该得分更低。它
免责声明:本文内容来自互联网,该文观点不代表本站观点。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请到页面底部单击反馈,一经查实,本站将立刻删除。