别信「测试已经写过了」:TestPrism 为什么说单一参考会把合格率抬高
据南京大学团队论文 TestPrism(arXiv:2610.12289,2026-11-08),14 种编码 agent 配置里最强的 Claude Fable 5.1,单一参考成功率 59.67%,同时验收所有正确实现并拒绝所有错误实现的联合成功(JSF)只有 28.00%。可接 784/785 的验证门:测试对着一份参考绿了,不等于测试可靠。数字均来自论文表,本文未复现;也不把「合格率被高估一倍」写成论文原句。

别信「测试已经写过了」:TestPrism 为什么说单一参考会把合格率抬高
本站前两篇都卡在验收这一头。《别信 Agent 说「没问题」》 说的是:不要把 agent 口头保证当成通过,人审规格,机器做独立硬检查。《让最贵的模型只写计划》 说的是:计划里要写下验证门,每一步以「命令 + 期望输出」结尾。还缺一个更容易被跳过的缺口:验证门本身,常常只对着一份参考实现,或当前这次补丁来绿。
南京大学团队的论文 TestPrism 把这件事写成了可执行的评测。据其表 2:14 种编码 agent 配置里,最强的 Claude Fable 5.1 在「初始程序失败、参考实现通过」这项单一参考标准(Reference Acceptance Rate,RAR)上达到 59.67%;同一批测试若还要接受面板里每一个正确实现、拒绝每一个错误实现,联合成功(Joint Success Function,JSF)只剩 28.00%。本文未复现该评测。
先把结论放在前面:「测试已经写过了,而且对着参考答案绿了」,并不足以说明测试可靠。 论文把单一参考评测写成 JSF 最松的特例,也是它的上限;两者之间的差距,就是那些过了参考、却经不起更多实现检验的任务占比。不要把二手报道里「合格率被高估一倍」当成论文原句——下文只用表内的 59.67% 对 28.00%。
说明:下文均据南京大学 Han Li、Lingxiang Hu、Jiacheng Huang、Ziqian Jiang、Jingkai Luo、Wei Gao、Yunfan Tan、Zun Wang、Jiaheng Liu 的论文 TestPrism: Rethinking Test Evaluation Beyond a Single Reference(arXiv:2610.12289,文中标注日期 2026-11-08;本文阅读的是其 HTML 版)转述。代码与数据有一份官方制品仓库 TestPrism/TestPrism(Apache-2.0;仓库简介写的是 official anonymous code artifact)。文中百分比与计数均来自该论文表格与正文,本文没有复现评测,也没有在自己的仓库里跑通 JSF。读者可拿走的是验收标准,不是一份「亲测」榜单。
一、JSF 要同时过三道门
TestPrism 的测试集有 300 道测试任务,来自 17 个公开基准,覆盖六种编程语言、67 个仓库与项目。每道题在评测时配一块实现面板:1 个参考实现、4 个正确的替代实现、5 个错误实现;300 题合计 3000 个已标注实现,对错各半。写测试时,这块面板对 agent 是隐藏的;评测时,提交的测试套件要在初始程序和面板里每一份实现上分别跑一遍。
论文的主指标 JSF,要求同一套测试同时满足三条:
- 在初始程序上失败。 测试得先能抓住「还没修好」的状态,不能一开始就全绿。
- 接受面板里每一个正确实现。 同一需求往往有多种合法写法;测试不能把参考实现的内部细节,误当成需求本身。
- 拒绝面板里每一个错误实现。 只认得参考答案还不够,看起来合理、其实有缺陷的实现也要被卡住。
如果把面板缩成只剩那一个参考实现,JSF 就退化为 RAR,也就是常见的 fail-to-pass:旧代码红、参考答案绿,便算成功。论文写得很清楚:JSF 不会超过 RAR;它们的差值,衡量的正是「通过了参考评测、却在完整面板上不再算成功」的任务比例——其中也包括缺失结果或执行出错的情形。
论文还报告了两组辅助指标:Valid Acceptance Rate(VAR)看测试能接受多少正确替代,Invalid Rejection Rate(IRR)看它能拒绝多少错误实现。两者都不以 RAR 过关为前置条件。另有沿用 SWT Bench 的变更覆盖(Change Coverage)和 TestExplora 的入口覆盖(Entry Coverage)。覆盖和成功相关,但论文也提醒:跑到了相关行为,并不保证断言在正确地判断它。
二、表 2:59.67% 对上 28.00%
主对比用的是各模型家族自己的原生编码 agent,并从 14 种配置里取出每个家族 JSF 最高的那一档。据表 2:
| 模型配置 | 单一参考 RAR | 联合成功 JSF |
|---|---|---|
| Claude Fable 5.1 | 59.67% | 28.00% |
| Kimi K3 | 56.67% | 24.67% |
| Qwen3.8 Max | 54.67% | 23.67% |
| GPT 5.6 sol -max | 54.00% | 23.33% |
| DeepSeek V4 Pro | 41.00% | 13.33% |
| GLM 5.3 | 43.00% | 11.33% |
最强一档已经能在将近六成任务上通过单一参考,但完整面板上只剩约两成八。以 Claude Fable 5.1 为例,59.67% 减去 28.00%,中间空着 31.67 个百分点:这些任务过了参考,却没能在完整面板上拿到联合成功。
表 2 里还有一个值得单独看的细节。六个配置里有五个的 IRR 高于 VAR——拒绝错误实现,往往比接受其他正确写法更容易一些。GLM 5.3 的拒绝率是这六档里最高的(IRR 86.33%),但接受率(VAR 50.33%)和 JSF(11.33%)反而是最低的一档。论文的判断是:只会抓缺陷还不够,测试还得容得下合法的另一种写法。
论文另做了一组诊断:在 50 道抽样任务上把面板从「只有参考」往外扩,提交的测试套件保持不变。平均 JSF 从 49.33% 起步,只加正确实现或只加错误实现都会下降;两种交替加入时,降得更明显。测试没变,是面板额外提出了「还得接受这些、拒绝那些」的要求。单一参考于是不只是最松的特例,也是这块不断扩大的面板上的上限。
三、失败从哪来:扑克牌和括号
数字之外,论文从六个模型家族各自 JSF 最高的配置中,各抽 50 条联合成功为 0 的失败轨迹,共 300 条;去掉 14 条超时后,由两位专家独立标注剩下的 286 条。据图 4,三类机制的份额是:
- 覆盖缺口 34.6%(99 条)。测试可能已经行使了某项操作,却没覆盖能暴露缺陷的输入组合。论文举的例子:一套扑克牌测试从未把 A-5 顺子(ace-low straight)拿去和三条比较,于是一个把这手顺子误判成高牌的错误实现得以通过。
- 错误断言 / 检查 50.0%(143 条)。这是最大一类:跑到了相关行为,断言却没有正确判断。例子是括号解析:测试里包含了未闭合的括号,却只检查输出数量,于是一个丢掉合法分组的错误实现也能过。
- 测试自身的执行逻辑错误 15.4%(44 条)。测试没能评到候选实现的行为。论文举的 EvoEval 例子:测试通过
self去访问存在测试类上的函数,结果多绑了一个参数,连参考修复都会失败。这类问题会拖累整体可靠性,但论文也写明:它并不能单独证明「单一参考有盲区」。
扑克牌和括号这两套测试,都在初始程序上失败、在参考实现上通过,却接受了一个错误实现。也就是说,缺输入组合和弱断言,都可以在单一参考评测里活下来,直到换上更多实现才被揭出来。
这和 785 里说的「空声明」是同一类风险:测试命令绿了,并不代表测试在判断该判断的事。784 把验收从「模型口头保证」挪到「独立硬检查」;TestPrism 补充的是:硬检查如果只对着一份参考绿,仍然可能把合格率抬高。
四、交叉验证比多开几路更值钱
论文配套提出 TestHelix,想把测试写得更能在多种实现之间站得住。它有三块:
- 异构合成。 多个隔离的 agent 各自写一对「测试 + 修复」,并要求这对组合自己先一致:测试能在初始程序上稳定失败,也能在自己的修复上通过。
- 同伴交叉验证。 把一份测试拿到同伴的修复上跑,再做不看生成修复的语义审查,并用反例回去改正。论文还提到:当多份合格修复都能通过已审查的测试套件时,用差分挑战去找能把它们分开的输入。
- 递归自我改进(RSI)。 在训练任务上调整测试生成策略,并在不相交的集合上验证后再冻结,用于正式评测。策略搜索用的是 AutoSaddler;优化目标是信号更密的 RAR,而不是更严的 JSF。
表 3 在相同的推理预算上限下,对比了 GPT 5.6 sol 与 Kimi K3。完整的 TestHelix(3 路异构合成 + 交叉验证 + RSI)把两者的 JSF 分别从原生 agent 的 23.33%、24.67% 提到 32.33%、33.33%。摘要里把这笔对照写成:相对本次评测中的原生 harness,JSF 提高 8.67 到 9.00 个百分点。若改与「只合成单对、不做交叉验证」相比,提高幅度是 11.67 到 12.00 个百分点——那是另一条对照,不要和前一条混写成同一句话。
更值得抄进日常习惯的,是消融结果。据正文:在同样预算下,只把异构对数从 1 开到 3、然后随机交上一份本地合格的套件,JSF 最多只再涨 1 个百分点;在 K=3 时打开完整的同伴交叉验证,能再加 6 个百分点以上。把交叉验证扩到 5 对,只再多 0.67 个百分点;而 RSI 改进这套 3 对流程,能再加 4.33 到 4.67 个百分点。论文的判断是:在这些预算上限里,改进测试被生成和被检查的方式,比把预算拿去多开几路更划算。
对日常 harness 来说,这句话已经够用:不要指望多生成几份测试就会自动更可靠;拿另一份合法(或看起来合法)的实现去交叉跑同一套测试,往往更值钱。
五、今天就能写进验收提示词的清单
你不必复现 TestPrism,也不必先把 TestHelix 跑起来。下面几条可以直接写进 PR 检查单,或写进 Cursor / Claude Code 的验收提示词;它们都从上述标准推出来,不是另做的「亲测」结论。
- 不要只用「旧代码红、这份补丁绿」来关闭验收。 这只相当于 RAR。能补的话,再准备至少一份正确的另一种写法,以及至少一份已知错误实现(历史 bug、失败的 agent 补丁、或刻意构造的反例),要求同一套测试接受前者、拒绝后者。
- 审查断言,而不只是看覆盖和用例数量。 只数输出个数、只检查类型、只覆盖参考实现的顺路输入,都可能在单一参考下活下来。问一句:这个断言有没有在判断规格要求的行为?
- 警惕测试绑死某一种写法。 内部函数名、碰巧的输出格式、中间状态,都不该被写成需求。测试过严,会把其他正确实现误拒;这正是 VAR 要盯的那一侧。
- 两份都能过测试的补丁,不要立刻当成等价。 若条件允许,试着找能把它们分开的输入。分不开,可能是它们真的等价,也可能是测试太弱——此时不要把「都绿了」写成已验收。
- 同一笔预算,优先拿另一种实现去交叉跑测试,而不是多开几路随机生成。 这是表 3 消融里最值得搬家的一句。
- 写 785 那种验证门时,门要指向行为,而不是「我刚写的测试已经绿了」。 完成标准仍应是可机检的命令和期望输出;但期望本身要经得起换一个正确实现、换一个反例。
如果只能改一个习惯:下次 agent 说「测试已经补上了」,先问这套测试除了参考补丁,是否还在别的正确写法和已知错误上跑过。只绿了一侧,就还只是一份对着单一参考的合格声明。
六、验证门要经得起换一个实现
784 不让人把 agent 口头「没问题」当成通过;785 要求计划里的每一步都能用命令验收。这一篇补的是验证门自己的口径:只对着一份参考绿,合格率会被抬高。TestPrism 用 300 道题和 3000 个已标注实现把这个差距写成了 59.67% 对 28.00%;TestHelix 则说明,交叉验证往往比多开几路更划算。
这些都是论文评测,不是本站复现。日常能拿走的仍然很具体:验收不要停在 fail-to-pass;断言要判断行为;有第二份实现时,就拿它来压测试。测试已经写过了,不等于测试已经可靠。
参考
- 论文:TestPrism: Rethinking Test Evaluation Beyond a Single Reference(arXiv:2610.12289,2026-11-08)
- HTML 版:https://arxiv.org/html/2610.12289
- 官方制品仓库:TestPrism/TestPrism(Apache-2.0)
- 轻对照 · 本站 784:https://blog.zhoudw.vip/blog/784
- 轻对照 · 本站 785:https://blog.zhoudw.vip/blog/785
数字与机制转述自上述论文。本文未复现评测,也不采用「合格率被高估一倍」这类二手标题作为论文原句。