本文记录一次真实的模型选型调研。所有数字都标注了抓取来源与抓取日期,体检脚本的输出为本地实测。
让 WorkBuddy 做"当前主流大模型四维能力对比",要求很简单:编码、多模态、长文本、工具使用四个维度,给团队做技术选型参考。
第一轮它交回来一张挺漂亮的表——10 个模型、四个维度、每个数字都带脚注。看着可以直接拿去汇报。
但我习惯性地做了一件事:把表里的分数拿回到发布这个分数的源头去核对。然后整张表的编码维度就塌了一半。
初版表里,编码维度的头号依据是 SWE-bench Verified。当时看到的聚合榜是这么排的:
排名 | 模型 | 分数 | 聚合站标注的来源 |
|---|---|---|---|
1 | Claude Opus 5 | 96.0% | System card(2026-07-24) |
2 | Claude Mythos 5 | 95.5% | System card(2026-06-09) |
3 | Claude Fable 5 | 95.0% | Model card(2026-07-15) |
来源:benchlm.ai/benchmarks/sweVerified 与 benchmarklist.com/benchmarks/openai_swe_bench_verified,2026-10 中下旬更新。两站都标了来源类型与取样日期(System card / Model card / self-reported + 日期),这也是后面能反查回去的入口。
看起来无懈可击。问题出在下一步——我打开 SWE-bench 官方榜 swebench.com 想确认这个 96%:
mini-SWE-agent 2.0.0;也就是说:一个在官方榜上查无此模型的分数,被放到了聚合表的第一名。96% 和 76.8% 不是"两个来源口径不同"这种小差异,是整整 19 个百分点、且其中一个无法溯源。
顺带说句公道话,被我查的这个聚合站自己在页面上写得很诚实:
We show this table for reference; we do not rank on it. ... We compile the table from provider self-reports and secondary reports and keep it for display only.
问题不在它,在于我差点把"for reference"的内容当成决策依据用了。
这次踩完之后,我把"引用一个 benchmark 分数之前必须过一遍"固化成了三个检查。任何一个不通过,这个分数就不能进结论。
基准分数不是静态事实,它是某个时间点、某套配置下的快照。
SWE-bench Verified 官方榜最新条目停在 2026-02-26,距今 241 天。这意味着 GPT-6 系、Claude 5.5 系、Gemini 4 这一代模型一个都没进去。网上流传的那些 90%+ 分数,没有一个能对上官方榜的条目。
所以这条检查很简单:先把榜上最新条目的日期扒出来,距今超过 120 天就直接判废,连里面的数都不用看。
这是最狠的一条,也是这次翻车的直接原因。一个分数如果在它的官方榜上查不到对应条目,那它就不是"榜单分数",而是"某篇发布材料里的一句话"。后者可以作为厂商自述引用,但不能挂在榜单名下面。
即便模型在榜、榜也在更,还要看跑分用的 agent 是否相同。Terminal-Bench 4.0 官方榜每个条目都标了 harness:
Opus 5.5 (max) [Claude Code] 64.8% ± 3.1% Sep 22, 2026
GPT-6 Astra (max) [Codex] 58.2% ± 2.8% Sep 3, 2026
GLM-5.3 (max) [Claude Code] 41.8% ± 3.2% Aug 14, 2026这张榜衡量的是"模型 + 配套 agent"的组合能力,不是裸模型。跨 harness 的两个分数不能直接比。反过来,如果某个聚合站的同一张表里,有的条目来自 mini-SWE-agent、有的来自 Harbor/NexAU、有的标注 self-reported,那这张表的纵向排序就是无效的。
把前两条检查写成脚本。--model 那个参数是核心——它回答"这个模型到底在不在官方榜上"。
#!/usr/bin/env python3
"""
bench_freshness.py —— 引用任何 benchmark 分数之前的"体检脚本"。
两条检查:
1) 新鲜度:榜上最新条目的日期距今多少天(>120 天基本不可用于当期决策)
2) 存在性:某模型到底有没有出现在官方榜上
用法:
python3 bench_freshness.py https://www.swebench.com/
python3 bench_freshness.py https://www.swebench.com/ --model "Claude Opus 5"
python3 bench_freshness.py https://www.tbench.ai/leaderboard --model "Opus 5.5"
注意:这两个榜单都把结果塞在 <script> 的 JSON payload 里做客户端渲染,
用"去标签 + 正则扫表格"的写法会什么都捞不到(我第一版就是这么翻车的)。
"""
import argparse
import re
import sys
import urllib.request
from datetime import date, datetime
UA = ("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) "
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0 Safari/537.36")
DATE_PATTERNS = [
(re.compile(r"\b20\d\d-\d\d-\d\d\b"), "%Y-%m-%d"),
(re.compile(r"\b(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) \d{1,2}, 20\d\d\b"), "%b %d, %Y"),
]
STALE_DAYS = 120
def fetch(url: str) -> str:
req = urllib.request.Request(url, headers={"User-Agent": UA})
with urllib.request.urlopen(req, timeout=30) as r:
raw = r.read().decode("utf-8", "replace")
# 不要去 script —— 表格数据在里面
return raw
def newest_date(raw: str):
seen = []
for pat, fmt in DATE_PATTERNS:
for m in pat.findall(raw):
try:
seen.append(datetime.strptime(m, fmt).date())
except ValueError:
pass
today = date.today()
past = [d for d in seen if d <= today]
return max(past) if past else None
def main():
ap = argparse.ArgumentParser()
ap.add_argument("url")
ap.add_argument("--model", help="要查存在性的模型名")
args = ap.parse_args()
raw = fetch(args.url)
today = date.today()
print(f"source : {args.url}")
print(f"fetched: {today}")
nd = newest_date(raw)
if not nd:
print("newest : <未解析出日期> —— 换个复用的解析方式,别硬猜")
return 1
gap = (today - nd).days
flag = "⚠ 停更" if gap > STALE_DAYS else "ok"
print(f"newest : {nd} (距今 {gap} 天) [{flag}]")
if args.model:
def norm(s):
return re.sub(r"[\s\-_.]+", "", s).lower()
hay = norm(raw)
needle = norm(args.model)
hit = needle in hay
print(f"model : {args.model!r} → {'在榜' if hit else '❌ 榜上不存在'}")
if not hit:
print(" ⚠ 该模型名未出现在官方页面,任何引用它的分数都不可溯源")
print(f"verdict: {'不可用于当期选型' if gap > STALE_DAYS else '可用于当期选型(仍需核对 harness)'}")
return 0
if __name__ == "__main__":
sys.exit(main())实测输出(本机运行,2026-10-25):
$ python3 bench_freshness.py https://www.swebench.com/ --model "Claude Opus 5"
source : https://www.swebench.com/
fetched: 2026-10-25
newest : 2026-02-26 (距今 241 天) [⚠ 停更]
model : 'Claude Opus 5' → ❌ 榜上不存在
⚠ 该模型名未出现在官方页面,任何引用它的分数都不可溯源
verdict: 不可用于当期选型
$ python3 bench_freshness.py https://www.swebench.com/ --model "Claude 4.5 Opus"
...
model : 'Claude 4.5 Opus' → 在榜
$ python3 bench_freshness.py https://www.tbench.ai/leaderboard --model "Opus 5.5"
source : https://www.tbench.ai/leaderboard
fetched: 2026-10-25
newest : 2026-09-29 (距今 26 天) [ok]
model : 'Opus 5.5' → 在榜
verdict: 可用于当期选型(仍需核对 harness)两条命令、十秒钟,就把初版表里的编码维度依据判了死刑。
我最早写的是常规套路:正则去掉 <script> 标签,再剥掉 HTML 标签,然后从文本里捞分数。
结果输出的是一堆 "resolved": 72.7 这种 JSON 碎片,日期干脆解析不出来。原因:这两个站都是前端渲染,表格数据以 JSON 形式嵌在 <script> 里,页面上肉眼看到的表格是浏览器跑完 JS 之后才有的。
所以脚本里那句 # 不要去 script —— 表格数据在里面 是踩出来的。如果你要用 Playwright 之类的无头浏览器去抓,那是另一条路,也能过;但对于"先确认这个分数能不能用"这件事,在原始 HTML 里做字符串匹配比起浏览器更快、也更不容易被前端改版搞坏。
判掉聚合站数据之后,我改用两类一手来源:厂商官方文档/发布说明(规格、价格、工具清单,天然可核查),和独立第三方统一 harness 的榜(当期只有 Terminal-Bench 4.0 同时覆盖中美最新旗舰)。
编码维度最终留下这张表(Terminal-Bench 4.0 官方榜,抓取日 2026-10-24):
排名 | 模型(推理档 / harness) | 解决率 | 发布日期 | 榜单总开销 |
|---|---|---|---|---|
1 | Claude Opus 5.5(max / Claude Code) | 64.8% ±3.1% | 2026-09-22 | $4.7k |
2 | Claude Sonnet 5.5(max / Claude Code) | 61.8% ±2.9% | 2026-09-28 | $7.3k |
3 | GPT-6 Astra(max / Codex) | 58.2% ±2.8% | 2026-09-03 | $3.3k |
3 | GPT-6.1 Sol(max / Codex) | 58.2% ±3.1% | 2026-09-29 | $0.6k |
5 | Claude Fable 5.1(max / Claude Code) | 57.9% ±3.8% | 2026-09-01 | $6.2k |
9 | GLM-5.3(max / Claude Code) | 41.8% ±3.2% | 2026-08-14 | $2.7k |
13 | Qwen3.8-Max-0902(max / Claude Code) | 27.0% ±3.8% | 2026-09-02 | $4.6k |
注意第 3 名:GPT-6 Astra 和 GPT-6.1 Sol 分数一模一样,都是 58.2%,但榜单记录的总开销一个是 $3.3k、一个是 $0.6k,差了 5.5 倍。 再看第 2 名 Sonnet 5.5,分数比第一名低 3 个点,开销反而高 $2.6k。
这些东西是"综合排名"给不了你的。任何把四个维度压成一个总分的展示方式,都会把这些干活时真正要算账的信息弄丢——这也是我最后拒绝给综合总排名的原因。
这次走完之后的收口,下面是截至 2026-10-25 的实测状态:
一、来源分级必须在交付物里显式标出来。 我最后用的分档是这样的:
来源 | 性质 | 最新数据日 | 本期可用性 |
|---|---|---|---|
Terminal-Bench 4.0 官方榜 | 独立第三方、统一 harness | 2026-09-29 | 高(局限:绑定厂商自带 harness) |
厂商官方文档 / 发布博客 | 一手 | 2026-07 ~ 10 | 高(规格、价格、工具清单) |
MMMU-Pro 汇总榜 | 多为厂商自报、头部已饱和 | 2026-10-18/20 | 中(1 分差不解读为能力差异) |
SWE-bench Verified 官方榜 | 独立但停更 | 2026-02-26 | 不可用于当期决策 |
τ²-bench、BFCL V4 | 饱和 / 停更 | 2026-10-08 / 2026-04-12 | 低(仅历史参考) |
各类"AI 排行榜"聚合站 | 二次加工 | — | 不采用 |
二、缺失即留空。 查不到公开分数的格子写"未见公开数据",不要用估算值、也不要用同类模型的数去填。这次有 4 个模型的多模态分数就留了空——比编一个看起来完整的表有用得多。
三、自己跑一遍再决定。 厂商自报分和第三方榜分在跨 harness 时不可比。正式选型前,用你自己 10–20 条真实任务,在同一个 harness、同一推理档位下跑一遍。这个成本远低于选错之后的迁移成本。
顺带说另一个现象:有个 GitHub 仓库每天自动从聚合站同步 Top-10,最近同步日 2026-10-21,但里面挂的还是 Terminal-Bench 2.0(榜首 GPT-5.5 82.0%),而官方已经跑到 4.0 了,榜首变成了 Opus 5.5 的 64.8%。
每天同步,不代表同步的是最新版。
这类仓库的问题是双向的:它既传播了无法溯源的自报分数,又因为停在旧的大版本上而让用户以为自己在看当期数据。判断依据还是那三个信号——同步频率不算一个。
这次最有价值的产出不是那张对比表,是那 30 行体检脚本。表会过期,脚本不会——下次要引用任何一个 benchmark,先 python3 bench_freshness.py <官网> --model <模型名> ,十秒钟就知道这个分数能不能写进结论。
给 WorkBuddy 派这类调研任务时,我现在的 prompt 里会直接写死一句:"每个分数必须能回到发布它的官方页面找到对应条目,找不到的标注为不可溯源,不要填充。" 加这一句之后,它交回来的东西质量完全不同。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。