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

603 lines
19 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# MCP 服务器评估指南
## 概述
本文档提供了为 MCP 服务器创建全面评估的指导。评估用于测试大语言模型能否仅通过所提供的工具,有效使用你的 MCP 服务器来回答真实、复杂的问题。
---
## 快速参考
### 评估要求
- 创建 10 个人类可读的问题
- 问题必须是只读、独立、非破坏性的
- 每个问题需要多次工具调用(可能多达数十次)
- 答案必须是单个可验证的值
- 答案必须稳定(不会随时间变化)
### 输出格式
```xml
<evaluation>
<qa_pair>
<question>你的问题在此</question>
<answer>单个可验证的答案</answer>
</qa_pair>
</evaluation>
```
---
## 评估的目的
衡量 MCP 服务器质量的关键不在于服务器实现工具的好坏或全面程度,而在于这些实现(输入/输出模式、文档字符串/描述、功能)能否让大语言模型——在没有其他上下文、仅能访问 MCP 服务器的情况下——回答真实且困难的问题。
## 评估概述
创建 10 个人类可读的问题,仅需通过只读、独立、非破坏性且幂等的操作即可回答。每个问题应具备以下特点:
- 真实
- 清晰简洁
- 无歧义
- 复杂,可能需要数十次工具调用或步骤
- 可用一个你事先确定的、可验证的单一值来回答
## 问题编写指南
### 核心要求
1. **问题必须是独立的**
- 每个问题不应依赖于任何其他问题的答案
- 不应假设在处理另一个问题之前已执行过写入操作
2. **问题必须仅涉及非破坏性和幂等的工具使用**
- 不应指示或要求通过修改状态来得出正确答案
3. **问题必须真实、清晰、简洁且复杂**
- 必须要求另一个大语言模型使用多个(可能数十个)工具或步骤才能回答
### 复杂度与深度
4. **问题必须要求深入探索**
- 考虑多跳问题,需要多个子问题和连续的工具调用
- 每一步应能从之前问题中发现的信息中获益
5. **问题可能需要大量翻页**
- 可能需要翻阅多页结果
- 可能需要查询旧数据(已过时 1-2 年)以找到小众信息
- 问题必须困难
6. **问题必须要求深入理解**
- 而非表层知识
- 可将复杂观点设为是非题,要求提供证据
- 可采用选择题形式,让大语言模型搜索不同的假设
7. **问题不能通过简单的关键词搜索解决**
- 不要包含目标内容中的特定关键词
- 使用同义词、相关概念或意译
- 需要多次搜索、分析多个相关项目、提取上下文,然后推导出答案
### 工具测试
8. **问题应对工具返回值进行压力测试**
- 可能使工具返回大型 JSON 对象或列表,压倒大语言模型
- 应要求理解多种数据形式:
- ID 和名称
- 时间戳和日期时间(月、日、年、秒)
- 文件 ID、名称、扩展名和 MIME 类型
- URL、GID 等
- 应探查工具返回所有有用数据形式的能力
9. **问题应主要反映真实的人类使用场景**
- 人类在 LLM 辅助下会关心的信息检索任务类型
10. **问题可能需要数十次工具调用**
- 这对上下文有限的大语言模型构成挑战
- 鼓励 MCP 服务器工具减少返回的信息量
11. **包含有歧义的问题**
- 可能有歧义,或者需要就调用哪些工具做出困难决策
- 迫使大语言模型可能犯错或误读
- 确保尽管存在歧义,仍然有一个可验证的单一答案
### 稳定性
12. **问题必须设计为答案不会变化**
- 不要问依赖动态"当前状态"的问题
- 例如,不要统计:
- 帖子的回复数
- 话题的回复数
- 频道的成员数
13. **不要让 MCP 服务器限制你创建问题的类型**
- 创建有挑战性的复杂问题
- 有些问题可能无法用现有的 MCP 服务器工具解决
- 问题可能需要特定的输出格式(日期时间 vs 纪元时间、JSON vs MARKDOWN
- 问题可能需要数十次工具调用才能完成
## 答案编写指南
### 可验证性
1. **答案必须可通过直接字符串比较来验证**
- 如果答案可以用多种格式重写,需在问题中明确指定输出格式
- 例如:"使用 YYYY/MM/DD 格式。"、"回答 True 或 False。"、"回答 A、B、C 或 D,不要包含其他内容。"
- 答案应为单个可验证的值,例如:
- 用户 ID、用户名、显示名称、名、姓
- 频道 ID、频道名称
- 消息 ID、消息字符串
- URL、标题
- 数值数量
- 时间戳、日期时间
- 布尔值(用于是非题)
- 电子邮件地址、电话号码
- 文件 ID、文件名、文件扩展名
- 选择题答案
- 答案不得要求特殊格式化或复杂的结构化输出
- 答案将通过直接字符串比较来验证
### 可读性
2. **答案通常应优先采用人类可读的格式**
- 例如:名称、名、姓、日期时间、文件名、消息字符串、URL、是/否、真/假、a/b/c/d
- 而非不透明的 ID(虽然 ID 也是可接受的)
- 绝大多数答案应是人类可读的
### 稳定性
3. **答案必须稳定/不变**
- 查看旧内容(例如已结束的对话、已启动的项目、已回答的问题)
- 基于"已闭合"的概念创建问题,这些概念将始终返回相同的答案
- 问题可要求考虑一个固定的时间窗口,以规避非平稳答案
- 依赖不太可能变化的上下文
- 例如:如果要查找论文名称,应足够具体,以免与后来发表的论文混淆
4. **答案必须清晰且无歧义**
- 问题必须设计为存在单个明确的答案
- 答案应可通过使用 MCP 服务器工具推导得出
### 多样性
5. **答案必须多样化**
- 答案应为不同形式和格式的单个可验证值
- 用户相关概念:用户 ID、用户名、显示名称、名、姓、电子邮件地址、电话号码
- 频道相关概念:频道 ID、频道名称、频道主题
- 消息相关概念:消息 ID、消息字符串、时间戳、月、日、年
6. **答案不能是复杂结构**
- 不能是一个值列表
- 不能是一个复杂对象
- 不能是 ID 或字符串列表
- 不能是自然语言文本
- 除非答案可以通过直接字符串比较进行直接验证
- 并且可以被实际复现
- 大语言模型不太可能以其他任何顺序或格式返回相同的列表
## 评估流程
### 第 1 步:文档审查
阅读目标 API 的文档以了解:
- 可用的端点及功能
- 如果存在歧义,从网络获取更多信息
- 尽可能并行执行此步骤
- 确保每个子代理仅从文件系统或网络上查阅文档
### 第 2 步:工具审查
列出 MCP 服务器中可用的工具:
- 直接检查 MCP 服务器
- 了解输入/输出模式、文档字符串和描述
- 在此阶段不要调用工具本身
### 第 3 步:建立理解
重复第 1 步和第 2 步,直到你有了良好的理解:
- 多次迭代
- 思考你想要创建的任务类型
- 完善你的理解
- 在任何阶段都不应阅读 MCP 服务器实现的代码
- 运用你的直觉和理解来创建合理、真实但极具挑战性的任务
### 第 4 步:只读内容审查
在理解 API 和工具之后,使用 MCP 服务器的工具:
- 仅通过只读和非破坏性操作来检查内容
- 目标:确定特定内容(例如用户、频道、消息、项目、任务)以创建真实的问题
- 不应调用任何会修改状态的工具
- 不得阅读 MCP 服务器实现的代码
- 使用各个子代理进行独立的探索,并行执行此步骤
- 确保每个子代理仅执行只读、非破坏性和幂等的操作
- 注意:某些工具可能返回大量数据,导致上下文溢出
- 进行增量式、小规模且有目标的工具调用来探索
- 在所有工具调用请求中,使用 `limit` 参数限制结果数量(<10
- 使用分页
### 第 5 步:任务生成
在检查内容后,创建 10 个人类可读的问题:
- 大语言模型应能使用 MCP 服务器回答这些问题
- 遵循上述所有问题和答案的编写指南
## 输出格式
每个问答对包含一个问题和一个答案。输出应为具有以下结构的 XML 文件:
```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)**
```xml
<qa_pair>
<question>找到在 2023 年第三季度归档、且此前是该组织中被 fork 最多的项目仓库。该仓库使用的主要编程语言是什么?</question>
<answer>Python</answer>
</qa_pair>
```
这个问题好的原因在于:
- 需要多次搜索才能找到已归档的仓库
- 需要确定在归档前哪个仓库的 fork 数最多
- 需要查看仓库详情以获取语言信息
- 答案是一个简单、可验证的值
- 基于历史(已闭合)数据,不会变化
**示例 2:需要理解上下文而无关键词匹配(项目管理 MCP)**
```xml
<qa_pair>
<question>找到在 2023 年底完成、专注于改善客户引导的倡议项目。项目负责人在完成后创建了一份回顾文档。当时该负责人的职位是什么?</question>
<answer>产品经理</answer>
</qa_pair>
```
这个问题好的原因在于:
- 没有使用具体项目名称("专注于改善客户引导的倡议项目")
- 需要从特定时间范围内找到已完成的项目
- 需要确定项目负责人及其职位
- 需要从回顾文档中理解上下文
- 答案是人类可读且稳定的
- 基于已完成的工作(不会变化)
**示例 3:需要多步聚合的复杂问题(问题追踪器 MCP)**
```xml
<qa_pair>
<question>在 2024 年 1 月报告的所有标记为"严重"优先级的 Bug 中,哪个受理人在 48 小时内解决了其被分配 Bug 的最高百分比?请提供该受理人的用户名。</question>
<answer>alex_eng</answer>
</qa_pair>
```
这个问题好的原因在于:
- 需要按日期、优先级和状态过滤 Bug
- 需要按受理人分组并计算解决率
- 需要理解时间戳以确定 48 小时窗口
- 测试分页功能(可能需要处理大量 Bug)
- 答案是单一用户名
- 基于特定时间段的历史数据
**示例 4:需要跨多种数据类型综合(CRM MCP)**
```xml
<qa_pair>
<question>找到在 2023 年第四季度从 Starter 方案升级到 Enterprise 方案、且年合同价值最高的客户账户。该账户属于哪个行业?</question>
<answer>医疗健康</answer>
</qa_pair>
```
这个问题好的原因在于:
- 需要理解订阅套餐变更
- 需要在特定时间范围内识别升级事件
- 需要比较合同价值
- 必须获取账户行业信息
- 答案简单且可验证
- 基于已完成的过往交易
### 不好的问题
**示例 1:答案随时间变化**
```xml
<qa_pair>
<question>当前分配给工程团队的未解决问题有多少?</question>
<answer>47</answer>
</qa_pair>
```
这个问题不好的原因在于:
- 答案会随着问题的创建、关闭或重新分配而变化
- 不是基于稳定/不变的数据
- 依赖动态的"当前状态"
**示例 2:关键词搜索过于简单**
```xml
<qa_pair>
<question>找到标题为"Add authentication feature"的拉取请求,并告诉我谁创建的。</question>
<answer>developer123</answer>
</qa_pair>
```
这个问题不好的原因在于:
- 可以通过精确标题的关键词搜索直接解决
- 不需要深入探索或理解
- 无需综合或分析
**示例 3:答案格式有歧义**
```xml
<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. **安装依赖**
```bash
pip install -r scripts/requirements.txt
```
或手动安装:
```bash
pip install anthropic mcp
```
2. **设置 API 密钥**
```bash
export ANTHROPIC_API_KEY=your_api_key_here
```
## 评估文件格式
评估文件使用 XML 格式,包含 `<qa_pair>` 元素:
```xml
<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 服务器(脚本自动启动服务器):
```bash
python scripts/evaluation.py \
-t stdio \
-c python \
-a my_mcp_server.py \
evaluation.xml
```
使用环境变量:
```bash
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 服务器(需先启动服务器):
```bash
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 服务器(需先启动服务器):
```bash
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`):
```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>
```
2. **安装依赖**
```bash
pip install -r scripts/requirements.txt
export ANTHROPIC_API_KEY=your_api_key
```
3. **运行评估**
```bash
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
```
4. **查看报告**(位于 `github_eval_report.md`),以:
- 查看哪些问题通过/未通过
- 阅读智能体对你工具的反馈
- 确定需要改进的方面
- 迭代优化你的 MCP 服务器设计
## 故障排除
### 连接错误
如果遇到连接错误:
- **STDIO**:确认命令和参数是否正确
- **SSE/HTTP**:检查 URL 是否可以访问,请求头是否正确
- 确保所有必需的 API 密钥已在环境变量或请求头中设置
### 准确率低
如果许多评估未通过:
- 查看每项任务中智能体的反馈
- 检查工具描述是否清晰全面
- 确认输入参数是否有完善的文档说明
- 考虑工具返回的数据是否过多或过少
- 确保错误消息具有可操作性
### 超时问题
如果任务超时:
- 使用能力更强的模型(例如 `claude-3-7-sonnet-20250219`
- 检查工具是否返回了过多数据
- 确认分页功能是否正常工作
- 考虑简化复杂问题