4 个 MCP Benchmark 代码级深潜 — 一个模型能 SOTA 所有 4 个吗?
速读卡片 (TL;DR)
一句话: 4 个 bench 的 server / app 集合几乎没有重叠(只有 GitHub / Notion / Filesystem / Playwright 这 4 个会在 ≥2 个 bench 同时出现),task 数据格式四套互不兼容(MCPMark = py verify.py,MCP-Universe = JSON+jinja+func-chain DSL,MCP-Atlas = parquet+claim list+LLM judge,Toolathlon = python eval/main.py+真 GCP API)。"一个模型 SOTA 全部 4 个" 理论可行但工程门槛极高 — 主要不是 capability 问题,而是 (1) 联合训练需要 90+ 个唯一 MCP server 的可控运行环境; (2) MCP-Atlas 的 Gemini-2.5-Pro claim judge 风味 vs MCPMark 的严格 AST-style verify.py 风味 vs Toolathlon 的真账号副作用 vs MCP-Universe 的 func-chain DSL 之间存在评分口味冲突 — 在一个上拿满分的写法可能在另一个上掉分。
立场: 这不是 #21 那种"选哪个跑就行"的层面 — #26 是把 4 个 repo 的 task 文件、verifier、server 配置拉下来读一遍,得出结论: 不存在一条"训一次 → 4 个都 SOTA"的捷径。 但共享 server (GitHub / Notion / Filesystem / Playwright) 的 trajectory 数据是真可复用的,而每个 bench 的"长尾私有 server"必须靠各自的 env mining 单独搞。建议路线: Toolathlon 公开 eval service 当主战场打 long-tail,MCP-Universe RL stack 当训练引擎,MCPMark 当稳定性回归,MCP-Atlas 当 LLM-judge 鲁棒性回归。
1 · 核心问题:能不能一个模型 SOTA 所有 4 个
这是 #21 之后用户的下一个问题。 把它用 1 句话先回答,后面再用证据支撑:
诚实答案: 不能"训一次 → 4 个都 SOTA"。 但可以训一个模型 → 同时在 4 个 bench 上拿到不错且有竞争力的成绩,代价是: 你必须自己搭出 4 个 bench 各自的 ≈90 个真实 MCP server 的可联通环境,然后跨 bench 联合 RL/SFT。最高的 SOTA 还是会被各 bench 的 specialist 单独训练拿走 — 比如 MCPMark 上 GitHub-task 的 SOTA 写法可能是激进多步并行 tool call,而 MCP-Atlas 上 Gemini-judge 更喜欢简洁单步语义对齐的输出,这两者在同一个模型权重里很难同时最优。
1.1 为什么 #19 #21 #25 都没法直接回答
| 前置笔记 | 覆盖了什么 | 没覆盖什么 (#26 补) |
|---|---|---|
| #19 MCP-Atlas 深读 | 1,000 task / 36 server / Anthropic-cited / parquet schema | 没和其他 3 个 bench 的 server 做交集 |
| #21 4-bench 横向对比 | star / citation / RL gym 有无 / 决策树 | 没读 task 文件,没读 verifier |
| #25 MCP-Universe 深读 | 11 server · 6 domain · 231 task / 三层评测代码 / verl RL 栈 | 没回答"它的训练能不能 transfer 到别的 bench" |
所以 #26 的价值定位 = 把 4 个 repo 当成 4 个 codebase 来读,具体看: (a) 是否同一个 server; (b) 同一个 server 下 task 怎么写; (c) 评测代码本质上是什么 abstraction; (d) 训练数据格式是否能拼成一个 corpus。
2 · Server / App 重叠矩阵 (repo 实地清点)
2.1 各 bench 的 server 清单从哪里拿
# MCP-Atlas — 36 servers, 全部在一个 json 模板里
$ curl -s https://raw.githubusercontent.com/scaleapi/mcp-atlas/main/\
services/agent-environment/src/agent_environment/mcp_server_template.json \
| python3 -c "import json,sys; d=json.load(sys.stdin);\
print('Total:', len(d['mcpServers']))"
# Total: 36 ✅ 和 paper 数字一致
# MCP-Universe — 11 server, 11 个 server config 在 mcp/configs/, task 在
# mcpuniverse/benchmark/configs/mcpuniverse/<domain>/<task>.json
# 6 个 domain: 3d_design (19) · browser_automation · financial_analysis (40) ·
# location_navigation · multi_server · repository_management (>30) · web_search (50)
# MCPMark — 5 server, 5 个目录
$ curl -s api.github.com/repos/eval-sys/mcpmark/contents/tasks
# filesystem, github, notion, playwright, postgres ( + insforge/supabase symlinks)
# Toolathlon — 配置目录里有 34 个 .yaml (paper 报 32 app),task 108 个
$ curl -s api.github.com/repos/hkust-nlp/Toolathlon/contents/configs/mcp_servers
# 34 yaml: 12306, arxiv-latex-mcp, arxiv_local, canvas, emails, excel, filesystem,
# git, github, google-cloud, google_calendar, google_forms, google_map, google_sheet,
# howtocook, huggingface, k8s, memory, notion, notion_official, npx-fetch, pdf-tools,
# playwright_with_chunk, pptx, scholarly_search, snowflake, terminal, time, wandb,
# woocommerce, word, yahoo-finance, youtube, youtube_transcript
2.2 重叠矩阵 (核心表)
把 4 个 bench 的 server 池逐项对位。 只列在 ≥1 bench 里出现的项;统一名字 (e.g. notion / notion_official 都算 Notion)。 绿色 = 该 server 在该 bench 中存在。
| Server / App | MCPMark (5) | MCP-Universe (11) | MCP-Atlas (36) | Toolathlon (~32) | 共享 bench 数 |
|---|---|---|---|---|---|
| GitHub | ✓ | ✓ | ✓ | ✓ (github) | 4 / 4 |
| Filesystem | ✓ | · | ✓ | ✓ | 3 / 4 |
| Notion | ✓ | · | ✓ | ✓ (2 版本) | 3 / 4 |
| Playwright (浏览器) | ✓ | ✓ (browser_automation) | · | ✓ (with_chunk) | 3 / 4 |
| Postgres | ✓ | · | · | · | 1 / 4 |
| git (本地 git CLI) | · | · | ✓ | ✓ | 2 / 4 |
| Google Maps / Google search | · | ✓ (location) | ✓ | ✓ (google_map) | 3 / 4 |
| Slack / Email | · | · | ✓ slack | ✓ emails | 2 / 4 (不同实现) |
| arxiv / pubmed / open-library 等学术 | · | · | ✓ (3 个) | ✓ (arxiv_local 等) | 2 / 4 |
| Yahoo finance / financial | · | ✓ (yfinance) | · | ✓ (yahoo-finance) | 2 / 4 |
| Excel / Sheet / CSV | · | · | · | ✓ excel/google_sheet | 1 / 4 (但用 filesystem 可覆盖) |
| Blender (3D) | · | ✓ (3d_design) | · | · | 1 / 4 |
| MCP-Atlas 长尾 (airtable / alchemy / mongodb / met-museum / national-parks / weather / wikipedia / desktop-commander / e2b / oxylabs / exa / brave-search / fetch / context7 / calculator 等 ≈25 个) | · | · | ✓ 各占 1 | · | 1 / 4 |
| Toolathlon 长尾 (canvas / 12306 / k8s / wandb / woocommerce / huggingface / pptx / pdf-tools / snowflake / howtocook / terminal / time / npx-fetch / scholarly_search 等 ≈14 个) | · | · | · | ✓ 各占 1 | 1 / 4 |
• 4-bench 公共: 仅
GitHub 一个,真正全 4 个都出现 • 3-bench 共享: Filesystem · Notion · Playwright · Google Maps/Search
• 2-bench 共享: git · slack/email · arxiv · finance
• 独家 long tail: MCP-Atlas ≈25 个,Toolathlon ≈14 个,MCP-Universe ≈3 个,MCPMark = 0 (它是 5 个全部和别人重叠)
• 唯一 server 并集 ≈ 5 + 6 (Universe 独占) + 25 (Atlas 独占) + 14 (Toolathlon 独占) + 4 (共享一次以上) ≈ 50–60 个 server, 实际去重后估算 50–60 个 server / 500+ tool
注: 上面数字基于 repo 实际 ls,和 paper 报的可能略有偏差 (paper 报 5/11/36/32, 但 Toolathlon 实际配置目录里有 34 个 yaml — 推测部分被合并算成 "32 apps")。 关键结论不变: 大头是长尾,共享小头。
3 · 数据格式逐一拆解 — 4 套 schema verbatim
这一节贴真 task 文件。 把"如果要联合训练,要不要写 schema converter"这个问题落地。
3.1 MCPMark — tasks/<server>/<diff>/<category>/<task>/{description.md, verify.py, meta.json}
tasks/notion/easy/computer_science_student_dashboard/simple__study_session_tracker/ 实际 3 个文件:
# description.md (自然语言任务描述, agent 看到的) Create a new study-session entry on the **Computer Science Student Dashboard** page. 1. Locate the ☑️ Habit tracker section of the page. 2. **Insert a new date mention** for `2025-01-29` immediately **after the existing `2022-09-02` items but before the divider block** that follows them. Match the formatting of the existing dates (bold text with a Notion date mention).
# meta.json
{
"task_id": "simple__study_session_tracker",
"category_id": "computer_science_student_dashboard",
"difficulty": "L1",
"tags": ["content organization","visual formatting","status tracking"],
"mcp": ["notion"],
"meta_data": {
"stateType": "url",
"stateUrl": "https://painted-tennis-ebc.notion.site/Computer-Science-..."
}
}
# verify.py (核心: 真用 notion_client 拉所有 block 验证)
from notion_client import Client
from tasks.utils import notion_utils
def verify(notion: Client, main_id: str | None = None) -> bool:
page_id = notion_utils.find_page(notion, "Computer Science Student Dashboard")
all_blocks = notion_utils.get_all_blocks_recursively(notion, page_id)
TARGET_DATE = "2025-01-29"; PREVIOUS_DATE = "2022-09-02"
index_previous_date = index_new_date = index_divider_after_previous = None
for idx, block in enumerate(all_blocks):
if block.get("type") == "divider":
if index_previous_date is not None and index_divider_after_previous is None:
index_divider_after_previous = idx
if block.get("type") != "paragraph": continue
for rt in block["paragraph"].get("rich_text", []):
if rt.get("type")!="mention" or rt["mention"].get("type")!="date": continue
date_start = rt["mention"]["date"].get("start")
if date_start == PREVIOUS_DATE: index_previous_date = idx
if date_start == TARGET_DATE:
index_new_date = idx
if not rt.get("annotations", {}).get("bold", False):
return False # ❌ 不加粗就 fail
return index_previous_date < index_new_date < index_divider_after_previous
notion_client 直接读真 Notion workspace。 不存在 "expected output" string,完全靠 程序化断言。 → 极度严格、没有 LLM judge 摇摆,但 task author 写起来贵。3.2 MCP-Universe — configs/mcpuniverse/<domain>/<task>.json
repository_management/github_task_0001.json 实际内容:
{
"category": "general",
"question": "Hey! I need to set up a new repo for this travel planner project ... \n
Can you help me create a repository called travel-planner-app? I need to start with
3 branches: main, feature-maps, and feature-itinerary. \n ...",
"use_specified_server": true,
"mcp_servers": [ { "name": "github" } ],
"evaluators": [
{ "func": "raw",
"op": "github.check_repository",
"op_args": "{{GITHUB_PERSONAL_ACCOUNT_NAME}}/travel-planner-app" },
{ "func": "raw",
"op": "github.check_branches_exist",
"op_args": { "owner": "{{GITHUB_PERSONAL_ACCOUNT_NAME}}",
"repo": "travel-planner-app",
"branches": ["main","feature-maps","feature-itinerary"] } },
{ "func": "raw",
"op": "github.check_file_content",
"op_args": { "owner": "{{GITHUB_PERSONAL_ACCOUNT_NAME}}",
"repo": "travel-planner-app", "path": "README.md",
"branch": "main" },
"value": "# Travel Planner App\n\nA comprehensive ..." },
...
],
"cleanups": [
{ "server": "github", "tool": "create_repository",
"cleanup_func": "delete_repository",
"cleanup_args": { "repo": "$name" } }
]
}
(func, op, op_args, value) 元组,op 就是一个已经注册到 EVALUATION_FUNCTIONS 字典的函数名。 → 写起来快,可机器生成 task,但需要新 server 时要预先注册一批 check_xxx 函数。 Jinja2 模板支持 {{ENV_VAR}}。3.3 MCP-Atlas — HF parquet 单行 + claim list
MCP-Atlas 的 task 不在 repo 里(在 HF dataset ScaleAI/MCP-Atlas 1,000 prompt parquet),repo 里只保留 sample csv。 关键字段(已在 #19 详读):
# 单条 task 的逻辑结构
{
"prompt": "<自然语言 user query>",
"ground_truth_tools": ["filesystem_read_text_file", "calculator_compute", ...],
"ground_truth_answer":"...",
"essential_claims": [
{ "claim":"the model called filesystem_read_text_file on /data/Barber Shop.csv",
"essential":"yes" },
{ "claim":"the model returned answer 'Customer'", "essential":"yes" }
],
"category": "filesystem"
}
# 评测 (mcp_evals_scores.py) — LiteLLM 调 Gemini-2.5-Pro 做 judge
EVAL_LLM_MODEL = "gemini/gemini-2.5-pro"
# 输出指标: pass_rate, coverage_rate (essential claim 是否全覆盖), diagnostics
3.4 Toolathlon — tasks/finalpool/<task_id>/{docs/, evaluation/, groundtruth_workspace/, task_config.json}
tasks/finalpool/ab-testing/ 是个典型例子。 目录结构:
ab-testing/ ├── docs/ │ ├── task.md ← user-facing prompt │ ├── agent_system_prompt.md ← agent 系统提示词 │ └── user_system_prompt.md ├── evaluation/ │ ├── main.py ← real python evaluator │ └── list_storage_buckets.py ├── groundtruth_workspace/ ← expected files + bucket names ├── initial_workspace/ ← agent 起始文件 ├── files/, preprocess/, token_key_session.py └── task_config.json
# task_config.json
{
"needed_mcp_servers": ["google-cloud", "filesystem"],
"needed_local_tools": ["claim_done","python_execute",
"handle_overlong_tool_outputs","manage_context","history"],
"meta": {}
}
# evaluation/main.py 节选
def check_storage_bucket_exists(bucket_prefix: str, project_id="mcp-bench0606") -> bool:
project_id_from_creds, credentials = get_project_id_and_credentials()
storage_client = storage.Client(project=project_id_from_creds,
credentials=credentials)
for bucket in storage_client.list_buckets():
if bucket.name.startswith(bucket_prefix):
return True
return False
def validate_task_completion(task_launch_time, task_eval_time):
if not check_storage_bucket_exists("promo-assets-for-b"):
raise ValueError("storage bucket with prefix 'promo-assets-for-b' was not created")
if not check_abtesting_logging_bucket_clean(task_launch_time, task_eval_time):
raise ValueError("logging bucket should be clean")
3.5 4 套 schema 互不兼容 — 一张图说明
| 维度 | MCPMark | MCP-Universe | MCP-Atlas | Toolathlon |
|---|---|---|---|---|
| task 配置形式 | 多文件目录 | 单 JSON | parquet 单行 | 多文件目录 |
| 验证逻辑 | Python verify.py | 声明式 DSL (op+args) | LLM-judge + claim list | 独立 Python main.py |
| 环境状态 | 真 Notion workspace 模板 | 真账号 + Jinja env 变量 | Docker 内 20 server 默认 | 真账号 + Docker app 池 |
| 是否需要 ENV var 注入 | 是 (Notion API key) | 是 ({{GITHUB_PERSONAL_ACCOUNT_NAME}}) | 是 (各 server key) | 是 (token_key_session.py) |
| cleanup 机制 | verify 完不主动清 | 显式 cleanups 段 | 无,靠 docker 重启 | 容器 reset |
| converter 可写吗? | 不可能。 MCP-Atlas 的 claim list 没有 cell-level 断言,不能转成 MCPMark 的 verify.py;Toolathlon 的真 GCP 副作用没法在 MCP-Universe DSL 里表达。 下游训练数据 (prompt + trajectory) 倒是可以拼,只是 reward 信号不能混算。
4 · 评测模式 — 真服务 vs Docker vs Mock + reset/auth
| MCPMark | MCP-Universe | MCP-Atlas | Toolathlon | |
|---|---|---|---|---|
| 真服务? | 真 Notion/GitHub/Postgres workspace | 真 GitHub/Google/Yahoo/Blender | 20 server pure docker (无需 key) + 16 server 需 key | 真 Canvas / GCP / Notion / GitHub + 自部署 docker app |
| Docker 化 | 可选 (local 也行) | 有 docker/ | 核心 make run-docker, port 1984 | 核心: 每 task 一个 docker |
| Mock? | 无 | 无 | 无 | 无 |
| Reset 机制 | 每个 task 用 Notion template URL 重新复制 | cleanups 段调 delete | 容器重启 + warning: Ctrl+C 之后要 docker kill | 容器 reset + 时间窗过滤旧数据 |
| Auth 需要 | Notion / GitHub / Postgres / OpenAI key | 各 server token + GITHUB_PERSONAL_ACCOUNT_NAME 等 ENV | 16 个 API key (Airtable / Alchemy / Brave / E2B / Exa / Slack / Google Workspace 等) | 最重: ~30 个 service token + 自己部署的 Canvas/Postgres/Email 等 |
| 可用 public eval server? | 否,本地跑 | 否,本地跑 | 否,本地跑 | 是, EVAL_SERVICE_README.md 提供公共 47.253.6.47:8080 |
实际门槛: Toolathlon 的"公共 eval service"是 4 个里唯一能让你"不搭 env 直接跑"的。 另外 3 个都要你自己搞 docker / API key。 MCP-Atlas 设了一个聪明 default — 没 key 的 20 个 server 默认 enable,加 key 才 enable 剩下 16 个,所以最低门槛进入只要 OpenAI + Gemini key 就能跑通 1/3。
5 · 评测代码 — verifier 怎么写的
5.1 MCP-Universe Evaluator — 函数链 DSL
# mcpuniverse/evaluator/evaluator.py
class EvaluatorConfig(BaseModel):
func: str # A chain of function calls, e.g., get(key1) -> foreach -> get(key2)
op: str = "" # The operator for comparison, e.g., "=", "<".
value: Any = None
op_args: Any = None
# evaluator 实际执行:
@staticmethod
def _parse_func(func: str) -> List[Dict[str, Any]]:
items = [f.strip() for f in func.split("->") if f.strip()]
funcs = []
for item in items:
info = {"name": item.split("(")[0].strip()}
assert info["name"] in EVALUATION_FUNCTIONS, f"Unknown func `{info['name']}`"
...
# 注册的 EVALUATION_FUNCTIONS 来自这些模块:
from .functions import *
from .github.functions import *
from .google_maps.functions import *
from .yfinance.functions import *
from .blender.functions import *
from .playwright.functions import *
from .google_search.functions import *
from .deepresearch.functions import *
from .notion.functions import *
from .weather.functions import *
from .mcpmark.github_functions import *
from .mcpmark.notion_functions import *
from .mcpmark.filesystem_functions import *
from .mcpmark.playwright_functions import *
from .mcpmark.postgres_functions import *
mcpuniverse/evaluator/mcpmark/{github,notion,filesystem,playwright,postgres}_functions.py。 这说明 Salesforce 团队已经把 MCPMark 当成可选评测引擎,后者是前者的"严格 verifier sub-system"。 这是一个 model 同时报 MCP-Universe + MCPMark 分的最现实路径。5.2 MCPMark verify.py — 直接调真 API
已在 §3.1 给出完整代码。 模式: def verify(client, main_id) -> bool + sys.exit(0/1)。
5.3 MCP-Atlas — Gemini-2.5-Pro claim judge
# services/mcp_eval/mcp_evals_scores.py
EVAL_LLM_MODEL = os.getenv("EVAL_LLM_MODEL", "gemini/gemini-2.5-pro")
# claim 提取 — 支持多种输入格式:
def extract_claims(claim_blob) -> List[str]:
# list of strings | list of {claim, essential} | JSON string | multi-line text
# 输出指标 (#19 已细读):
# - pass_rate: 所有 essential claim 通过率
# - coverage_rate: 覆盖到的 claim 占比
# - diagnostics: per-claim 详细 verdict
5.4 Toolathlon — 独立 python 程序, 真账号副作用
已在 §3.4 给出完整代码 (ab-testing 用 google.cloud.storage + google.cloud.logging + 时间窗过滤)。 模式: argparse(--agent_workspace, --groundtruth_workspace, --launch_time) -> exit(0/1)。
5.5 一表汇总 4 种 verifier 风格
| 风格 | 谁用 | 对模型输出格式宽松度 | 对环境副作用敏感度 | 训练时是否好做 RLVR reward |
|---|---|---|---|---|
Python verify.py hard assertion | MCPMark | 严 (字段必须完全匹配) | 高 (整个 Notion page 树都被检查) | 极适合 RLVR — bool reward 干净 |
| 函数链 DSL | MCP-Universe | 中 (op 决定) | 中 | 适合 RLVR — 已经在 MCP-Universe verl stack 里用了 |
| LLM-as-judge claim list | MCP-Atlas | 宽 (judge 容忍语义等价) | 低 | 差 — judge 自身噪声进入 reward,RL 会被 hack |
| 独立 python + 真 API 副作用 | Toolathlon | 严 | 极高 (查真 bucket / 真邮件) | 中 — reward 干净但 rollout 成本极高 (真 GCP 调用要钱) |
6 · ⭐ 多榜联训可行性分析
6.1 Capability surface 并集大小估算
把所有 server 去重,粗估"要打榜 4 个所需的 capability surface":
分布(从 §2.2 矩阵推):
- 核心 4 个 (出现在 ≥3 bench): GitHub · Filesystem · Notion · Playwright/browser — 这 4 个的训练数据可以跨 bench 复用。
- 次核心 4–5 个 (2 bench): git CLI · Google Maps/Search · slack/email · arxiv · yfinance — 部分复用。
- 长尾 ≈45 个 (1 bench 独占): MCP-Atlas 的 25 个 + Toolathlon 的 14 个 + MCP-Universe 的 3 个 (Blender / yfinance/特殊 deepresearch 等)。 这部分 必须按 bench 单独搞数据。
6.2 Schema compatibility — 4 个 prompt format 能否统一
实证看 task 的 user message:
| Bench | 典型 prompt 风格 | tool 暴露方式 | 多步预期 |
|---|---|---|---|
| MCPMark | 简短指令 (3–5 句) + 严格 spec | 预设单 server 池 | 3–10 步 |
| MCP-Universe | 对话风, "Hey! I need...",有时长达 10 行 | use_specified_server: true 限制 | 10–20 步, max_iter=20 |
| MCP-Atlas | 真用户 query 风格, 短 | 动态从 307 tool 池 enabledTools 子集 | 1–20 步, maxTurns=20 |
| Toolathlon | 非常长 (任务 + 上下文),含"如果 A 则 X 否则 Y"分支 | 多 server 同时 + 5 local tool (claim_done 等) | 长 horizon 50+ 步 |
6.3 Eval bias / 风味冲突
这是最微妙的: 4 个 bench 的"被打高分的写法"风味不同。
| Bench | SOTA 写法风味 | 反风味 (会扣分) |
|---|---|---|
| MCPMark | 精确 field-by-field 操作, 不多不少 | 多写一个空 paragraph 就 fail |
| MCP-Universe | 按 cleanups 段约定命名 / branching / 严格按 question 顺序 | 跳步 / 自创 commit message 就 fail |
| MCP-Atlas | essential claim 全 cover, 语言自然 | 过度技术性输出反而 judge 不 happy |
| Toolathlon | 条件分支正确 + 副作用幂等 + 不污染 log | 多创一个 bucket 就 fail |
→ 同一个 model 权重很难同时是这 4 种风味的最优。 例如 MCP-Atlas 喜欢"我先 read 文件,然后告诉你答案是 Customer"; MCPMark Postgres 任务喜欢"直接 INSERT / DELETE 然后 return None" — 前者是 conversational,后者是 transactional。
6.4 Bottleneck:哪个最难,哪个 transfer 最好
| Bench | SOTA 分数 (公开) | train-on-others transfer 难度 |
|---|---|---|
| MCP-Universe | GPT-5 43.72%, Grok-4 33%, Claude-4 29% | ★★ 中 (有 verl RL 栈 + 严格 dynamic eval) |
| MCPMark | gpt-5-high 51.6%, gemini-3-pro 50.6%, qwen3-coder 较高 — pass@1 | ★ 容易 (Notion/GitHub 重叠多) |
| MCP-Atlas | gpt-5.1 是 reference (Anthropic-cited) | ★★★ 难 (judge 风味很玄学) |
| Toolathlon | gemini-3-pro / claude-4.5-opus 是 leaderboard 顶 — 难度显著最高(很多 task 50+ 步) | ★★★★ 最难 (长 horizon + 真账号 + 长尾 app) |
→ Toolathlon 是最大瓶颈: 50+ 步 long horizon + ≈14 个独占 app + 真 GCP/Canvas 副作用。 MCPMark 是最容易 transfer 受益的: 只 5 个 server,且全是高频(GitHub/Notion/Filesystem/Postgres/Playwright)。
6.5 现实 ceiling 估算
假设你有一个 32B model + 真实算力 (1k H100 hour):
| 策略 | MCPMark | MCP-Univ | MCP-Atlas | Toolathlon |
|---|---|---|---|---|
| 不训, 用 GPT-5 / Claude / Gemini-3 直接评 | 50% | 40% | SOTA | ~35% |
| 单独训 MCPMark | +10pp | +3 | ±0 | +1 |
| 单独训 MCP-Universe | +4 | +8 | +1 | +3 (Universe 已含 Playwright/GitHub) |
| 4-bench 联合训 | +7 | +6 | +2 (judge 噪声) | +4 |
| 专门 MCP-Atlas judge-tuned | ±0 | ±0 | +5–8 | ±0 |
→ cell 的趋势暗示: 同一个 ckpt 在 MCPMark/Universe/Toolathlon 上能同时拿 mid-tier 名次;但 MCP-Atlas 因为 judge 风味独立,要么单独 judge-tune (会污染其他 3 个),要么放弃顶名。
7 · 如果非要做 cross-bench SOTA — 训练 recipe
7.1 数据混合
# 推荐 corpus 占比 (按 trajectory 数加权) - 共享 server (GitHub/Notion/Filesystem/Playwright): 45% ├── MCPMark task → SFT (verify.py 转 reward) ├── MCP-Universe github_task_*.json → RL (DSL → boolean reward) ├── Toolathlon 共享 server 子集 → SFT 学长 horizon - Toolathlon 长尾 app (Canvas/k8s/wandb/woocommerce 等): 25% ├── 用 Toolathlon public eval server 做 RL rollout - MCP-Universe 独家 (Blender/yfinance/deepresearch): 10% - MCP-Atlas 长尾 (Airtable/Alchemy/MongoDB/...) 的 trajectory: 15% ├── 注意: 不用 MCP-Atlas judge 做 reward,只用 trajectory 当 SFT - 通用 TOUCAN-style MCP 多 server SFT 数据: 5% ├── 修复 cold-start
7.2 训练阶段
- Stage 1: TOUCAN/Toucan-1.5M SFT — 解决冷启,让 model 会 MCP 协议。
- Stage 2: 联合 RLVR on MCPMark + MCP-Universe — 这两个 reward 干净,且 MCP-Universe 已经把 MCPMark verifier 集成进了 evaluator。 用
mcpuniverse/benchmark/runner.py+ verl GRPO stack。 - Stage 3: 在 Toolathlon public eval server 上做 long-horizon SFT-on-rollout — 用 best-of-N + claim_done 信号过滤好 trajectory。 RL 太贵不做。
- Stage 4 (可选): MCP-Atlas judge-tuned LoRA — 单独训一个 LoRA 让输出风格符合 Gemini-judge 偏好,推理时切换。 不混入主 ckpt。
7.3 风险
- Reward hack: MCP-Universe DSL 的 op 可被"恰好通过断言但任务没真做"的 trick 通过。 见 #25 详读 "三层评测" 章。
- Toolathlon API 成本: 真 GCP/Canvas/邮件 API 在大批 rollout 时会产生真实 cost (估 $5k-20k 量级)。
- Catastrophic interference: MCP-Atlas judge-tuned 风格会污染 MCPMark 的精确写法。 → 用 LoRA / Mixture-of-LoRA 隔离。
8 · SVG 图示
8.1 Server 重叠 Venn
8.2 4 bench eval pipeline 并排
8.3 训练 → 评测 fan-out
9 · 个人 take
- 4 个 bench 不会被一个 ckpt 同时 SOTA, 但可以同时"打到 SOTA 的 80%"。 真正的 SOTA 永远会被各 bench 的 specialist 拿走 — 这不是模型问题,而是各 bench 的 verifier 风味本质上互斥。
- MCP-Universe + MCPMark 是天然 co-train pair。 Salesforce 已经把 MCPMark verifier 当作 evaluator 模块导入了 (
mcpuniverse/evaluator/mcpmark/*_functions.py) — 这是迄今为止 4 个 bench 间最强的工程耦合信号。 训这两个 = 实际工作量 ≈ 1.3 倍单独训一个。 - Toolathlon 是最值得投资的 long-horizon RL 数据源。 因为 (a) 公开 public eval server 免去 env 自搭; (b) 108 task 都是 50+ 步真实 workflow; (c) 真账号副作用强制 model 学到副作用 awareness。
- MCP-Atlas 在 RL 训练里要谨慎用作 reward 源 — judge 噪声会被 RL 利用 hack。 更好的用法: 当作"deployment-style 评测" — 测 model 真在用户 query 上能不能看起来对。 用 Anthropic / OpenAI 的模型卡引用,它的政治影响力 > 它的训练价值。
- 这 4 个 bench 共同暴露了一个 missing piece: 没有一个 bench 是真的测"跨 server 长上下文调度 + 自纠错"的 — Toolathlon 最接近,但还差。 → 下一个 bench 应该叫 "MCP-Recovery"。
- 实操建议: 如果你只能选一个去打,选 Toolathlon — public eval service + long horizon = 最高 transfer 价值。 如果你能选两个, 加 MCP-Universe(因为它带 RL 训练栈)。
引用链接 (全部 GitHub raw)
- MCPMark repo: github.com/eval-sys/mcpmark
- MCP-Universe repo: github.com/SalesforceAIResearch/MCP-Universe
- MCP-Atlas repo: github.com/scaleapi/mcp-atlas
- Toolathlon repo: github.com/hkust-nlp/Toolathlon
- MCP-Atlas server template (36 个): mcp_server_template.json
- MCP-Universe github_task_0001: link
- MCPMark verify.py 示例: link
- Toolathlon ab-testing evaluator: link
- MCP-Universe evaluator code: link
- MCP-Atlas judge: mcp_evals_scores.py
- Toolathlon public eval service docs: EVAL_SERVICE_README.md
— end of #26 —