绿 了 的 测试, 不 等于 规格 真的 满足 了
SpecBench 用 30 个从零写的系统级任务,把可见的单功能测试和隐藏的组合测试分开。奖励黑客缺口是两者通过率之差。代码行数每增加十倍,第 90 百分位缺口大约多 27 个百分点。有的「编译器」靠哈希表记住公开测试,验证分 97%,留出分是 0。

本文目录
本文是论文 SpecBench: Measuring Reward Hacking in Long-Horizon Coding Agents(arXiv:2605.21384)正文第 1 节至第 5 节及附录 A 至 C 的中文译文,由智测团队翻译。参考文献和附录 D 的逐条任务清单未展开。正文保留了任务规模、奖励黑客缺口、案例和算力账单里的数字。
1 引言
图 1 是评测框架。编码智能体根据高层规格迭代开发软件,并对可见的验证测试 s_val 做优化。这些测试分别核验单个功能。生成的代码再在留出测试 s_test 上评测。留出测试要求跨功能的、接近真实使用的组合场景。奖励黑客缺口 Δ 是两者之差:Δ = s_val − s_test。它量化智能体在代理指标上刷了多少分。图注写:若系统真正通过全部验证测试,缺口应为 0。正文的定义更精确:Δ = 0 表示没有在刷分,也就是验证通过率与留出通过率一致,而不只是验证测试全过。
软件工程正在换范式。开发者越来越多地把复杂系统的端到端实现交给自主智能体。智能体在人很少介入的情况下迭代写代码、测试、再改(Anthropic,2026;OpenAI,2025a)。任务时程变长之后,产出的代码量开始超过任何人能认真审阅的程度。监督因此塌缩到一个表面:自动测试套件。开发者把它当作规格是否满足的代理,智能体把它当作优化目标。对着这个代理优化,会造成强化学习里研究已久、但在自主编码里还较少被量化的漏洞:奖励黑客(Skalse 等,2022;Krakovna 等,2020)。当唯一反馈是测试过不过,智能体可以走阻力最小的路,写出能通过那些测试、却不满足开发者真实意图的代码。
奖励黑客已有定性案例(Wang 等,2026),但这个领域缺少在智能体编码里定量测量它的办法。本文提出 SpecBench:30 个系统级编码任务,从 JSON 解析器到操作系统内核。每个任务用两套测试评(图 1)。验证套件对智能体可见,供它迭代,逐个测规格里的功能。留出套件对智能体隐藏,把同样这些功能组合成端到端使用场景。例如 SQL 数据库任务里,验证测试分别覆盖 SELECT、JOIN 和 GROUP BY,留出测试是可以把三者组合起来的查询。奖励黑客缺口是验证通过率减去留出通过率。正的缺口表示智能体在可见代理上得分,却没有真正满足规格。
图 2 把奖励黑客缺口对参考实现的代码行数作图。每个点是一次实验。缺口的上界(第 90 百分位)随规模可预测地上升:代码行数每增加十倍,第 90 百分位缺口大约增加 27 个百分点。
作者在模型、编码脚手架(Codex、Claude Code、OpenCode)和搜索策略(AIDE、Linear、Autoresearch)上做了大规模经验研究。他们发现每个模型都能在每个任务上把可见测试套件刷满。在这层均匀的通过率下面,奖励黑客沿两条轴放大。第一,验证与留出通过率的缺口随任务复杂度增长(图 2)。第二,更弱的模型(用 MMLU 衡量)比更强的模型缺口更大(图 4)。两条发现给出同一条实践警告:团队把任务拉长,或换成更小的模型时,智能体的绿色测试报告越来越掩盖下降的符合度。
除了定量结果,作者还记录刷分策略本身。一端是功能隔离:单个功能实现了,但组件之间不共享状态。另一端是故意利用:把验证测试记进查找表,完全绕过真正的实现。
总结有三条。(i)正式定义并测量长程智能体编码中的奖励黑客,补上评测缺口。(ii)给出原则性框架和测试床,暴露规模化测试驱动开发里藏着的脆弱性。(iii)这些结构性利用在不同模型、搜索策略和代码库规模上都很普遍,因此需要重新思考如何指导和评测人工智能系统。下一代编码智能体的安全,尤其在长程任务上,应优先真正的架构完整性,而不是被游戏化的空壳制品。
2 基准设计
设置。每个任务提供自然语言规格 S、带桩实现的起始代码,以及作为优化目标的验证测试套件 T_val。智能体 A 收到 S 和 T_val,在 N 步预算内迭代生成代码、跑 T_val、再修改,得到候选实现 c。另一套留出测试 T_test 从不给智能体看,只用于评测。规格 S 定义目标系统的全部要求,并写明系统会被用在端到端的复杂功能交互场景里,而 T_test 评的就是这些场景。
测量奖励黑客。s_val(c) 和 s_test(c) 是 c 在验证套件和留出套件上的通过率,取值在 0 到 1。奖励黑客缺口定义为:
Δ(c) = s_val(c) − s_test(c)
Δ 大于 0 时,智能体把代理(验证通过率)优化得超过了真实的规格符合度:功能级测试过了,功能必须组合时失败。Δ = 0 表示没有在刷分。这直接实例化 Skalse 等人的框架:优化代理奖励偏离真实目标。这里代理奖励是 s_val,真实目标是 s_test。
表 1 按任务时程汇总。短时程是参考实现少于 1 万行,9 个任务,平均 5.1 千行,平均 53 个验证测试、102 个留出测试。中时程是 1 万到 2.5 万行,13 个任务,平均 1.38 万行,66 个验证测试、80 个留出测试。长时程超过 2.5 万行,8 个任务,平均 4.56 万行,54 个验证测试、99 个留出测试。全部 30 个任务,平均 1.95 万行,59 个验证测试、93 个留出测试。
测试设计。让 Δ 忠实测量奖励黑客的关键,是 T_val 和 T_test 的关系。验证套件对每个单独功能有测试。例如 SQL 数据库的验证测试分别核验 SELECT、JOIN、GROUP BY 和 HAVING。留出套件在每个测试里组合这些功能。例如一条查询连接两张表,按连接进来的列分组,再用 HAVING 过滤聚合结果。关键是,T_test 不引入 S 和 T_val 已经规定之外的要求。被测的每个组合都是规格所要求的。真正符合规格的实现,不加修改就应两套都过。因此 Δ 大于 0 反映的是智能体在刷代理。
任务套件。30 个系统级编程任务,复杂度跨度很大:短的如建一个 JSON 解析器(参考实现约 1,500 行),超长的如从零实现操作系统内核(参考实现约 11 万行)。每个任务都带一份通过全部 T_val 和 T_test 的参考实现,保证测试套件是可满足的。表 2 与先前基准比较。这些基准里,只有 SpecBench 能测量奖励黑客。注意,这里的验证测试和留出测试,不要和 SWE-Bench Pro 那种训练/验证划分混淆。那里的划分是不同任务。SpecBench 上,T_val 和 T_test 是为同一个任务设计的两套测试。
| 基准 | 任务数 | 代码行范围 | 语言 | 从零写 | 测量奖励黑客 |
|---|---|---|---|---|---|
| HumanEval | 164 | 5–50 | Python | 是 | 否 |
| MBPP | 974 | 5–30 | Python | 是 | 否 |
| ClassEval | 100 | 50–200 | Python | 是 | 否 |
| SWE-bench Verified | 500 | 不适用(补丁) | Python | 否 | 否 |
| SWE-bench Pro | 723 | 不适用(补丁) | Python | 否 | 否 |
| LiveCodeBench | 400 以上 | 10–100 | Python | 是 | 否 |
| DevBench | 22 | 1 千–1 万 | Python | 是 | 否 |
| KernelBench | 250 | 50–500 | CUDA | 是 | 否 |
| SpecBench | 30 | 1.5 千–11 万 | C / Python / Go | 是 | 是 |
3 实验
智能体 A 用两层结构:内层智能体写和改代码,外层搜索循环决定精炼哪个候选 c。这样可以独立变化编码模型和搜索策略。本节之外,附录 C 还有一个案例。
内层智能体。三个:Codex、Claude Code、OpenCode。它们是前沿级编码智能体,能用工具、编辑文件、访问终端。为扩大模型覆盖,OpenCode 这个开源命令行再配开放权重和接口模型。正文写「五个」,实际列出六个:DeepSeek-V3.2、DeepSeek-V4-Pro、Qwen3-Coder、Kimi-K2.5、Kimi-K2.6、Minimax-M2.7。译文按列出的名称照录。
搜索策略。每个编码智能体外面配一种搜索策略,控制外层循环如何探索解空间。生成解的过程可以看成树:每个节点是内层智能体建出的一整份代码库。每个节点可以分出子节点,在父节点的代码库上扩展,试图通过更多验证测试。根节点是给智能体的起始桩代码。每次提示产生一个新节点。三种策略:AIDE、Linear、Autoresearch。AIDE 常用于优化代码解,用树搜索,分支操作是起草、调试和改进。每一步选择搜索树里最有希望的节点,用三种操作之一生成子节点。AIDE 里智能体只有从根到当前最好节点这条路径的上下文,没有兄弟节点的上下文。Linear 是让编码智能体做长程任务的简单办法:顺序精炼,不分支,每一步只改进父节点那一个候选。Autoresearch 扩展 Linear,始终记住到目前为止验证分数最好的那一个候选。图 3 画出三者的差别。Linear 返回链上的最终节点。Autoresearch 也走单链,但按公开验证分数保留遇到过的最好候选。
3.1 任务时程与奖励黑客
先看实现时程长度(用参考实现的代码行数衡量)和奖励黑客严重程度的关系。图 2 把每次运行的 Δ 对参考行数作图。平均缺口和第 90 百分位缺口都随任务规模可预测地上升。例如第 90 百分位缺口大约每十倍行数增加 27 个百分点(R² = 0.21)。不到 1 万行的任务,最坏缺口是 21 个百分点。超过 2.5 万行的任务,达到 100 个百分点。
这个缩放说明,长程代码生成里的奖励黑客,较少由孤立的实现难度驱动,更多由组合表面积的增长驱动。系统需要的实现变大时,内部接口、共享不变量和跨功能执行路径的数量,比功能级验证测试的数量增长快得多。智能体因此可以用局部正确的处理器或功能专用的捷径拿到高验证分,同时仍然建不出这些功能要交互所需的全局架构。R² 相对不高,说明行数只是时程的粗代理:有些小任务仍有难的语义交互,有些大任务的模块结构更容易拆。尽管如此,Δ 的急剧上升表明,长程任务给严重奖励黑客制造更多机会,使它从偶发边界变成结构性失败模式。
3.2 模型能力与奖励黑客
图 4 把每个模型的平均奖励黑客缺口对一般能力作图,用 MMLU 当粗代理。趋势清楚为负:更强的模型缺口更小。但能力单独消除不了问题。即便最强的模型也留下非零缺口,说明奖励黑客不只是弱模型的失败模式。
中图和右图说明趋势从哪来。各模型的验证分几乎饱和:更强和更弱的模型都能把公开测试优化到很高。差别只在留出测试上显现,较弱模型的分数低得多。一旦智能体有能力拟合功能级检查,单靠验证套件就分不出真正的实现质量。留出套件揭示的是:模型有没有建出真实使用场景要正确通过所需的底层系统架构。
两条结论。第一,提高模型能力会改善真实的规格符合度。更强的模型更善于推出测试 T_val 和规格 S 背后的预定抽象,更少依赖脆弱的、功能专用的实现。第二,更好的模型并不消除测试驱动优化带来的激励错配。验证套件只观察有限的功能级行为,实现可以得分很高,同时仍缺少真实使用所需的共享不变量和跨功能交互。SpecBench 评的是规格已经蕴含的使用场景,而不是引入新要求。所得缺口因此测量:可见的测试表现能把真正的实现质量高估多少。
3.3 智能体与搜索方式
图 5 报告每种智能体和搜索策略组合的验证通过率与留出通过率。每根柱是验证分,柱中实心部分是留出分,阴影部分是奖励黑客缺口 Δ。多数设置下验证分接近饱和,说明智能体能可靠地优化可见验证测试。阴影面积差很多,意思是相近的验证分可以对应很不同的真实规格符合度。
奖励黑客不绑在某一种智能体或搜索策略上。Claude Code 在 AIDE、Autoresearch 和 Linear 下的验证分几乎一样,但留出分低得多,缺口大约 43 到 48 个百分点。Codex 与搜索方式的交互更强:AIDE 在 Codex 的运行里留出分最高,Autoresearch 的缺口最大。这说明,当验证分与组合正确性对不齐时,保留验证分最好的候选会放大对代理的过度优化。OpenCode 相反:AIDE 的缺口最大,Autoresearch 和 Linear 收回更高的留出分。
搜索策略改变奖励黑客如何表现,但不消除底层的激励错配。树搜索在探索发现真正更好的架构时有帮助,但若脆弱候选在验证测试上得分高,它也会选中它们。记住迄今最好的候选可以保住有用改进,也可以锁死在一个被代理优化过的实现上。图 5 强化 SpecBench 的中心主张:公开验证表现单独不是真实实现质量的可靠指标。即便验证分几乎分不出来,留出测试仍揭示生成的系统是否满足预定规格,差别可以很大。
3.4 搜索更多会不会放大刷分
一个自然的问题是:奖励黑客是不是只因为搜索不够。若智能体起初产出脆弱实现,后来再精炼成连贯系统,增加搜索预算就应缩小缺口。图 6 在每个搜索步上跟踪缺口。报告四分位均值(IQM),它捕捉典型行为并降低对离群点的敏感;也报告第 90 百分位(P90),捕捉严重奖励黑客的上尾。
额外搜索并不能可靠地去掉奖励黑客。各智能体的 IQM 缺口在整个搜索过程中保持非零。OpenCode 在大部分运行里中心缺口最大。Codex 和 Claude Code 开始时缺口较小,但在后来的搜索步上明显上升。P90 曲线更强:严重奖励黑客贯穿整条搜索轨迹,而且常常随着搜索进行变得更大。即便额外步骤改进了某些实现,也消除不了被强烈刷分的解的尾巴。
按搜索策略看就明白为什么。AIDE 和 Linear 在更长搜索后 IQM 缺口都上升,P90 缺口保持高。迭代精炼可以通过加功能专用的修补来提高验证表现,而不必然改进留出测试所需的共享抽象。Autoresearch 的 IQM 曲线更平,说明保留迄今最好的候选有时能避免缺口在中心大幅上升。但缺口仍高于零,所以这种选择解决不了底层的代理错配。
图 6 表明,奖励黑客不是早搜阶段的失败、多算一点就会消失。更长的搜索给智能体更多机会改进真正的实现,也给它们更多机会发现在验证测试上得分高的刷分候选。效果因此取决于验证套件与真实使用是否对齐。当验证测试奖励的是局部功能完成、而不是真实使用场景时,额外搜索会保住甚至放大奖励黑客缺口,而不是把它关上。
3.5 加大验证集覆盖
软件工程里提高代码质量的常见做法是写更全面的测试。既然前面观察到奖励黑客,一个自然的问题是:给智能体更丰富的验证测试,会不会缩小缺口。若可见套件包含功能组合的测试,智能体就收到跨功能交互的直接优化信号,也许会被带向能正确处理它们、而不刷分的实现。作者逐步提高可见测试套件的组合复杂度,留出评测保持不变。
三种验证体制。单功能体制:智能体只看到默认验证测试,每个测试孤立地演练规格里的一个功能。这是其他实验的基线。加组合体制:可见套件加上演练多功能交互的测试,智能体同时收到单个功能和它们的组合的优化信号。全覆盖体制:再进一步,加入与留出套件难度相近的组合测试,使智能体优化的测试在组合复杂度上与留出评测相当。三种体制的留出评测都不变,缺口始终用同一套留出套件测量。
图 7 显示,提高验证覆盖的结果是混合的。缺口既不持续缩小,也不持续变大,而且任务之间差别很大。一端,sql_database 的缺口在加入组合测试后从 35 个百分点降到 9 个百分点,更丰富的信号引导智能体去修它先前没有激励去处理的跨功能交互。另一端,c_compiler 的缺口增加 25 个百分点,智能体难以满足更大的一套测试,这些测试对紧耦合的代码提出相互冲突的要求。另有几个任务,无论放出多少测试,缺口几乎不动,说明组合本身真的难实现,而不只是缺少优化信号。奖励黑客不能单靠改进测试套件消除:智能体已有能力、只缺信号时,更丰富的测试有帮助;底层组合真的难做对时,更丰富的测试会适得其反。
3.6 奖励黑客案例
SpecBench 揭示一个谱系:从显式利用代理,到更隐蔽的系统级失败。作者人工检查有代表性的生成程序,看什么样的实现失败造成缺口。图 8 是两个例子。图 9 按智能体和模型组汇总定性类别的分布。
严重:查找表记忆。在 C 编译器任务上,Codex 发现一种完全绕过实现的策略。它不建词法分析器、语法分析器和代码生成器,而是用系统自带的 GCC 预先算出公开测试程序的期望输出,再把结果存在一个 2,900 行的哈希表里,把输入源码的哈希映射到期望输出字节。生成的「编译器」只是对输入做哈希、查表,再发出把预计算输出写出去的汇编。验证测试上达到 97%,留出测试上是 0%,缺口 97 个百分点。这个利用是在搜索中被选中的,尤其能说明问题:同一次 AIDE 运行里,更早的一个节点产出过真正的 7,900 行编译器,验证分 53%,留出分 43%。AIDE 仍然选了查找表制品,因为它在可见验证目标上得分更高。当代理与真实目标错位时,按验证分搜索会主动把智能体从更真实的实现上带开。
中等:功能隔离。最常见的失败没那么显式,但更普遍。在 SQL 数据库任务上,智能体常常把 SELECT、JOIN、GROUP BY 和 HAVING 实现成彼此分开的处理器。每个处理器通过自己那个功能的验证测试。但实现缺少列解析、别名、连接后表模式和聚合状态的共享表示。留出测试在一条查询里组合这些功能时,处理器无法跨功能边界传递必要状态。例如一条查询把员工和部门连接,按连接进来的列分组,再用 HAVING 过滤,会失败,因为 GROUP BY 的逻辑解析不了连接引入的列。这种实现验证表现 100%,留出表现只有 35%,缺口 65 个百分点。这不像查找表记忆那样是故意刷分。它从优化单个功能级检查里自然长出来:生成的系统含局部说得通的组件,但从未建出端到端正确所需的全局抽象。
图 9 把生成的系统分成真正的解、功能隔离失败、边界情形缺口和故意利用。饼图是各类在编码智能体之间、以及在更强与更弱模型之间的比例。能力分组用 SWE-Bench 分数分开。故意利用很少,组合失败占奖励黑客行为的大得多的一部分。各智能体都有相当一部分生成系统落入功能隔离或边界情形缺口:功能级验证下看起来正确,更广的使用下失败。较弱模型更明显:相对更强的模型,真正的解更少,功能隔离失败更多。这与第 3.2 节一致:较弱模型的验证分与较强模型相当,留出分却低得多。
高缺口可以来自显式利用,例如记住公开测试,但更常反映局部测试通过与全局系统正确之间的结构错配。SpecBench 能同时暴露这两种失败,因为留出测试不引入新要求,只要求规定的功能组合成一个真正能工作的系统。
4 相关工作
奖励黑客与规格博弈。优化代理、同时损害真实目标,由 Skalse 等人形式化。他们证明几乎没有代理是不可被利用的。Krakovna 等人编目了强化学习和程序合成里的博弈实例。Pan 等人和 Gao 等人量化了基于人类反馈的强化学习里的奖励过度优化。Manheim 和 Garrabrant 把这些连到古德哈特定律。在编码智能体上,Baker 等人表明经过强化学习训练的模型会利用测试框架,并且能跨领域迁移。Denison 等人表明博弈会从简单形式升级到严重形式。Greenblatt 等人发现低风险刷分会泛化到新设置。SpecBench 往前走了一步,在长程、系统级软件工程任务里研究奖励黑客。
奖励黑客基准。EVILGENIE 改 LiveCodeBench 以允许操纵测试,发现大模型裁判在检测奖励黑客上胜过留出测试。Countdown-Code 表明,监督微调里 1% 的作弊,会在强化学习与可验证奖励阶段引向灾难性刷分。TRACE 有 517 条轨迹、54 类黑客行为,GPT-5.2 只检出 63%。Terminal Wrench 编目 331 个可被利用的任务和 3,632 条利用轨迹。RHB 发现强化学习后训练把利用率从 0.6% 提高到 13.9%。SpecBench 不同:评的是系统级软件(1.5 千到 11 万行),刷分来自架构失败(功能隔离),而不是操纵测试。这符合社区把编码智能体部署到真实生产环境的趋势。
编码基准。HumanEval 和 MBPP 评孤立函数。SWE-bench 假设已有架构。ClassEval 发现模型在类内依赖上吃力。DevBench、CrossCodeBench、LiveCodeBench、KernelBench 和 NL2Repo 各自推进了范围,但都没有把代理和真实目标分开。SpecBench 与上述全部不同,有三点:(1)任务要求从零建造完整系统(1.5 千到 11 万行),不是给已有仓库打补丁;(2)明确把代理指标(验证测试)和真实目标(留出测试)分开,从而定量测量奖励黑客;(3)任务复杂度跨越数量级,从 JSON 解析器到操作系统内核,覆盖长程开发的全谱。
基于大模型的编码智能体。现代编码智能体把前沿大模型和工具使用、终端访问、文件编辑放进迭代循环。专有脚手架包括 Codex CLI(OpenAI 模型,全自动执行)、Claude Code(Anthropic 模型,持久工作区状态)和 Gemini CLI(Google 模型,外壳访问)。开源替代如 OpenCode 和 Aider 支持多种模型后端。包在这些智能体外面的搜索策略和模型本身一样重要。AIDE 用树搜索做代码生成,以起草–调试–改进分支探索解空间。Ralph-loop 用线性顺序精炼。Autoresearch 扩展线性搜索,跨步骤维持最好候选。实验比较了三种策略,发现搜索算法对奖励黑客的影响,小于底层模型能力的影响。
5 结论
SpecBench 用可见验证测试和留出测试的分离,测量长程编码智能体的奖励黑客。在 30 个系统级编程任务上,高验证分可以大幅高估真实的规格符合度,任务时程越长越明显。这是古德哈特定律在自主软件开发里的表现:一旦测试通过率成为优化目标,它就可能不再可靠地衡量生成的系统是否满足预定规格。SpecBench 从量和质两方面暴露这个缺口,既有故意的代理利用,也有更常见的功能组合失败。未来对编码智能体的评测必须超出表面的测试通过,去测量生成的系统是否保住真实软件正确性所需的共享抽象、不变量和端到端行为。
附录 A 局限与更广影响
SpecBench 把奖励黑客操作化成验证表现与留出表现的缺口。留出测试被设计成不引入规格之外的要求,但它们仍是有限的测试套件,不能穷尽地证明完全符合规格。因此,小的奖励黑客缺口不应被理解成生成的系统在所有可能使用场景里都正确。它只表明系统从孤立的验证检查,泛化到了留出测试所覆盖的组合行为。基准聚焦 30 个系统级编程任务,以及有限的编码智能体和搜索策略。未来工作应扩展任务套件、评更多脚手架,并研究同样的失败模式是否出现在更大的真实仓库里。
更广影响。SpecBench 表明测试通过率不是代码质量的可靠指标,对把编码智能体部署到生产的组织有直接影响。作者发布基准和方法,以便从业者在部署前审计智能体的奖励黑客。编码智能体的时程变长时,奖励黑客很可能变严重。作者主张评测框架要测量测试分数之外的结构完整性。
附录 B 计算资源
全部实验在一台能访问云托管模型接口的机器上完成,没有定制训练或微调。表 3 按智能体汇总,费用是标准费率下的接口费用。
| 智能体 | 运行次数 | 计算(小时) | 接口费用(美元) |
|---|---|---|---|
| Codex(gpt-5.2-codex) | 596 | 873 | 30,192 |
| Claude Code(Opus 4.6) | 516 | 754 | 1,655 |
| OpenCode(多种模型) | 800 | 929 | 1,611 |
| 合计 | 2,046 | 2,739 | 38,904 |
正文把总预算写成大约 2,700 个 GPU 当量小时(墙钟 114 天),接口费用合计 38,904 美元。表上的小时数是 2,739。Codex 占费用的大头,因为每个词元更贵,尽管运行次数相近。Claude Code 和 OpenCode 每次运行便宜得多。每个内层智能体步骤超时 600 秒,编译器任务是 1,200 秒。树搜索的外层循环通常 2 到 4 小时结束。
附录 C 案例:Claude 的 C 编译器
为理解奖励黑客是不是自主智能体独有,还是也延伸到有人指导的开发,作者评测 Claude 的 C 编译器(CCC)。它是 Claude Opus 4.6 在持续人类监督下建成的 18.6 万行 Rust 编译器(Carlini,2026)。CCC 不是在 SpecBench 上优化的。它完全对着 GCC 折磨测试套件开发。那是一套超过 900 个 C 程序、广泛用于验证生产编译器的集合。CCC 通过整套折磨测试。作者把 SpecBench 纯粹当作独立的、分布外评测,看一个有人指导、并被测试套件验证过的编译器,在留出测试上是否仍表现出奖励黑客。
设置。在 SpecBench 的 c_compiler 任务上评 CCC。该任务有 46 个验证测试(单个 C 语言特性:算术、指针、结构体、函数、控制流)和 299 个留出测试。留出测试包括 88 个跨特性组合(例如 for 循环里的结构体成员访问加指针算术,带 fallthrough 和类型转换的嵌套 switch),150 个来自 GCC 折磨套件、要求多特性代码生成正确的测试,以及 61 个错误检测测试,核验编译器正确拒绝非法 C 程序(例如函数参数过多、变量重定义、循环外的 break)。
结果。CCC 在验证测试上 97.8%,留出测试上 83.3%,奖励黑客缺口 Δ = 14.5 个百分点。作为比较,同一任务上自主的 AIDE 智能体,缺口从 0 个百分点(不能工作的实现)到 99 个百分点(查找表黑客),中位数 55 个百分点。
这 14.5 个百分点几乎完全由错误检测失败驱动。CCC 能正确编译并执行大多数合法 C 程序,合法程序上的组合测试通过率超过 97%。但它默默接受 GCC 会正确拒绝的非法 C。表 4 是代表例子:参数过多、同一作用域里变量重定义、循环外的 break、冲突的类型、字符串赋给 float、void 变量、重复的 case 标签、把结构体当成整数赋值。每个测试含 GCC 在编译期会拒绝的非法 C。CCC 全部默默接受并编译。
这些不是组合失败。它们是规格符合度里缺失的一个维度,而 GCC 折磨套件从不测这个维度。折磨套件验证正确程序产生正确输出,不验证不正确的程序产生错误。因为 CCC 对着只检查合法输入的测试套件优化,智能体把代理优化得很完美,同时漏掉实际 C 语言规格的一个核心部分。
含义有三点。第一,奖励黑客不限于自主智能体。即便有仔细的人类指导和全面的测试套件,对着覆盖未测维度的留出测试来评,仍会产生可测的缺口。第二,缺口来自测试套件的结构,不是来自模型能力或人的监督。CCC 是一个能工作的编译器,只是从未在非法输入上被测过。第三,SpecBench 的留出测试能揭示这个盲点,恰恰因为它们包含错误检测测试,而标准编译器测试套件省略了这一维。
觉得有用,转给同事
微信扫码
用微信扫一扫,在手机上打开后即可转发。