打开网易新闻 查看精彩图片

这项由华为加拿大研究院、加拿大女王大学、曼尼托巴大学与康科迪亚大学联合开展的研究,以预印本形式发布于2026年7月29日,论文编号为arXiv:2607.27167,有兴趣深入了解的读者可通过该编号查阅完整原文。

**一个真实存在的尴尬**

软件工程师都清楚,在接手一个全新项目时,最头疼的不是写代码本身,而是搞清楚"这个程序到底要干什么"。遇到文档写得含糊不清,或者某些功能根本没有文档,工程师就必须反复测试、反复确认,才能动笔。

现在,AI编程助手已经能帮我们修复代码错误、补全函数、甚至处理复杂的代码仓库问题。但如果面对的任务是——给你一个陌生程序的简短说明文档,外加一个只能运行、不能看源码的可执行文件,让你从零开始把这个程序重新写出来——那么即便是目前最强大的AI模型,成功率也低得让人咋舌:200个任务里,完整通过测试的不足1%。

这就是本篇论文所要直面的问题。研究团队提出了一个名为SPECFIRST的框架,核心思路来自一个古老的软件工程智慧:在动手写任何代码之前,先把"需求说明书"彻底搞清楚。

**一、现有AI编程助手为何在"白纸作画"时频频翻车**

要理解这个问题,先设想一个场景。你被要求仿制一款陌生的厨房电器,手头只有一张薄薄的产品介绍册,以及一台可以通电运行、但不能打开外壳的实机。你需要把它的全部功能都复现出来——包括各种按键组合、各种异常情况下的报错提示、各种边界情形下的精确输出。

现有的AI编程框架(比如SWE-agent、OpenHands)在这类任务里的做法,就是把"搞明白这台机器怎么工作"和"把它造出来"这两件事混在一起做。AI在同一个工作循环里,一边按按钮测试机器行为,一边写仿制品的设计图,一边动手组装。这听起来似乎挺高效,实际上却造成了三个根深蒂固的问题。

第一个问题是探索不够深入。既然要同时写代码,AI就不可能把测试这台机器的事做得很彻底。那些在说明书里没提到的边角功能——比如同时按下两个特定按键会发生什么,或者输入超长内容时会报什么错——AI往往还没来得及验证,就已经开始动手组装了。结果就是,仿制品的很多功能根本没被原版验证过。

第二个问题是记忆衰退。AI在工作过程中积累的行为知识,是以对话记录的形式保存在"脑子"里的。但随着对话越来越长,早期发现的重要信息会被慢慢"挤出"有效记忆。更糟糕的是,很多框架为了节省计算资源,会压缩历史对话,而这个压缩过程往往会把那些关键的行为发现给丢掉。研究团队发现,在一个具体案例里,AI在第4轮就发现了程序包含十几个功能命名空间,但在后续25轮的工作里,其中6个命名空间的名字再没出现过,最终提交的代码里这6个命名空间全部缺失,导致126个测试用例在代码运行前就注定失败。

第三个问题是早期错误会像滚雪球一样越滚越大。在没有一份稳定参考文档的情况下,如果AI在第5轮对某个功能的理解出了偏差,它会在这个错误理解的基础上继续建造,第10轮、第50轮、第100轮的代码都建立在这个错误地基上。研究团队记录了一个案例:AI正确读取了某函数的参数类型定义,但在第57轮真正实现这个函数时,用了一个完全丢失了类型信息的错误写法。此后140轮里,这个函数被反复重构了5次,但每次都复刻了那个错误写法,因为AI已经没有参照物来校正自己了。最终25个相关测试因类型错误而失败。

**二、一个来自传统软件工程的古老答案**

传统软件工程早就给出了解决方案——需求分析阶段必须独立存在,而且必须先于编码阶段。在正规的软件开发流程里,工程师会在写第一行代码之前,花大量时间与原型系统交互、构建场景、梳理所有功能细节,把这些发现整理成一份完整的需求说明书,然后才开始实现。

SPECFIRST就是把这个思路移植到AI编程智能体上。整个框架分成两个阶段,这两个阶段严格分开,互不干涉。

第一个阶段叫做"规格说明提取"。一个专门的"规格智能体"(Spec Agent)接过任务,它的唯一职责就是彻底弄清楚目标程序的行为。它不写任何代码,只是反复地、系统地运行那个可执行文件,观察各种输入下的输出结果,把所有发现整理成一份结构化的说明文档,也就是SPEC.md文件。

第二个阶段才是"代码合成"。一个普通的编程智能体接过任务,它手里有三样东西:原始说明文档、可执行文件,以及第一阶段产出的SPEC.md。这份规格文件就像一座灯塔,无论编程过程多漫长、对话记录多繁杂,它始终在那里,随时可以查阅。

这个分离的设计直接瓦解了前面提到的三个问题:规格智能体可以心无旁骛地深挖行为细节;规格文件以外部文档形式存储,不受对话压缩影响;编程智能体始终有一个稳固的参照物,早期的正确理解永远不会被遗忘。

**三、规格智能体是怎么"审讯"那个可执行文件的**

规格智能体的工作方式,就像一位侦探面对一个只能通过行为来了解的嫌疑人。它无法打开嫌疑人的大脑,只能不断地提问、观察反应,从蛛丝马迹中还原全貌。

它采用的是自由形式的命令行交互,这样它可以一次性构造复杂的测试场景——比如先创建一个特定格式的输入文件,再运行程序处理它,然后检查输出结果,所有这些步骤可以链式执行。对于那些需要键盘交互的程序,环境里预装了终端模拟工具,让它能够模拟真实的按键操作并捕获屏幕内容。

在探索策略上,研究团队识别出了四类文档最容易"说不清楚"的行为,规格智能体会专门针对这些区域展开系统性测试。首先是边界条件——当输入为空时会发生什么?当输入极长时呢?当输入包含特殊字符时程序如何反应?这些信息文档通常只字不提。其次是错误路径——当参数不对、必填项缺失、参数相互冲突时,程序会在哪个输出通道报错?错误码是多少?这些细节对于正确复现行为至关重要。再次是多参数组合效果——文档可能分别描述了参数A和参数B各自的行为,但同时使用A和B时会发生什么,往往没有说明。最后是输出格式的精确细节——字段之间用什么分隔符?末尾有没有多余空格?数字的格式化方式是什么?这些细节在文字描述里总是模糊不清。

为了确保探索的是真实的程序行为而不是走捷径,系统设置了明确的限制:智能体不允许通过网络搜索或代码托管平台找到原程序的源代码,也不允许使用反汇编工具分析程序内部结构。所有发现必须来自正常使用程序的过程。系统会自动检测命令历史记录,一旦发现违规操作,当前运行立即记零分。

规格智能体的终止条件分三层:它自己判断探索完成时会主动结束;如果迟迟不结束,1000轮操作的步骤上限会强制终止;此外还有6小时的时钟时限作为最后保障。在实际运行中,绝大多数任务都在步骤上限远未到来之前就自行结束了。

产出的SPEC.md文件采用六节式结构:概述、命令行参数、输入与标准输入、输出格式、错误模式、边界情况。这六个章节覆盖了重新实现一个程序所需要知道的全部行为维度,结构足够清晰让编程智能体能直接利用,又足够灵活不会遗漏特殊细节。

**四、用一个真实案例感受SPECFIRST的价值**

论文里用gomplate这个程序作为贯穿始终的示例,非常值得详细了解。gomplate是一个命令行模板渲染工具,它的说明文档(README)只有寥寥数百字,描述了基本用法和几个示例,末尾写着"完整文档请访问官方网站"。然而这个程序实际上扩展了Go语言的模板引擎,提供了横跨十几个功能命名空间的大量内置函数,涵盖数据处理、数学运算、网络操作、加密、字符串处理等方方面面。

在没有规格提取阶段的情况下,AI编程智能体面对这样的程序时,通常只会实现文档里明确提到的那些功能,把大量隐含功能直接忽略。而规格智能体在专门的探索阶段里,会发现并记录全部命名空间的函数列表、调用签名、边界行为和错误模式。论文展示了SPEC.md里的部分内容:完整的函数集合、各命名空间的函数别名、命令行参数的精确语义、以及若干边界情况说明,比如"--in参数与--file参数互斥,同时使用会报错"这类细节。有了这份文件,编程智能体在写代码时就知道需要实现哪些功能、每个功能的精确行为是什么,而不是凭猜测和印象行事。

**五、实验结果:数字背后的故事**

研究团队在ProgramBench这个基准测试的全部200个任务上评估了SPECFIRST,这200个任务涵盖了各种真实世界的命令行程序,包括著名的FFmpeg视频处理工具、SQLite数据库、PHP解释器等。这200个程序的底层实现语言主要是Rust(107个)、Go(46个)和C/C++(45个),整个测试集合包含约25万个测试函数,平均每个任务有770个测试用例,而且这些测试对AI完全保密,AI在工作过程中无法看到测试内容。

评估使用了四个不同的AI模型:两个来自阿里云的开源Qwen3系列(397B参数的大模型和35B参数的中型模型),以及两个OpenAI的模型(能力较强的GPT-5.5-high和较轻量的GPT-5.4-mini)。这四个模型横跨两个不同的技术路线,能力差距大约在一个数量级,用来验证结论的普遍性。

结果非常清晰。在所有四个模型上,SPECFIRST都稳定地超越了不带规格提取阶段的直接合成方式。提升幅度从最小的6.9%(GPT-5.4-mini)到最大的21.3%(Qwen3.5-397B),最高绝对分数达到65.14%(GPT-5.5-high)。所有提升在统计检验下都具有显著性,说明这不是随机波动带来的偶然差异。

从赢/输/平的角度来看,在200个任务里,SPECFIRST在至少59%的任务上优于对照组,能力最强的GPT-5.5-high在75%的任务上都赢了。

不止平均分数的提升,SPECFIRST还把顶端表现拉得更高。以GPT-5.5-high为例,如果把"通过率超过90%"定义为接近完美的实现,SPECFIRST达到这个门槛的任务比例从5.5%跳升到16.5%;如果门槛提高到95%,比例从1.5%跳升到6.5%,增长了四倍多。换句话说,SPECFIRST不仅让所有程序都做得稍微好一点,更重要的是让一部分程序从"差强人意"直接迈入了"几乎完美"。

在不同难度级别上,SPECFIRST的优势同样全面覆盖:简单任务、中等任务、困难任务都有提升。特别值得注意的是,对困难任务的提升往往更显著——GPT-5.5-high在困难任务上的提升幅度达到29.9%,而简单任务只有7.1%。这说明当任务本身的行为复杂性越高、文档说明越不充分时,提前建立完整规格说明的价值越大。

**六、规格智能体到底多彻底地"研究"了那个程序**

研究团队引入了一个叫做"探测覆盖率"的指标来量化这件事。为了测量这个指标,他们给测试集里的每个程序都装上了代码覆盖率监控工具(针对不同语言分别使用对应工具),记录每次运行时实际执行了程序里哪些代码行。把所有探测过程中触达过的代码行加起来,除以程序总代码行数,就得到了探测覆盖率——这个数字越高,说明AI对程序行为的理解越全面。

对照组(直接合成,无规格提取)的探测覆盖率在49%到55%之间,视模型而定。SPECFIRST将这个数字提升到了58%到60%,提升幅度在9.4%到18.5%之间,且全部具有统计显著性。

更有意思的分析在于:SPECFIRST里有两个智能体,规格智能体和编程智能体都会运行程序。研究团队把两者各自的覆盖率单独统计了出来。结论是,规格智能体单独达到的覆盖率(约55%~58%)始终高于编程智能体单独达到的覆盖率(31%~51%),把两者的覆盖合并起来,比规格智能体单独的覆盖只多出一点点。这说明覆盖率的提升几乎完全来自专门的探测阶段,而不是编码过程中顺带测试带来的副产品。

**七、规格说明改变了编程智能体的工作方式**

研究团队还做了一项行为分析:在整个编程过程中,每隔一个工作步骤就记录一次代码仓库的规模(代码行数),然后把时间轴归一化,观察代码是如何随时间增长的。

对照组的曲线有一个典型特征:在工作过程的前半段,代码几乎没有增长,AI一直在忙着测试和理解程序行为;到了后半段才开始快速写代码,但此时留给调试和完善的余地已经不多了,经常出现"一次性倾倒"大量代码的现象,随后就戛然而止。

SPECFIRST的曲线则完全不同:代码从工作开始不久就稳定增长,增长曲线更早、更平缓、持续更长,最终停止时代码仓库也更大——比对照组普遍大7%到29%。

研究团队还在具体案例层面做了对比。以一个叫做"age"的程序为例,对照组的AI花了大量步骤在测试和理解行为上,最后试图一次性写出完整的841行代码,不出意外地因为调试时间不够而失败。SPECFIRST里的编程智能体由于已经有了SPEC.md,只花了2到9步建立工作上下文,就立刻转入了持续的代码建设阶段。

还有一个反直觉的发现值得专门说明:对照组的AI之所以表现不好,并不是因为工作步骤不够用。研究团队统计了对照组各任务实际用了多少步骤——结果是没有一个任务用到了1000步的上限,所有任务都是AI自己主动停止的,中位数只用了22到177步,只占可用预算的2%到18%。也就是说,问题不在于"给的时间不够",而在于AI在步骤远未用完时就已经产生了"我理解得差不多了,可以提交了"的错误感知,然后自行结束。单纯给AI更多计算预算并不会解决这个问题,因为它们自己会停。SPECFIRST解决的是"在开始写代码时就掌握足够完整的行为知识"这个本质问题。

**八、失败案例揭示了下一步的方向**

研究团队随机抽取了50个失败案例,对照着测试失败信息、SPEC.md内容和对应代码片段,逐一分析失败原因,识别出了五种失败模式。

最常见的失败(占52%)是"规格正确但实现出错":SPEC.md对这个功能的描述是准确完整的,但编程智能体没有正确实现。这类失败的具体表现包括:某个子命令在帮助文档里存在但程序分发逻辑里没有处理、某个参数被解析了但效果没有被应用、错误输出的格式与SPEC.md的描述自相矛盾。这是最主要的失败类型,意味着提升编程智能体的代码实现能力是当前最重要的改进方向。

第二常见的是"规格描述不够精确"(占26%):SPEC.md记录了相关功能,但描述不够细致,让编程智能体不得不猜测。比如,SPEC.md说"非法输入会报错",但没有指明错误码是1还是2,也没有说错误信息是输出到标准错误还是标准输出,于是编程智能体猜错了,而测试的期望是明确的。

"规格遗漏"(占10%)表示规格智能体根本没有发现这个功能的存在,通常是一些隐藏较深的CLI参数、子命令或错误路径。"规格描述错误"(占4%)是SPEC.md记录的行为与程序实际行为相反,如把应该输出到标准错误的内容记成了标准输出。最后8%是环境依赖错误,比如测试期望的错误信息里包含了特定的DNS服务器地址,这类问题属于测试基础设施的噪声,与AI能力无关。

**九、规格文件的格式也有讲究**

论文还专门测试了SPEC.md的不同格式是否会影响最终效果,在50个任务上用GPT-5.4-mini进行了对比。

测试了三种格式。第一种是完全自由格式,智能体自己决定如何组织内容,没有任何模板约束。第二种是OpenSpec格式,这是一个来自软件工程领域的正式规格书写标准,要求用"必须/应当/可以"这样的措辞标注每条需求,并为每条需求提供"给定/当/那么"格式的场景示例,非常正式和结构化。第三种是研究团队使用的六节式格式,介于两者之间:有固定的章节标题提供基本结构,但章节内的书写方式完全自由。

结果是三种格式都比没有规格文件的直接合成更好,无规格的基准得分55.9%,自由格式60.7%,OpenSpec格式61.7%,六节式格式62.6%。六节式格式效果最好,研究团队的解释是:纯自由格式可能导致智能体遗漏某些重要维度;而OpenSpec格式虽然更精确,但它过于正式的结构可能反而压制了一些难以套入模板的行为细节。六节式格式的"有框架但不死板"恰好处在最有效的区间。

**十、代价:SPECFIRST要多花多少钱**

引入额外的规格提取阶段意味着额外的计算成本。研究团队统计了每个任务的平均花费,SPECFIRST的总成本比直接合成高出48%到130%。

具体来说,规格智能体本身的花费在每个任务0.25美元(GPT-5.4-mini)到3.16美元(GPT-5.5-high)之间。规格智能体增加的成本拉高了总花费,但对于GPT-5.4-mini,编程智能体的花费反而下降了17%——说明有了清晰规格后,编程过程里那些反复试探的开销被节省了下来。GPT-5.5-high的总成本增加了130%,主要来自其规格智能体本身的高单价。

研究团队的观点是,这部分额外成本是"做了更多有价值的工作"带来的,而不是做了重复低效的工作。更宽的行为覆盖和更大的代码实现都是实质性产出,不是浪费。

说到底,SPECFIRST的核心发现可以用一句话来概括:在动手写代码之前,先把"这个程序到底要干什么"彻底搞清楚,是一件比想象中更有价值的事情。

这个道理对人类程序员来说早就是常识,但现有的AI编程框架却在这件事上存在系统性的短板——它们总是急着开始写代码,在理解还很不充分的时候就仓皇上阵,结果往往是边写边猜、越写越偏。SPECFIRST通过把"弄清楚"和"写出来"这两个阶段强制分开,让每个阶段都能全力以赴,最终得到了稳定且全面的提升。

当然,从实验结果来看,即便加上了规格提取阶段,AI程序员的整体成功率依然有很大的提升空间——最强模型的平均通过率才65%,距离"完美复现"还很遥远。占比52%的最主要失败类型是"知道应该怎么做但就是没做对",这说明接下来的改进重点在于提升编程智能体把规格转化为正确代码的能力。研究团队也指出,让规格智能体发现那些更深层隐藏的边界行为,是另一个值得持续探索的方向。

这项研究给我们留下一个有意思的思考:如果我们用这个框架来评估人类程序员,那些在需求分析阶段花费最多精力的程序员,最终写出的代码是不是也更少出错?传统软件工程积累的那些"最佳实践",或许在AI编程时代同样适用,甚至适用得更彻底。

感兴趣的读者可以通过arXiv:2607.27167查阅完整论文,参与这个在AI编程领域仍然充满开放问题的探索。

Q&A

Q1:SPECFIRST框架和普通AI编程助手的本质区别是什么?

A:普通AI编程助手会把"搞清楚程序行为"和"写代码"混在同一个循环里交替进行,导致理解不深入、知识容易遗忘、早期错误越滚越大。SPECFIRST强制把这两件事分成独立的两个阶段:第一阶段专门由规格智能体彻底探测程序行为并写成文档,第二阶段编程智能体拿着这份文档再去写代码。就像专业软件团队在编码前先做需求分析一样,两件事分开做,每件都能做得更彻底。

Q2:ProgramBench测试集为什么被认为特别难?

A:ProgramBench要求AI根据一份简短的说明文档和一个只能运行不能看内部的可执行文件,从零开始重写出功能完全一致的程序。难点在于文档永远写不全——那些边界情况、精确错误格式、参数组合效果都不会被文档记录,AI必须通过反复运行程序来自己发现。测试集包含200个真实程序、近25万个测试用例,测试对AI完全保密,目前最强的AI模型在无规格提取的情况下只能让不足1%的程序完整通过。

Q3:SPECFIRST产出的SPEC.md文件具体包含哪些内容?

A:SPEC.md采用六个固定章节的结构:概述(程序是干什么的)、命令行参数(各参数的精确语义和组合效果)、输入与标准输入(接受什么格式的输入)、输出格式(精确的字段顺序、分隔符、空白字符规则)、错误模式(各种错误情况下的错误码和错误信息输出位置)、边界情况(空输入、极端值、参数冲突等特殊情形)。这六个章节覆盖了重新实现一个程序所需要了解的全部行为维度。