SpecFirst: Behavioral Specification Elicitation as a First-Class Step in Agent-Based Program Synthesis from Scratch
Yihao Chen, Shi Chang, Feng Lin, Khaled Chawa, Boyuan Chen, Shaowei Wang, Ahmed E. Hassan
cs.SE, cs.CL
2026-07-30
让 Agent 先把可执行二进制当黑盒摸一遍、写成规格文档再开始写码,200 个 ProgramBench 任务上四个模型的测试通过率稳定提升 6.9%–21.3%。
LLM agent 在有现成代码库时干得不错(修 bug、加功能、补全),但「从零造一个程序」是另一回事:给它一份自然语言文档和一个只能跑不能看源码的二进制(execute-only binary),让它复刻出行为一致的程序。ProgramBench 这个 benchmark 把这件事量化了,连 GPT-5.5-high 这种前沿模型,完整通过的实例也不到 1%。
现成的 agent 框架(SWE-agent、OpenHands)把读文档、探二进制、写代码全揉在一个 loop 里,agent 在同一份 turn 预算里自由切换。作者观察到这种揉法有三个系统性毛病:探测不充分(急着写码,边界和报错路径漏掉);规格在长对话里被稀释(上下文一长,压缩机制把当初读到的行为细节删掉);早期误解一路传播(第 4 轮读错的函数签名,后面 140 轮都照着错的重构)。
SpecFirst 的做法是把传统软件工程里的「需求工程」阶段搬过来:在写任何代码之前,先由一个专门的 spec agent 把目标程序的行为摸清楚,落成一份结构化的 SPEC.md,再交给写码 agent。
spec agent 拿到文档和二进制,用自由形式的 bash 黑盒探测(不用结构化 API,因为这样最接近人摸索陌生工具的方式,还能连命令)。它按四类模式深挖:边界探测(空输入、超长字符串、特殊字符)、错误路径(畸形输入、缺参数、冲突 flag,记录每个条件的 stderr 和退出码)、flag 组合测试、输出格式比对。交互式程序用预装的 tmux 虚拟终端发键盘事件。
为防止 agent 走捷径作弊,作者明令禁止两类动作:从 GitHub 或包仓库找回源码(那就等于抄答案)、用反汇编器或跟踪器看二进制内部。一个自动裁判扫命令历史,发现克隆仓库、装包、下源码包、调反汇编器一律判零分。SPEC.md 用六个固定小标题(Overview、Flags、Input & stdin、Output format、Error patterns、Edge cases),只规定记什么、不规定怎么发现,刻意隔离「定规格」和「写代码」两件事。
终止条件按优先级:spec agent 自己声明写完(多数 run 在远未到 1000 轮上限前就自己停了)、1000 轮硬上限、6 小时墙钟。两阶段之间压缩上下文,丢掉 spec agent 的冗长推理,只把 SPEC.md 传给下游。
全部 200 个 ProgramBench 实例,四个模型(Qwen3.5-397B、Qwen3.6-35B、GPT-5.5-high、GPT-5.4-mini),对照基线是同一套 mini-swe-agent 但不加 spec 阶段:
| 模型 | 基线通过率 | SpecFirst | 相对提升 |
| Qwen3.5-397B | 33.66% | 40.84% | +21.3% |
| Qwen3.6-35B | 27.51% | 31.40% | +14.1% |
| GPT-5.5-high | 59.02% | 65.14% | +10.4% |
| GPT-5.4-mini | 39.09% | 41.78% | +6.9% |
全部 p<0.01,GPT-5.5-high 在 150/200 个实例上更好。越难的实例提升越大:Hard 档 GPT-5.5-high 从 30.8% 拉到 40.0%(+29.9%)。
它还把「接近满分」的程序比例顶上去:GPT-5.5-high 上,通过率≥90% 的实例从 5.5% 涨到 16.5%(三倍),≥95% 从 1.5% 涨到 6.5%(四倍多)。
探测覆盖率(用 go build -cover、cargo llvm-cov 这类工具统计二进制有多少行被执行过)SpecFirst 达到 58.3%–60.3%,比基线高 9.4%–18.5%。而且这个覆盖几乎全来自 spec agent,单独的 spec agent(54.9%–58.3%)就压过写码 agent(31.2%–51.3%)。
行为分析里有个反直觉的点:基线 agent 不是因为预算耗尽才停的,0 个实例撞到 1000 轮上限,中位数只用掉 22–177 轮(预算的 2%–18%)。它们是「自以为够了」就停了。有了 SPEC.md,写码 agent 更早开始写、写得更久,最终代码量大 7%–29%。
代价是钱:每实例成本涨 48%–130%,GPT-5.5-high 从 $2.54 涨到 $5.85(+130%,主要是 spec agent 本身的开销)。
这篇给的是个范式提醒,不是新模型。只要你的 agent 任务里有「目标行为藏在某个能跑的东西里、文档又不全」这个特征,就能照搬:把「搞清楚要什么」拆成独立一步,产物落成文件而非记在上下文里。作者自己也说,二进制只是个例子,REST API、容器化服务、编译好的 SDK、远程 CLI,甚至一个能问答的人,对 spec agent 来说都等价。
对做 agent 工程的人,它把三件容易忽视的事点破:长 horizon 任务里行为意图会被上下文压缩吃掉;早期小错会持续放大;agent 早停往往是因为「懂的不够」而非预算不够,所以堆算力救不了。
作者自己列的局限很到位:只测了确定性命令行程序,带 GUI 或复杂进程通信的不一定成立;只在一个 scaffold(SWE-agent)上做的。
最该警惕的是失败分析。占 52% 的最大失败类型是 F4「执行错」:SPEC.md 写对了、写全了,实现照样跑偏。这说明规格阶段的天花板已经摸到了,剩下的缺口得靠更强的执行期推理(对照 SPEC.md 自检、测试驱动修复循环),光把规格做得更全不够。这个结论削弱了「spec 万能」的叙事:提升主要来自那些原本能部分通过的实例,剩下大头是写码 agent 本身的能力问题。
成本翻倍也是个现实约束,GPT-5.5-high 单实例 $5.85,跑满 200 实例乘四模型乘两配置不是小开销。