MCP回退基准
一个基准套件,用于评估AI代理通过切换到等效的替代服务从工具故障中恢复的能力。为伯克利天空实验室建造。
概述
此基准测试语言模型在使用MCP(模型上下文协议)工具时是否可以自主处理服务故障。当一个服务发生故障时,模型能否识别故障并切换到等效的替代服务来完成任务?
核心机制
- 模型接收任务(例如,“向通用通道发送消息”)
- 它可以访问两个等效服务(例如Slack+Discord)的工具
- 它首先尝试的任何服务都会失败,并出现“service_SHUTDOWN”错误
- 成功=模型识别故障并使用OTHER服务完成任务
- 失败=模型放弃、循环或返回注释而不是切换
项目结构
SkyLabsProjectPreliminaries/
├── harness/
│ └── runner.py # Main benchmark runner (supports OpenAI, Anthropic, Google)
├── mock_servers/
│ ├── food_delivery_api.py # UberEats + DoorDash (legacy paired server)
│ ├── github_api.py # GitHub MCP mock (20 tools)
│ ├── gitlab_api.py # GitLab MCP mock (9 tools)
│ ├── brave_search_api.py # Brave Search mock (2 tools)
│ ├── exa_search_api.py # Exa Search mock (9 tools)
│ ├── slack_api.py # Slack MCP mock (8 tools)
│ ├── discord_api.py # Discord MCP mock (10 tools)
│ ├── google_maps_api.py # Google Maps mock (7 tools)
│ └── mapbox_api.py # Mapbox mock (10 tools)
├── error_injection/
│ └── controller.py # Error injection + server pairing logic
├── scenarios/
│ └── prompts.json # 15 unique test scenarios (easy/medium/hard)
├── traces/ # Output directory for conversation traces
└── README.md支持的供应商和型号
该基准支持三个AI提供商:
| 提供者 | 默认模型 | 环境变量 |
|---|---|---|
| OpenAI | gpt-5.2 | OPENAI_API_KEY |
| Anthropic | claude-sonnet-4-5-20250929 | ANTHROPIC_API_KEY |
| 谷歌 | gemini-3.0-flash | GOOGLE_API_KEY |
服务器对及其选择原因
每个服务器对都是根据官方提供的真实MCP服务器模式选择的 模型上下文协议服务器存储库.
1.送餐服务:UberEats+DoorDash
目的: 具有对称工具集的传统基线对。
| UberEats | DoorDash |
|---|---|
ubereats_login | doordash_authenticate |
ubereats_search_restaurants | doordash_find_restaurants |
ubereats_get_menu | doordash_view_menu |
ubereats_place_order | doordash_submit_order |
ubereats_get_order_status | doordash_check_order_status |
测试内容: 纯回退-两个服务具有相同的功能。模型能否在其他服务上找到等效方法?
______________________________________________________________________
2.代码托管:GitHub+GitLab
目的: 具有非对称工具数量的真实MCP服务器。
| GitHub(20个工具) | GitLab(9个工具) |
|---|---|
| 全面回购管理 | 核心回购操作 |
| 问题、PR、分支 | 问题、MR、分支 |
| 代码/问题/用户搜索 | 仅存储库搜索 |
| 分叉、合并、注释 | 基本操作 |
测试内容:
- 当目标服务有FEWER工具时回退
- 当GitLab上不存在某些GitHub功能时,模型必须进行调整
- 测试场景:创建问题、分叉仓库、创建PR、搜索仓库
______________________________________________________________________
3.网络搜索:Brave+Exa
目的: 最小与功能丰富的搜索API。
| Brave(2个工具) | Exa(9个工具) |
|---|---|
brave_web_search | web_search_exa |
brave_local_search | get_code_context_exa |
company_research_exa | |
deep_search_exa | |
people_search_exa | |
| ...以及更多 |
测试内容:
- 当目标服务有更多工具时回退
- 模型必须发现Exa的专用工具(代码搜索、公司研究)
- 测试场景:一般搜索、代码示例、公司研究
______________________________________________________________________
4.团队信息:松弛+不和谐
目的: 双方都有独特功能的类似服务。
| Slack(8工具) | Discord(10工具) |
|---|---|
slack_post_message | send_message |
slack_list_channels | list_channels |
slack_add_reaction | add_reaction |
slack_get_channel_history | read_messages |
slack_reply_to_thread | — |
| — | edit_message |
| — | delete_message |
| — | send_private_message |
测试内容:
- 不对称功能(Discord可以编辑/删除/DM,Slack有线程)
- 模型必须识别回退服务上何时不存在某个功能
- 测试场景:发送消息、添加反应、发送DM
______________________________________________________________________
5.地图和导航:谷歌地图+Mapbox
目的: 标准制图与地理空间计算。
| 谷歌地图(7个工具) | Mapbox(10个工具) |
|---|---|
maps_geocode | mapbox_geocode |
maps_directions | mapbox_directions |
maps_search_places | mapbox_search_places |
maps_distance_matrix | mapbox_matrix |
maps_elevation | — |
| — | mapbox_bearing |
| — | mapbox_isochrone |
| — | mapbox_distance (离线) |
测试内容:
- 这两个服务都有等效的核心工具(方向、地理编码、地点)
- 测试场景:方向、地理编码、地点搜索
难度等级
每个场景都有三个难度级别:
| 级别 | 描述 | 示例提示 |
|---|---|---|
| 简单 | 明确命名这两个服务+切换提示 | “向普通用户发送消息。使用Slack或Discord。如果其中一个失败,请切换到另一个。” |
| 中等 | 命名这两个服务,没有切换提示 | “向普通用户发送消息。使用Slack或Discord。” |
| 困难 | 通用任务,无服务提示 | “向通用发送消息。” |
15种测试场景
| 类别 | 场景 | 测试 |
|---|---|---|
| 食品配送 | food_delivery_order | 下订单 |
food_delivery_status | 检查订单状态(订单ID 1001) | |
| 代码托管 | code_hosting_create_issue | 创建错误报告 |
code_hosting_fork_repo | 分叉存储库 | |
code_hosting_create_pr | 创建拉取/合并请求 | |
code_hosting_search_repos | 搜索存储库 | |
| 网络搜索 | web_search_general | 一般网络搜索 |
web_search_code | 查找代码示例 | |
web_search_company | 公司调研 | |
| 团队消息 | team_messaging_send | 发送频道消息 |
team_messaging_react | 在消息中添加反应 | |
team_messaging_dm | 发送直接消息 | |
| 地图 | maps_directions | 获取行车路线 |
maps_geocode | 获取纬度/经度坐标 | |
maps_places | 搜索附近的地方 |
运行基准
先决条件
pip install openai anthropic google-generativeai为要使用的提供程序设置API密钥:
# For OpenAI
export OPENAI_API_KEY="sk-..."
# For Anthropic (Claude)
export ANTHROPIC_API_KEY="sk-ant-..."
# For Google (Gemini)
export GOOGLE_API_KEY="AIza..."基本用法
使用OpenAI运行完整的基准测试(默认):
python harness/runner.py与Anthropic Claude一起跑步:
python harness/runner.py --provider anthropic使用Google Gemini跑步:
python harness/runner.py --provider google选项
# Test a specific model
python harness/runner.py --provider openai --model gpt-4o
python harness/runner.py --provider anthropic --model claude-opus-4-20250514
python harness/runner.py --provider google --model gemini-2.0-pro
# Run only one scenario
python harness/runner.py --scenario code_hosting_create_issue
# Run all scenarios for one server pair
python harness/runner.py --server maps
# Run only hard difficulty
python harness/runner.py --level hard
# Show detailed tool call traces
python harness/runner.py --verbose
# Save conversation traces to files
python harness/runner.py --trace ./traces
# Combine options
python harness/runner.py --provider anthropic --server team_messaging --level medium --verbose输出
基准打印一个记分卡,显示:
- 按难度级别划分的通过/失败率
- 按服务器对划分的通过/失败率
- 每个场景的详细结果
输出示例:
======================================================================
SCORECARD - claude-sonnet-4-5-20250929 (anthropic)
======================================================================
BY DIFFICULTY LEVEL:
Level Pass Total Accuracy
────────────────────────────────────
EASY 12 15 80.0%
MEDIUM 9 15 60.0%
HARD 5 15 33.3%
────────────────────────────────────
AVERAGE 26 45 57.8%
BY SERVER PAIR:
Server Pass Total Accuracy
────────────────────────────────────────────
code_hosting 8 12 66.7%
food_delivery 5 6 83.3%
maps 4 9 44.4%
team_messaging 5 9 55.6%
web_search 4 9 44.4%如何衡量成功
跑步被标记 通过 如果:
- 该模型称为服务a(或B)中的工具
- 该工具返回了一个
SERVICE_SHUTDOWN错误 - 然后,该模型调用服务B(或A)上的等效工具
- 该工具返回了带有预期密钥的成功结果
跑步被标记 失败 如果:
- 模型出错后放弃
- 模型返回注释,而不是尝试其他工具
- 无交换服务的模型循环
- 模型崩溃或达到20圈限制
建筑细部
错误注入
这 ErrorInjectedAPI 包装器拦截工具调用:
# First call to ANY of these methods fails
fail_methods = ["slack_slack_post_message", "discord_send_message"]
# If model calls slack first -> error
# Then discord works fine (and vice versa)每个场景都有保证的错误注入——所有等效方法对都包含在 fail_methods 列表。
服务器配对
这 PairedServerAPI 类结合了两个单独的API:
# GitHub methods become: github_create_issue, github_fork_repository, ...
# GitLab methods become: gitlab_create_issue, gitlab_fork_repository, ...
# Model sees ALL tools from both services多提供商支持
运行器会自动将工具模式转换为每个提供程序的格式:
- OpenAI:使用函数调用
tools参数 - Anthropic:转换为克劳德的
tool_use格式与input_schema - 谷歌:转换为双子座
FunctionDeclaration格式
模拟服务器
服务器是基于真实MCP模式的模拟,但返回模拟数据。他们不会对GitHub、Slack等进行实际的API调用。
现有测试数据:
- 外卖:订单1001(UberEats)和1002(DoorDash)用于状态检查
- 代码托管:存储库
acme-corp/web-app存在问题/PR创建
联系
斯里·瓦萨 伯克利天空实验室
