现在选 Coding Agent,很容易掉进一个看起来很合理的流程:先看 SWE-bench 或社区排行榜,再挑分数最高的模型,最后把 Codex、Claude Code 或其他 harness 接进自己的项目。

我以前也会先看这种榜单。它当然有价值,至少能快速排除明显不合适的模型。但真正把模型放进一个长期维护的仓库以后,问题会变得更具体:你的项目是 TypeScript 还是 Python,测试要不要起浏览器和数据库,改动多半是 UI、缓存、SQL 还是构建系统,历史 PR 的难度分布又是什么样。公共 benchmark 很难同时替你回答这些问题。

最近我从一条 Show HN 看到 SelfBench。它的思路不是再造一个统一排行榜,而是把你自己仓库已经合并的 PR变成 Coding Agent 的 eval task,再用同一批任务比较 model、harness、reasoning effort 和 cost。

这个方向我一开始最想确认的是:仓库真的会改变模型排名吗?

我在 2026-10-07 抓了 SelfBench 当时公开的全部 9 个 repository release,又对任务和上游 guardrail 做了一轮静态审计。结果支持“repo-specific eval 有价值”,但也顺手推翻了一个很容易写过头的结论:模型赢家确实会随仓库变化,可当前几十个任务规模的榜单,头部相差几个百分点时,还远没有稳到可以说谁“明显更强”。

SelfBench 真正有意思的地方,是把历史 PR 变成你自己的测试分布

SelfBench 的输入不是人工编出来的一组通用 coding puzzle,而是仓库已经发生过的真实修改。

大致过程是:

merged PR
   ↓
回到修改前的 base commit
   ↓
从工程请求生成 instruction
   ↓
准备 held-out tests + reference patch
   ↓
smoke / nop / oracle / determinism
   ↓
独立 reviewer
   ↓
导出 Harbor task
   ↓
同一批任务跑不同 model / harness / reasoning effort
   ↓
比较 accuracy 与 cost

这里用到的 Harbor task format 很适合做这件事。一个 task 会把 instruction、容器环境、测试和 solution 分开,agent 只在自己的工作区完成任务,verifier 再根据隐藏测试给结果。

SelfBench 在这个基础上多做了一层“从历史 PR 生产 benchmark”。对一个已经有稳定 PR 历史的团队来说,这个变化非常关键:模型不再只面对别人定义的任务,而是面对你自己真正会合并的那类改动。

这和“在公开榜单上多找几个和自己技术栈相似的项目”还是不一样。真正的 repository-specific eval 会把你仓库里的目录结构、依赖、测试习惯、业务边界和长期积累的工程约束一起带进任务里。

我觉得这才是 SelfBench 最值得借鉴的部分。它不需要证明公共 benchmark 没用,而是把公共 benchmark 的角色往前挪了一步:先拿公共榜单做 shortlist,再用自己的任务做最后选择。

9 个仓库跑下来,没有一个配置能一直拿第一

SelfBench 的公开结果 API 当时一共有 9 个仓库。我把每个 release 的 task count、passed、accuracy、model、harness、reasoning level 和 cost-per-task 拉下来重新算了一遍,先确认 published accuracy 确实等于 passed / tasks。

当前结果大概是这样:

仓库任务数最高准确率 setting
vercel/next.js38GPT-6.1 Sol / Codex / High — 84.2%
PostHog/posthog36Claude Opus 5.5 / Claude Code / High — 69.4%
earendil-works/pi50GPT-6 Sol / Codex / High — 84.0%
getsentry/sentry81Claude Opus 5.5 与 Claude Sonnet 5.5 / Claude Code / High — 82.7% 并列
mupt-ai/self-bench38GPT-6.1 Sol / Codex / High — 76.3%
vercel/eve38Claude Opus 5.5 / High 与 GPT-6.1 Sol / Low — 73.7% 并列
vercel/vercel47Claude Opus 5.5 / Claude Code / High — 80.9%
supabase/supabase36四个 setting 以 77.8% 并列第一
pingdotgg/t3code39Claude Opus 5.5 / Claude Code / High — 76.9%

把并列也算进去,9 个仓库里一共出现了 6 个不同的 exact top setting、5 个不同的 winner model family,没有任何一个完整配置在所有仓库里都拿第一。

我还对“同一 setting 在不同仓库里的相对排名”做了 Spearman rank correlation。两两仓库的相关性最低约 0.462,最高约 0.995,中位数是 0.807。

这个数字挺有意思。它不是说每个仓库都把排行榜彻底洗牌——大多数时候强模型依然大致强——但也明显没有稳定到“公共榜单第一名,换个仓库还是第一名”。

这正好解释了我为什么不太想再问“哪个 Coding Agent 模型最强”。更实际的问题应该是:

在我这个仓库、这批真实改动、这个 harness 和成本预算下,哪个 setting 更合适?

这里的 setting 不能只看 model name。SelfBench 的结果把 model、harness 和 reasoning effort 放在一起是对的。同一个模型切到不同 harness 或 effort,成本和准确率都可能变化。把“Claude vs GPT”单独拎出来做结论,信息其实已经丢了一层。

另一个结果反而比 accuracy 稳很多:在这 9 个当前 release 里,最便宜的 model family 全部是 GPT-6 Luna,只是 Low / High reasoning setting 不完全相同。

但这个结论也只能理解为 2026-10-07 这份快照。provider pricing、reasoning 配置、任务长度都会变,cost-per-task 不是一个可以永久截图保存的属性。真正可复用的是“看 accuracy × cost 的 Pareto frontier”这个方法,而不是记住今天哪个模型是多少钱。

公开目录本身可以直接看:SelfBench public directory。

真正让我改口的是:9 个仓库的第一名,都没有和第二名拉开到很干净

如果只看到上面的表,很容易继续往下写成“Next.js 更适合 GPT-6.1 Sol,PostHog 更适合 Claude Opus”。这句话方向上没错,但语气太满了。

因为当前 release 的规模只有 36 到 81 个任务。

我用每个 setting 的 passed / tasks 做了一个很朴素的 Wilson 95% 区间敏感性检查。它不是为了把这些 benchmark task 假设成严格 IID 样本,也不是要做正式的模型显著性检验,我只是想看看:排行榜上那几个百分点的差距,放进小样本不确定性以后到底有多稳。

结果是 0 / 9。

也就是说,9 个仓库里,没有一个仓库的第一名区间完全落在第二名区间之上。

举个最直观的例子,Next.js 当前第一名是 32/38,84.2%;第二名是 30/38,78.9%。数字看着差了 5.3 个百分点,但两边的描述性区间仍然重叠得很明显。

Sentry 更典型:67/81 是 82.7%,66/81 是 81.5%。这种差距如果写成“Claude Sonnet 明显击败 GPT-6.1 Sol”,基本就是让排行榜替你做了一个它没有能力做的结论。

这里不是说模型之间没有差异,更不是说 SelfBench 的结果没意义。

恰恰相反,我觉得它让模型选择更接近真实工程了。只是几十个 task 更适合做方向性证据:谁明显落后,谁进入 Pareto frontier,谁值得在自己的仓库继续跑;而不是为了 2% 或 5% 的差距下一个永久结论。

如果真要拿 repository-specific eval 做采购、团队默认模型或大规模路由策略,我会更愿意增加 task 数、重复 trial,并观察排名是否在不同批次里稳定。只跑一版 leaderboard 就定长期赢家,和只看一次公共榜单其实没有本质区别。

自动生成 benchmark 最危险的地方,不是模型作弊,而是 grader 自己偏了

SelfBench 还有一个我一开始比较警惕的设计:负责 authoring task 的 agent 能看到原始已经完成的 PR。

这很方便,因为它需要从真实修改中抽 instruction、测试和 reference solution;但它也天然带来一个问题——如果 hidden tests 写得太贴着 gold implementation,benchmark 就可能变成“复现原作者写法”,而不是“完成需求”。

SelfBench 自己显然意识到了这个风险。我把上游固定到 commit 67242b85569ea0c27af0c68bd2769ed2d02a05c4 做了源码检查,确认这些 guardrail 不是只写在 README 里:

  • static audit 会阻止 gold patch 和 held-out test patch 修改同一文件;
  • verifier 会把 agent 对 hidden-test 路径的修改恢复掉,再以只读方式保护;
  • nop 要求 base snapshot 在新测试上失败、既有 regression 继续通过;
  • oracle 要求 reference patch 应用以后通过,并且 fail-to-pass 会重复运行验证 determinism;
  • reviewer prompt 明确要求检查:另一种不同但正确的实现,也应该能通过这些测试。

我另外从 Next.js 和 Sentry 各抽了两个公开 task,看了 instruction、test patch 和 gold patch,没有执行任何第三方代码。

四个样本的结构检查都通过:test / gold 文件路径零重叠,instruction 里没有 source PR 号、GitHub URL 或 grader artifact 名称,环境 image 带 digest,hidden paths 会被保护,同时 task 里也有 benchmark canary。

人工看测试内容时,我也没有看到特别明显的“只有照着 gold 私有 helper 写才过”的情况。

例如 Next.js 的 stale cache task,instruction 要的是 stale-while-revalidate、同 key 去重、root-param key 独立等外部行为;隐藏测试主要通过真实 app fixture、cache handler 和请求行为去验证,而 gold patch 改的是内部 cache wrapper。

Sentry 一个 dropped-data UI task 甚至故意用了比较宽松的语义 regex 去检查解释文字,没有把某一句 copy 写死。这种测试设计比“必须返回原 PR 的精确字符串”健康得多。

但四个 task 只能说明这四个没发现明显问题。它绝对不能证明整个自动生成 pipeline 永远公平。Authoring agent 见过完成后的实现,这个信息优势客观存在,机械规则和 reviewer 只能降低耦合风险,不能在逻辑上把它消灭。

还有训练污染。

SelfBench 会给公开 task 加 benchmark canary,代码里也明确让这些公开 task 不要被搜索引擎正常索引。这对后续训练数据过滤和污染检测有帮助,但它解决不了更早的问题:源 PR 本来就是公开的历史代码和讨论,它以前是否已经进入训练语料,canary 无法倒推证明。

所以“这是我自己的仓库 benchmark”不等于“这是 contamination-free benchmark”。私有仓库在这点上更干净一些,但又会引入代码、凭据和数据控制问题。

我现在会这样用:公共榜单负责筛选,自己的仓库负责定默认值

跑完这轮以后,我反而更愿意继续看公共 benchmark,只是不会再让它承担最后一步决策。

如果只是个人小项目,仓库还没多少稳定的 merged PR,或者你只是偶尔用一次 Coding Agent,那自己搭 repo-specific eval 很可能不划算。看公共 benchmark、选两三个主流模型,再按价格和实际手感决定,已经足够。

但下面几种情况,我会认真考虑给自己的仓库建立 eval:

你同时在用多个模型或 harness,每个月 API 成本已经不是可以忽略的小数;团队希望确定一个默认 agent,而不是每个人凭感觉选;仓库已经有几十个到几百个代表性 merged PR;测试环境能够比较稳定地还原;或者你正在做 model routing,需要知道“什么任务送给谁”而不是只想知道“总榜谁第一”。

真正开始做时,我不会追求一次就搭出很大的 benchmark。先挑一批能代表真实工作分布的 PR,保证 task instruction 和 hidden tests 经得起人工 review,再看 accuracy、cost、失败类型和不同 setting 的稳定性。

SelfBench 已经把这条链路做得比较完整,所以我不打算再为这篇文章重复造一个仓库。想直接看实现,可以从 mupt-ai/self-bench 开始;想理解它底层 task 为什么能把 instruction、environment、solution 和 verifier 分开,可以继续看 Harbor 的 Task Structure。

如果你更关心的是“Agent 写出的测试本身靠不靠谱”,我前面还做过一轮 Mutation Testing 的第一方 A/B 实验;如果现在的问题只是 Codex 新模型已经发布但客户端不显示,可以看 Codex Model Catalog + Sub2API 原名透传。

对我来说,这次 SelfBench 最有价值的结论已经不是某个模型今天排第一。

而是模型选择终于可以从“别人榜单上的平均能力”往前走一步,变成“它在我真正会合并的这类代码修改里表现怎样”。只要同时记住另一半——你不仅要评估 agent,也要评估你拿来评估 agent 的 benchmark——repo-specific eval 才不会变成另一种更昂贵的排行榜迷信。