Files
2026-07-13 21:35:36 +08:00

19 KiB
Raw Permalink Blame History

MCP 服务器评估指南

概述

本文档提供了为 MCP 服务器创建全面评估的指导。评估用于测试大语言模型能否仅通过所提供的工具,有效使用你的 MCP 服务器来回答真实、复杂的问题。


快速参考

评估要求

  • 创建 10 个人类可读的问题
  • 问题必须是只读、独立、非破坏性的
  • 每个问题需要多次工具调用(可能多达数十次)
  • 答案必须是单个可验证的值
  • 答案必须稳定(不会随时间变化)

输出格式

<evaluation>
   <qa_pair>
      <question>你的问题在此</question>
      <answer>单个可验证的答案</answer>
   </qa_pair>
</evaluation>

评估的目的

衡量 MCP 服务器质量的关键不在于服务器实现工具的好坏或全面程度,而在于这些实现(输入/输出模式、文档字符串/描述、功能)能否让大语言模型——在没有其他上下文、仅能访问 MCP 服务器的情况下——回答真实且困难的问题。

评估概述

创建 10 个人类可读的问题,仅需通过只读、独立、非破坏性且幂等的操作即可回答。每个问题应具备以下特点:

  • 真实
  • 清晰简洁
  • 无歧义
  • 复杂,可能需要数十次工具调用或步骤
  • 可用一个你事先确定的、可验证的单一值来回答

问题编写指南

核心要求

  1. 问题必须是独立的

    • 每个问题不应依赖于任何其他问题的答案
    • 不应假设在处理另一个问题之前已执行过写入操作
  2. 问题必须仅涉及非破坏性和幂等的工具使用

    • 不应指示或要求通过修改状态来得出正确答案
  3. 问题必须真实、清晰、简洁且复杂

    • 必须要求另一个大语言模型使用多个(可能数十个)工具或步骤才能回答

复杂度与深度

  1. 问题必须要求深入探索

    • 考虑多跳问题,需要多个子问题和连续的工具调用
    • 每一步应能从之前问题中发现的信息中获益
  2. 问题可能需要大量翻页

    • 可能需要翻阅多页结果
    • 可能需要查询旧数据(已过时 1-2 年)以找到小众信息
    • 问题必须困难
  3. 问题必须要求深入理解

    • 而非表层知识
    • 可将复杂观点设为是非题,要求提供证据
    • 可采用选择题形式,让大语言模型搜索不同的假设
  4. 问题不能通过简单的关键词搜索解决

    • 不要包含目标内容中的特定关键词
    • 使用同义词、相关概念或意译
    • 需要多次搜索、分析多个相关项目、提取上下文,然后推导出答案

工具测试

  1. 问题应对工具返回值进行压力测试

    • 可能使工具返回大型 JSON 对象或列表,压倒大语言模型
    • 应要求理解多种数据形式:
      • ID 和名称
      • 时间戳和日期时间(月、日、年、秒)
      • 文件 ID、名称、扩展名和 MIME 类型
      • URL、GID 等
    • 应探查工具返回所有有用数据形式的能力
  2. 问题应主要反映真实的人类使用场景

    • 人类在 LLM 辅助下会关心的信息检索任务类型
  3. 问题可能需要数十次工具调用

    • 这对上下文有限的大语言模型构成挑战
    • 鼓励 MCP 服务器工具减少返回的信息量
  4. 包含有歧义的问题

    • 可能有歧义,或者需要就调用哪些工具做出困难决策
    • 迫使大语言模型可能犯错或误读
    • 确保尽管存在歧义,仍然有一个可验证的单一答案

稳定性

  1. 问题必须设计为答案不会变化

    • 不要问依赖动态"当前状态"的问题
    • 例如,不要统计:
      • 帖子的回复数
      • 话题的回复数
      • 频道的成员数
  2. 不要让 MCP 服务器限制你创建问题的类型

    • 创建有挑战性的复杂问题
    • 有些问题可能无法用现有的 MCP 服务器工具解决
    • 问题可能需要特定的输出格式(日期时间 vs 纪元时间、JSON vs MARKDOWN
    • 问题可能需要数十次工具调用才能完成

答案编写指南

可验证性

  1. 答案必须可通过直接字符串比较来验证
    • 如果答案可以用多种格式重写,需在问题中明确指定输出格式
    • 例如:"使用 YYYY/MM/DD 格式。"、"回答 True 或 False。"、"回答 A、B、C 或 D,不要包含其他内容。"
    • 答案应为单个可验证的值,例如:
      • 用户 ID、用户名、显示名称、名、姓
      • 频道 ID、频道名称
      • 消息 ID、消息字符串
      • URL、标题
      • 数值数量
      • 时间戳、日期时间
      • 布尔值(用于是非题)
      • 电子邮件地址、电话号码
      • 文件 ID、文件名、文件扩展名
      • 选择题答案
    • 答案不得要求特殊格式化或复杂的结构化输出
    • 答案将通过直接字符串比较来验证

可读性

  1. 答案通常应优先采用人类可读的格式
    • 例如:名称、名、姓、日期时间、文件名、消息字符串、URL、是/否、真/假、a/b/c/d
    • 而非不透明的 ID(虽然 ID 也是可接受的)
    • 绝大多数答案应是人类可读的

稳定性

  1. 答案必须稳定/不变

    • 查看旧内容(例如已结束的对话、已启动的项目、已回答的问题)
    • 基于"已闭合"的概念创建问题,这些概念将始终返回相同的答案
    • 问题可要求考虑一个固定的时间窗口,以规避非平稳答案
    • 依赖不太可能变化的上下文
    • 例如:如果要查找论文名称,应足够具体,以免与后来发表的论文混淆
  2. 答案必须清晰且无歧义

    • 问题必须设计为存在单个明确的答案
    • 答案应可通过使用 MCP 服务器工具推导得出

多样性

  1. 答案必须多样化

    • 答案应为不同形式和格式的单个可验证值
    • 用户相关概念:用户 ID、用户名、显示名称、名、姓、电子邮件地址、电话号码
    • 频道相关概念:频道 ID、频道名称、频道主题
    • 消息相关概念:消息 ID、消息字符串、时间戳、月、日、年
  2. 答案不能是复杂结构

    • 不能是一个值列表
    • 不能是一个复杂对象
    • 不能是 ID 或字符串列表
    • 不能是自然语言文本
    • 除非答案可以通过直接字符串比较进行直接验证
    • 并且可以被实际复现
    • 大语言模型不太可能以其他任何顺序或格式返回相同的列表

评估流程

第 1 步:文档审查

阅读目标 API 的文档以了解:

  • 可用的端点及功能
  • 如果存在歧义,从网络获取更多信息
  • 尽可能并行执行此步骤
  • 确保每个子代理仅从文件系统或网络上查阅文档

第 2 步:工具审查

列出 MCP 服务器中可用的工具:

  • 直接检查 MCP 服务器
  • 了解输入/输出模式、文档字符串和描述
  • 在此阶段不要调用工具本身

第 3 步:建立理解

重复第 1 步和第 2 步,直到你有了良好的理解:

  • 多次迭代
  • 思考你想要创建的任务类型
  • 完善你的理解
  • 在任何阶段都不应阅读 MCP 服务器实现的代码
  • 运用你的直觉和理解来创建合理、真实但极具挑战性的任务

第 4 步:只读内容审查

在理解 API 和工具之后,使用 MCP 服务器的工具:

  • 仅通过只读和非破坏性操作来检查内容
  • 目标:确定特定内容(例如用户、频道、消息、项目、任务)以创建真实的问题
  • 不应调用任何会修改状态的工具
  • 不得阅读 MCP 服务器实现的代码
  • 使用各个子代理进行独立的探索,并行执行此步骤
  • 确保每个子代理仅执行只读、非破坏性和幂等的操作
  • 注意:某些工具可能返回大量数据,导致上下文溢出
  • 进行增量式、小规模且有目标的工具调用来探索
  • 在所有工具调用请求中,使用 limit 参数限制结果数量(<10
  • 使用分页

第 5 步:任务生成

在检查内容后,创建 10 个人类可读的问题:

  • 大语言模型应能使用 MCP 服务器回答这些问题
  • 遵循上述所有问题和答案的编写指南

输出格式

每个问答对包含一个问题和一个答案。输出应为具有以下结构的 XML 文件:

<evaluation>
   <qa_pair>
      <question>找到在 2024 年第二季度创建、完成任务数量最多的项目。项目名称是什么?</question>
      <answer>网站改版</answer>
   </qa_pair>
   <qa_pair>
      <question>搜索在 2024 年 3 月关闭的、标记为"bug"的问题。哪个用户关闭的问题最多?请提供其用户名。</question>
      <answer>sarah_dev</answer>
   </qa_pair>
   <qa_pair>
      <question>查找修改了 /api 目录下文件、并在 2024 年 1 月 1 日至 1 月 31 日期间合并的拉取请求。有多少个不同的贡献者参与了这些 PR?</question>
      <answer>7</answer>
   </qa_pair>
   <qa_pair>
      <question>找到在 2023 年之前创建、获得星标数最多的仓库。仓库名称是什么?</question>
      <answer>data-pipeline</answer>
   </qa_pair>
</evaluation>

评估示例

好的问题

示例 1:需要深入探索的多跳问题(GitHub MCP)

<qa_pair>
   <question>找到在 2023 年第三季度归档、且此前是该组织中被 fork 最多的项目仓库。该仓库使用的主要编程语言是什么?</question>
   <answer>Python</answer>
</qa_pair>

这个问题好的原因在于:

  • 需要多次搜索才能找到已归档的仓库
  • 需要确定在归档前哪个仓库的 fork 数最多
  • 需要查看仓库详情以获取语言信息
  • 答案是一个简单、可验证的值
  • 基于历史(已闭合)数据,不会变化

示例 2:需要理解上下文而无关键词匹配(项目管理 MCP)

<qa_pair>
   <question>找到在 2023 年底完成、专注于改善客户引导的倡议项目。项目负责人在完成后创建了一份回顾文档。当时该负责人的职位是什么?</question>
   <answer>产品经理</answer>
</qa_pair>

这个问题好的原因在于:

  • 没有使用具体项目名称("专注于改善客户引导的倡议项目")
  • 需要从特定时间范围内找到已完成的项目
  • 需要确定项目负责人及其职位
  • 需要从回顾文档中理解上下文
  • 答案是人类可读且稳定的
  • 基于已完成的工作(不会变化)

示例 3:需要多步聚合的复杂问题(问题追踪器 MCP)

<qa_pair>
   <question>在 2024 年 1 月报告的所有标记为"严重"优先级的 Bug 中,哪个受理人在 48 小时内解决了其被分配 Bug 的最高百分比?请提供该受理人的用户名。</question>
   <answer>alex_eng</answer>
</qa_pair>

这个问题好的原因在于:

  • 需要按日期、优先级和状态过滤 Bug
  • 需要按受理人分组并计算解决率
  • 需要理解时间戳以确定 48 小时窗口
  • 测试分页功能(可能需要处理大量 Bug)
  • 答案是单一用户名
  • 基于特定时间段的历史数据

示例 4:需要跨多种数据类型综合(CRM MCP)

<qa_pair>
   <question>找到在 2023 年第四季度从 Starter 方案升级到 Enterprise 方案、且年合同价值最高的客户账户。该账户属于哪个行业?</question>
   <answer>医疗健康</answer>
</qa_pair>

这个问题好的原因在于:

  • 需要理解订阅套餐变更
  • 需要在特定时间范围内识别升级事件
  • 需要比较合同价值
  • 必须获取账户行业信息
  • 答案简单且可验证
  • 基于已完成的过往交易

不好的问题

示例 1:答案随时间变化

<qa_pair>
   <question>当前分配给工程团队的未解决问题有多少?</question>
   <answer>47</answer>
</qa_pair>

这个问题不好的原因在于:

  • 答案会随着问题的创建、关闭或重新分配而变化
  • 不是基于稳定/不变的数据
  • 依赖动态的"当前状态"

示例 2:关键词搜索过于简单

<qa_pair>
   <question>找到标题为"Add authentication feature"的拉取请求,并告诉我谁创建的。</question>
   <answer>developer123</answer>
</qa_pair>

这个问题不好的原因在于:

  • 可以通过精确标题的关键词搜索直接解决
  • 不需要深入探索或理解
  • 无需综合或分析

示例 3:答案格式有歧义

<qa_pair>
   <question>列出所有以 Python 为主要编程语言的仓库。</question>
   <answer>repo1, repo2, repo3, data-pipeline, ml-tools</answer>
</qa_pair>

这个问题不好的原因在于:

  • 答案是一个列表,可能以任意顺序返回
  • 难以通过直接字符串比较来验证
  • 大语言模型可能以不同格式输出(JSON 数组、逗号分隔、换行分隔)
  • 更好的做法是询问具体的聚合值(计数)或最高值(最多星标)

验证流程

创建评估后:

  1. 检查 XML 文件 以了解模式
  2. 加载每个任务指令,并使用 MCP 服务器和工具并行找出正确答案——亲自尝试解决问题
  3. 标记所有需要写入或破坏性操作的操作
  4. 汇总所有正确答案,替换文档中的任何错误答案
  5. 移除所有需要写入或破坏性操作的 <qa_pair>

请记住并行求解任务以避免上下文溢出,然后在最后汇总所有答案并对文件进行修改。

创建高质量评估的提示

  1. 在生成任务之前深入思考并提前规划
  2. 在有机会时进行并行处理 以加快速度并管理上下文
  3. 聚焦于真实的使用场景——人类真正想要完成的任务
  4. 创建有挑战性的问题 以测试 MCP 服务器能力的极限
  5. 确保稳定性——使用历史数据和已闭合的概念
  6. 验证答案——亲自使用 MCP 服务器工具解决问题
  7. 根据过程中的发现迭代并优化

运行评估

创建评估文件后,你可以使用提供的评估框架来测试你的 MCP 服务器。

环境设置

  1. 安装依赖

    pip install -r scripts/requirements.txt
    

    或手动安装:

    pip install anthropic mcp
    
  2. 设置 API 密钥

    export ANTHROPIC_API_KEY=your_api_key_here
    

评估文件格式

评估文件使用 XML 格式,包含 <qa_pair> 元素:

<evaluation>
   <qa_pair>
      <question>找到在 2024 年第二季度创建、完成任务数量最多的项目。项目名称是什么?</question>
      <answer>网站改版</answer>
   </qa_pair>
   <qa_pair>
      <question>搜索在 2024 年 3 月关闭的、标记为"bug"的问题。哪个用户关闭的问题最多?请提供其用户名。</question>
      <answer>sarah_dev</answer>
   </qa_pair>
</evaluation>

运行评估

评估脚本(scripts/evaluation.py)支持三种传输类型:

重要说明:

  • stdio 传输:评估脚本会自动为你启动并管理 MCP 服务器进程。请勿手动运行服务器。
  • SSE/HTTP 传输:你必须在运行评估之前单独启动 MCP 服务器。脚本会连接到指定 URL 上已运行的服务器。

1. 本地 STDIO 服务器

适用于本地运行的 MCP 服务器(脚本自动启动服务器):

python scripts/evaluation.py \
  -t stdio \
  -c python \
  -a my_mcp_server.py \
  evaluation.xml

使用环境变量:

python scripts/evaluation.py \
  -t stdio \
  -c python \
  -a my_mcp_server.py \
  -e API_KEY=abc123 \
  -e DEBUG=true \
  evaluation.xml

2. Server-Sent EventsSSE

适用于基于 SSE 的 MCP 服务器(需先启动服务器):

python scripts/evaluation.py \
  -t sse \
  -u https://example.com/mcp \
  -H "Authorization: Bearer token123" \
  -H "X-Custom-Header: value" \
  evaluation.xml

3. HTTPStreamable HTTP

适用于基于 HTTP 的 MCP 服务器(需先启动服务器):

python scripts/evaluation.py \
  -t http \
  -u https://example.com/mcp \
  -H "Authorization: Bearer token123" \
  evaluation.xml

命令行选项

usage: evaluation.py [-h] [-t {stdio,sse,http}] [-m MODEL] [-c COMMAND]
                     [-a ARGS [ARGS ...]] [-e ENV [ENV ...]] [-u URL]
                     [-H HEADERS [HEADERS ...]] [-o OUTPUT]
                     eval_file

positional arguments:
  eval_file             评估 XML 文件的路径

optional arguments:
  -h, --help            显示帮助信息
  -t, --transport       传输类型:stdio、sse 或 http(默认:stdio
  -m, --model           要使用的 Claude 模型(默认:claude-3-7-sonnet-20250219
  -o, --output          报告输出文件(默认:输出到 stdout

stdio options:
  -c, --command         运行 MCP 服务器的命令(例如:python、node
  -a, --args            命令的参数(例如:server.py
  -e, --env             环境变量,格式为 KEY=VALUE

sse/http options:
  -u, --url             MCP 服务器 URL
  -H, --header          HTTP 头,格式为 'Key: Value'

## 输出

评估脚本会生成一份详细报告,包括:

- **汇总统计**:
  - 准确率(正确数/总数)
  - 平均任务耗时
  - 每任务平均工具调用次数
  - 工具调用总数

- **每项任务的结果**:
  - 提示语及预期响应
  - 智能体的实际响应
  - 答案是否正确(✅/❌)
  - 耗时及工具调用详情
  - 智能体对其方法的总结
  - 智能体对工具的反馈

### 将报告保存到文件

```bash
python scripts/evaluation.py \
  -t stdio \
  -c python \
  -a my_server.py \
  -o evaluation_report.md \
  evaluation.xml

完整工作流程示例

以下是创建和运行评估的完整示例:

  1. 创建评估文件my_evaluation.xml):
<evaluation>
   <qa_pair>
      <question>找到在 2024 年 1 月创建问题最多的用户。该用户的用户名是什么?</question>
      <answer>alice_developer</answer>
   </qa_pair>
   <qa_pair>
      <question>在 2024 年第一季度合并的所有拉取请求中,哪个仓库的数量最多?请提供仓库名称。</question>
      <answer>backend-api</answer>
   </qa_pair>
   <qa_pair>
      <question>找到在 2023 年 12 月完成、且从开始到结束持续时间最长的项目。它花了多少天?</question>
      <answer>127</answer>
   </qa_pair>
</evaluation>
  1. 安装依赖
pip install -r scripts/requirements.txt
export ANTHROPIC_API_KEY=your_api_key
  1. 运行评估
python scripts/evaluation.py \
  -t stdio \
  -c python \
  -a github_mcp_server.py \
  -e GITHUB_TOKEN=ghp_xxx \
  -o github_eval_report.md \
  my_evaluation.xml
  1. 查看报告(位于 github_eval_report.md),以:
    • 查看哪些问题通过/未通过
    • 阅读智能体对你工具的反馈
    • 确定需要改进的方面
    • 迭代优化你的 MCP 服务器设计

故障排除

连接错误

如果遇到连接错误:

  • STDIO:确认命令和参数是否正确
  • SSE/HTTP:检查 URL 是否可以访问,请求头是否正确
  • 确保所有必需的 API 密钥已在环境变量或请求头中设置

准确率低

如果许多评估未通过:

  • 查看每项任务中智能体的反馈
  • 检查工具描述是否清晰全面
  • 确认输入参数是否有完善的文档说明
  • 考虑工具返回的数据是否过多或过少
  • 确保错误消息具有可操作性

超时问题

如果任务超时:

  • 使用能力更强的模型(例如 claude-3-7-sonnet-20250219
  • 检查工具是否返回了过多数据
  • 确认分页功能是否正常工作
  • 考虑简化复杂问题