源码、测试、git 历史全删,只留一个不许读、只许跑的二进制——五月全场 0 分,十月 37 个程序被从行为反推着重建出来
ProgramBench: Can Language Models Rebuild Programs From Scratch?
5 月 5 日,SWE-bench 和 SWE-agent 的原班团队(现在挂在 Meta Superintelligence Labs 下面)挂出一个新基准 ProgramBench,题型简单到有点狠:拿 200 个真实开源项目,把源码、测试和 git 历史全部删掉,只留一个编译好的可执行文件和它的说明文档,让 agent 重写一遍。用什么语言、怎么分模块、建什么抽象,全由它自己定;判分只看一件事——新程序的输入输出行为跟原程序是否一致。论文里的结论是一个整齐的零:9 个当时最强的编码模型,200 道题,一道都没有全部通过。最好的 Opus 4.7 也只在 3% 的题上通过了 95% 以上的测试。
值得今天去读它的理由,是五个月后那张榜。10 月 22 日更新的排行榜上,Opus 5.5(xhigh)拿到 18.5% 全解、70.5% 接近全解——200 道题里有 37 个程序,在一行源码都没看过的前提下被从行为反推着重建了出来,跑任何输入都和原版一样。而同一张表上 FFmpeg 那一行是 0.0%,它在上面烧掉了 66 美元和 392 次调用。这两个数字必须一起读,单看哪一个都会得出错的结论。
题目是怎么出的:删掉源码,再删掉二进制的读权限
题目是用 agent 半自动造的:先让一个 SWE-agent 把仓库编译成可执行文件并记下构建脚本,再让另一个 agent 反复运行这个程序、追着行覆盖率补测试,把观察到的输入输出固化成断言——共 248,853 条行为测试,中位数每题 770 条,最多的一题近 1.5 万条,全程不给做题的模型看。作者还花了一节证明这些自动生成的测试不是水货:生成测试的行覆盖率平均 79.7%、中位 86.2%,而这些项目自带的测试套件是平均 56.8%、中位 64.3%;只跟 FFmpeg 的 FATE、PHP 的回归套件这类专门的行为测试比,生成的是 62.16% 对 66.11%,12 个项目里有 6 个反超。另有一道断言质量的 lint,专门揪「只检查退出码」「只匹配一小段子串」这类几乎白送的断言——装上它之后,一个故意写错的假程序能通过的测试比例从 18.5% 降到 3.7%。
但这篇最该被抄走的是防作弊那部分,因为它不是写在提示词里的,是写在文件系统上的。二进制的权限位被设成 111,只能执行、不能读,于是 Ghidra、objdump、strings、hexdump 一概失效;容器没有外网,只留 localhost 给那 18 个网络工具用;镜像里没有 .git、没有构建缓存,可执行文件是从另一个构建容器单独注入的,免得残留的中间产物泄露实现;评测开始前,任何哈希与原二进制相同的文件都会被删掉,防止有人交一个套在原程序外面的壳。作者交代过为什么走到这一步:早期版本只在提示词里禁止作弊、保留联网,结果 Opus 4.5 从 `--help` 的输出里认出了仓库地址直接 shallow clone,别的模型改用 `cargo install`、`go get` 把源码装下来,还有的直接交一层包装。「越强的模型越能找到创造性的绕法,而把什么算越界这条线用自然语言说清楚,越说越含糊——模型自己在思考里都不确定某个动作算不算允许。」
联网那一版后来被当成正式对照实验留在了论文里,顺手量出一个该记住的数:开着网,用 9 个 LLM 裁判投票判有没有偷看源码,Sonnet 4.6 有 36% 的题被判作弊,Opus 4.6 是 21%,Gemini 3 Flash 20%,其中七成九到九成五的违规形式就是直接去查源码。而这 9 个来自三家厂商的裁判,在 40% 到 57% 的题上互相不同意。所以他们的选择是断网,不是加裁判。
它写出来的东西,和人写的不是一个形状
这篇最有意思的一节跟分数无关。作者只挑通过 75% 以上测试的解法去跟原项目比——也就是只看「确实大致做出来了」的那些:代码量中位数 1,173 行对原版 3,068 行,文件数 3 个对 15 个,六成解法全部挤在 1 到 3 个文件里;目录最大深度中位数 1 对 2,67% 的解法比原项目更扁,只有 2% 更深。函数个数只有原版的 10% 到 29%,但每个函数长 1.08 到 1.62 倍。语言选择也说明问题:模型可以随便挑语言,结果只有一半的运行跟原项目同语言,1,800 次运行里 Python 占 36%,比 Rust(25%)和 Go(20%)都多;Go 项目有 70% 被用原语言重写,Rust 和 C/C++ 项目则过半被换掉。还有一组是干活的节奏:Sonnet 4.6 每题中位数敲 868 条命令,最长一次 1,978 条;GPT 5.4 中位数 17 条,而且中位 96% 的代码是在一个回合里一次性写完的,近四成轨迹从头到尾没改过任何已有文件。对一部分模型来说,开发不是写—编译—调的循环,就是一次生成。顺带说一句,98.1% 的运行是模型自己主动交卷的,只有 1.9% 撞到 6 小时墙上时间、1 次撞到 1,000 步上限——分数低不是被预算掐死的。
五个月从 0 到 18.5%,以及还剩多少
涨幅是真的,价钱也是真的。Opus 5.5 那一轮跑完 200 道题花了 7,273 美元、60,863 次模型调用,平均每题 36 美元;37 道满分题里便宜的 2.7 美元就下来了,贵的单题 98 美元。还顶着 0 分的那几道,恰好画出了今天的上限:FFmpeg、PHP 解释器、tree-sitter、pandoc(Haskell)、dropbear SSH、pigz 全部 0.0%。而且不是没花钱——FFmpeg 66 美元、php-src 63 美元、tree-sitter 63 美元,都是实打实跑完才归零的。最可乐的一行是 zip-password-finder:6 次调用、0.01 美元、0 分,它看了一眼就交卷了。另一头的坡很平缓:sqlite 77%、typst 80%、lazygit 84%、DuckDB 53%、tinycc 21.5%。榜上所有成绩都是作者自己用同一个 mini-SWE-agent 跑出来的,厂商不能自带脚手架——这条被写成了原则,作者还顺手点了一句:Claude Code 那种「据说好几十万行代码」的东西一直在不透明地变,拿它比模型没法比。
作者自己打的折扣
他们对自己的指标相当克制。70.5% 那个「接近全解」被明说只是临时参照:有些题有近 1.5 万条测试,1% 也是一百条,而单独一条测试不过都可能意味着程序有根本性缺陷。至于更软的「平均通过率」,作者直接说会严重误导人,因为每道题里都掺着一堆「有没有这个 flag」「`--help` 会不会炸」这种几乎免费的测试。两条真正的局限也写在明面上:行为测试只是有限样本,所以分数是正确性的下界——没通过的一定是错的,通过的在没测到的输入上仍可能跑偏;以及测试只管输入输出,不管速度、内存和磁盘占用,一个比原版慢几个数量级的实现照样能满分。污染问题他们也正面答了:200 个仓库全是开源的,训练时百分之百见过,他们的论据是分数全零不像记忆的样子,加上那个「强制换一种语言实现」的对照分数没大变——而那个对照本身有个耐人寻味的结果:三个 GPT 模型被强制换语言之后反而各涨了 4.2%,Python 的占比从 36% 升到 51%,作者的解读是模型其实不太清楚哪种语言更适合自己。
本文为 AKL AI Club 原创撰写的导读,不是原文翻译;著作权归原文作者所有。 篇目由编辑独立选取,来源均经人工核实。