4 个 MCP Benchmark 代码级深潜 — 一个模型能 SOTA 所有 4 个吗?

对象: MCP-Atlas (Scale AI) · MCP-Universe (Salesforce) · MCPMark (eval-sys) · Toolathlon (HKUST)· 深度: 直接读 GitHub repo 里的 task config / verifier / docker-compose / server 清单
前置阅读: #19 MCP-Atlas 深读 · #21 4-bench 高层对比 · #25 MCP-Universe 深读
关键词: cross-benchmark · server overlap matrix · evaluator code · multi-bench RL · capability surface

速读卡片 (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 之间存在评分口味冲突 — 在一个上拿满分的写法可能在另一个上掉分。

4 共享
仅 GitHub / Notion / Filesystem / Playwright 在 ≥2 bench
~88
4 bench 唯一 server 并集 (粗估)
4 套
完全不兼容的 task schema
理论可
实际门槛 = env 搭建 ≫ 模型能力

立场: 这不是 #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 / AppMCPMark
(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✓ emails2 / 4 (不同实现)
arxiv / pubmed / open-library 等学术··✓ (3 个)✓ (arxiv_local 等)2 / 4
Yahoo finance / financial·✓ (yfinance)·✓ (yahoo-finance)2 / 4
Excel / Sheet / CSV···✓ excel/google_sheet1 / 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 个)
···✓ 各占 11 / 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
MCPMark schema 特点: 验证是真 Python 函数,调用 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" } }
  ]
}
MCP-Universe schema 特点:声明式 DSL — 每个 evaluator 是一个 (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
MCP-Atlas schema 特点: LLM-as-judge + claim list。 优点是 task 写起来最快,缺点是 judge model 偏好直接影响排名 — 比如某个 model 输出 "Customer" vs "The first word is Customer.",judge 可能给不同分。

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")
Toolathlon schema 特点: 真账号 + 真 API 副作用。 evaluator 是个独立 python 程序,会去查 Google Cloud Storage 和 Cloud Logging,带时间窗过滤防污染。 → 这意味着 不可能在本地纯 mock,必须用 Toolathlon 团队的 public eval server (或自己搞一套 GCP 子账号)。

3.5 4 套 schema 互不兼容 — 一张图说明

不可能。 MCP-Atlas 的 claim list 没有 cell-level 断言,不能转成 MCPMark 的 verify.py;Toolathlon 的真 GCP 副作用没法在 MCP-Universe DSL 里表达。 下游训练数据 (prompt + trajectory) 倒是可以拼,只是 reward 信号不能混算。
维度MCPMarkMCP-UniverseMCP-AtlasToolathlon
task 配置形式多文件目录单 JSONparquet 单行多文件目录
验证逻辑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 可写吗?

4 · 评测模式 — 真服务 vs Docker vs Mock + reset/auth

MCPMarkMCP-UniverseMCP-AtlasToolathlon
真服务?真 Notion/GitHub/Postgres workspace真 GitHub/Google/Yahoo/Blender20 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 等 ENV16 个 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 *
重要发现: MCP-Universe 已经把 MCPMark 的 verifier 直接引进来了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 assertionMCPMark (字段必须完全匹配)高 (整个 Notion page 树都被检查)极适合 RLVR — bool reward 干净
函数链 DSLMCP-Universe中 (op 决定)适合 RLVR — 已经在 MCP-Universe verl stack 里用了
LLM-as-judge claim listMCP-Atlas (judge 容忍语义等价) — judge 自身噪声进入 reward,RL 会被 hack
独立 python + 真 API 副作用Toolathlon极高 (查真 bucket / 真邮件)中 — reward 干净但 rollout 成本极高 (真 GCP 调用要钱)

6 · ⭐ 多榜联训可行性分析

6.1 Capability surface 并集大小估算

把所有 server 去重,粗估"要打榜 4 个所需的 capability surface":

|servers needed| ≈ 50–60 个 unique server  ·  |tools| ≈ 500–700 个

分布(从 §2.2 矩阵推):

训练侧: 公共 4 server 占比 ≈ 4/55 ≈ 7%,但task 数占比可能 ≈ 25–30% (因为 4 bench 都重 GitHub/Notion)。 → 共享 server 上的训练 边际收益高;长尾 server 单条 trajectory 成本高且不 transfer。

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+ 步
4 种 prompt 风格可以同时训练在一个 model 上(都是自然语言英语),但 prompt format 的偏差会让 in-distribution 性能不均: 习惯 MCPMark 短指令的 model 在 Toolathlon 50 步长任务上容易 mid-trajectory 漂移; 反之亦然。

6.3 Eval bias / 风味冲突

这是最微妙的: 4 个 bench 的"被打高分的写法"风味不同

BenchSOTA 写法风味反风味 (会扣分)
MCPMark精确 field-by-field 操作, 不多不少多写一个空 paragraph 就 fail
MCP-Universe按 cleanups 段约定命名 / branching / 严格按 question 顺序跳步 / 自创 commit message 就 fail
MCP-Atlasessential 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 最好

BenchSOTA 分数 (公开)train-on-others transfer 难度
MCP-UniverseGPT-5 43.72%, Grok-4 33%, Claude-4 29%★★ 中 (有 verl RL 栈 + 严格 dynamic eval)
MCPMarkgpt-5-high 51.6%, gemini-3-pro 50.6%, qwen3-coder 较高 — pass@1★ 容易 (Notion/GitHub 重叠多)
MCP-Atlasgpt-5.1 是 reference (Anthropic-cited)★★★ 难 (judge 风味很玄学)
Toolathlongemini-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):

策略MCPMarkMCP-UnivMCP-AtlasToolathlon
不训, 用 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 训练阶段

  1. Stage 1: TOUCAN/Toucan-1.5M SFT — 解决冷启,让 model 会 MCP 协议。
  2. Stage 2: 联合 RLVR on MCPMark + MCP-Universe — 这两个 reward 干净,且 MCP-Universe 已经把 MCPMark verifier 集成进了 evaluator。 用 mcpuniverse/benchmark/runner.py + verl GRPO stack。
  3. Stage 3: 在 Toolathlon public eval server 上做 long-horizon SFT-on-rollout — 用 best-of-N + claim_done 信号过滤好 trajectory。 RL 太贵不做。
  4. Stage 4 (可选): MCP-Atlas judge-tuned LoRA — 单独训一个 LoRA 让输出风格符合 Gemini-judge 偏好,推理时切换。 不混入主 ckpt

7.3 风险


8 · SVG 图示

8.1 Server 重叠 Venn

MCPMark (5) MCP-Atlas (36) Toolathlon (~32) MCP-Universe (11) GitHub (4/4) Filesystem Notion Playwright Postgres ~25 long-tail (airtable, exa, mongodb, ...) ~14 long-tail (Canvas, k8s, wandb, ...) Blender, yfinance, deepresearch
图 1 · 4 bench server 重叠示意。 GitHub 是唯一 4-bench 公共;Filesystem/Notion/Playwright 在 3 个 bench 出现;真正的 capability surface 大头在 4 个角落的"长尾"区。

8.2 4 bench eval pipeline 并排

MCPMark tasks/<srv>/<diff>/<t> description.md → agent 真 Notion/GitHub API verify.py (Python) bool reward MCP-Universe configs/<dom>/*.json question (Jinja env) 真 + docker pool func-chain DSL eval bool reward MCP-Atlas HF parquet 1k prompt enabledTools 子集 docker port 1984 Gemini-2.5-Pro judge noisy pass/coverage Toolathlon tasks/finalpool/<t>/ docs/task.md (长) 真 GCP/Canvas + docker evaluation/main.py bool reward (贵)
图 2 · 4 个 bench 的 eval pipeline 横向对比。 蓝色 = 干净 bool reward; = LLM judge 噪声;绿 = 可做 RLVR。 MCP-Atlas 的 judge 步是和其他 3 个最大差异源。

8.3 训练 → 评测 fan-out

TOUCAN 1.5M SFT (冷启) MCPMark verify-RLVR MCP-Univ verl GRPO Toolathlon long-horizon SFT MCP-Atlas judge LoRA Trained Model (32B) MCPMark pass@1 MCP-Universe 三层 eval MCP-Atlas pass/coverage Toolathlon avg@k 绿 = eval fan-out · 蓝 = 训练数据流入 · 红虚线 = 单独 LoRA (不污染主 ckpt)
图 3 · 一个 ckpt 在 4 bench 上做 fan-out 评测的训练 recipe 示意。 MCP-Atlas 因为 judge 风味独立,用 LoRA 隔离;主 ckpt 同时被 MCPMark/Universe/Toolathlon 联合训。

9 · 个人 take


引用链接 (全部 GitHub raw)

— end of #26 —