FeatureArc: 在 不断 演进 的 功能 上 评 测 编码 智能 体
73 个从仓库历史挖出的多阶段任务上,十个编码智能体的汇总成功率从第一阶段的 62.7% 降到整项功能的 28.5%。失败之后,约 95% 的后续阶段没有发现更早的错误。

本文目录
FeatureArc:在不断演进的功能上评测编码智能体
作者:Yunlong Wang 1、Alyssa Wu 1、Cuiyun Gao 2、Jia Feng 1、Songyuanyi Lu 1、Zhichao Hu 1
单位:1 腾讯混元团队;2 香港中文大学。电子邮件:{joeyolwang, alyssawwu, plusfeng, alinasyylu, frankiehu}@tencent.com,cygao@cse.cuhk.edu.hk。通信作者:Alyssa Wu 与 Cuiyun Gao。原文用星号标出这两位通信作者。六位作者依次是 Yunlong Wang、Alyssa Wu、Cuiyun Gao、Jia Feng、Songyuanyi Lu 与 Zhichao Hu。其中 Yunlong Wang、Alyssa Wu、Jia Feng、Songyuanyi Lu 与 Zhichao Hu 的单位编号为 1,即腾讯混元团队;Cuiyun Gao 的单位编号为 2,即香港中文大学。
摘要
一项软件功能通常会随时间演进:新的用例和需求到来时,开发者会扩展它的第一版,而每一次扩展都建立在更早写好的代码之上。大多数功能基准在一份固定代码库上评测单次请求。功能演进要求在智能体自己更早的代码上评测相继的扩展,并检查该功能是否仍然正确。我们提出 FeatureArc,用来在不断演进的功能上评测编码智能体,并给出一条从其仓库历史构造任务的流水线。该基准把同一功能相继阶段之间的依赖、明确的需求与接口契约,以及四种编程语言上的可执行检查结合在一起。流水线在每个阶段前后的参考代码上,验证针对新行为的失败转通过(fail-to-pass,F2P)测试,以及针对既有行为的通过转通过(pass-to-pass,P2P)测试。我们在 73 个经过人工复核、含 2 到 10 个阶段的任务上评测了 10 个编码智能体。每个智能体在一个持续的会话和工作区里工作,没有外部测试反馈,也不回滚。评测揭示了第一阶段成功与整项功能成功之间的差距:汇总成功率从第一阶段的 62.7% 降到在最终代码上测试整项功能时的 28.5%。轨迹分析把继承来的缺陷识别为一种常见失败机制,出现在 72.9% 的失败后续阶段中。这些更早的错误常常不被发现:在一次失败之后的阶段里,智能体大约有 95% 的时候没有注意到更早的错误,它们的自测也很少回看更早的阶段。因此,在阶段之间没有人工检查的情况下自主演进一项功能,对当前的编码智能体仍然是一项实质性挑战。在腾讯,这条流水线把内部评测扩展到这一设定,并指导 Hunyuan 的开发。Hunyuan 是腾讯的大语言模型家族。
关键词:编码智能体、基准、软件演进、功能开发、软件仓库挖掘
I 引言
图 1:L4 功能实现。
软件功能会演进,因为开发者扩展已有代码以满足新需求 [1, 2]。我们把这种演进描述为一系列阶段,从最初实现到相继扩展。编码智能体现在可以自主检查仓库、编辑代码并运行测试 [3, 4]。在要求智能体解决单个 GitHub 议题的 SWE-bench 上 [5],发布时最好的模型在 2023 年只解决了 1.96%;智能体现在能解决其 500 个议题、经人工核验的 Verified 子集中的 70% 以上 [6, 7]。在 SWE-chat 收集的 13,000 个真实会话里,有 37% 的会话中,智能体写出了几乎全部被提交的代码 [8]。开发者也开始把一整项功能的相继扩展委托出去,中间不再插入检查。于是每一次扩展都继承智能体更早的代码,包括它尚未注意到的错误。我们问:一个能把单条需求实现得很好的智能体,在需求演进时扩展自己的代码,能否让这项功能保持正确?
表 I:功能基准的比较。
| 基准 | 在自己的代码上迭代 | 单一功能 | 仓库历史 | 自动构造 | 多种语言 |
|---|---|---|---|---|---|
| 每个任务一次功能请求 | |||||
| FEA-Bench [9] | ✗ | ✗ | ✓ | ✓ | ✗ |
| FeatBench [10] | ✗ | ✗ | ✓ | ✓ | ✗ |
| FeatureBench [11] | ✗ | ✗ | $\triangle$ | ✓ | ✗ |
| 每个任务若干阶段 | |||||
| CCBench [12] | ✗ | ✓ | $\triangle$ | ✗ | ✓ |
| SWE-STEPS [13] | ✓ | ✗ | ✓ | ✓ | ✗ |
| SlopCodeBench [14] | ✓ | $\triangle$ | ✗ | ✗ | ✗ |
| EvoCode-Bench [15] | ✓ | $\triangle$ | ✗ | ✗ | ✓ |
| EvoWeb [16] | ✓ | $\triangle$ | ✗ | ✓ | ✗ |
| FeatureArc(本文) | ✓ | ✓ | ✓ | ✓ | ✓ |
评测这种能力,要求智能体在维持一项功能的同时检查自己更早的工作。阶段之间的用户反馈决定哪些实现与验证责任仍留在智能体身上。类似于驾驶自动化的等级 [17] 和人工智能智能体自主性的等级 [18],我们为功能实现区分四级委托:在 L1,用户告诉智能体如何修复一个失败的阶段;在 L2,用户指出失败的行为;在 L3,用户只说一个阶段是否通过;在 L4,用户只给出下一份规格说明,对更早的阶段什么都不说(图 1)。L4 功能实现要求智能体自己找到更早的错误,而在 L1–L3,由用户报告失败的阶段。腾讯内部的多阶段功能评测只覆盖了 L1–L3,因此对持续开发做 L4 评测有实际需要。早先一次构造 L4 任务的尝试,是把单次功能请求拆成阶段,得到的依赖很弱:所得阶段大体上像彼此独立的单阶段任务,限制了它们测试相继扩展的能力。因此 L4 需要在构造上就互相依赖的阶段。我们从仓库历史中恢复这些阶段,以捕捉开发者实际上如何扩展一项功能来满足新需求,每一次扩展都建立在更早的实现之上。
现有功能基准覆盖了这一设定的部分,但在 L4 上从仓库历史评测同一功能的演进仍留有缺口。如表 I 所示,大多数基准在一个固定的起始状态上提出单次功能请求 [9, 10, 11],于是没有后续阶段可供一个错误去影响。有若干阶段的基准评测的是不同的开发设定:CCBench [12] 把所有阶段放在一条指令里;SWE-STEPS [13] 在每个阶段之后返回测试反馈,并把不必属于同一功能的拉取请求串起来;SlopCodeBench [14]、EvoCode-Bench [15] 和 EvoWeb [16] 使用手写的阶段,或从相似产品生成的阶段,它们并不跟随一项功能在仓库里实际生长的方式。在表 I 所比较的基准中,FeatureArc 是唯一把历史上的同一功能依赖、顺序请求,以及在智能体自己的代码上继续评测且不给隐藏测试反馈这几件事结合起来的基准。勾、三角和叉分别表示完全支持、部分支持和没有支持;自动构造覆盖任务、环境和测试,允许人工复核。
我们用 FeatureArc 和一条构造其任务的自动流水线来填补这一缺口。该基准有三个互补的性质。第一,历史上的同一功能依赖要求智能体扩展一份已有实现:流水线从仓库历史中恢复一个用户可见功能的相继阶段。第二,以需求为依据的验证使每一次扩展都明确且可测:一份需求文档和一份接口契约规定期望行为,而失败转通过(F2P)测试和通过转通过(P2P)回归测试 [19] 对照参考状态检查新行为和既有行为。最后一次检查在智能体得到的代码上评测完整功能。第三,多样的仓库语境让智能体在 Python、TypeScript、Rust 和 Go 中、跨越七个应用领域接触功能演进。我们通过分层抽样、用多个模型的轨迹筛查任务缺陷,以及人工检查来选择评测集(第 III-F 节)。在 L4,每个智能体在一个持续的会话和工作区里按顺序收到规格说明;隐藏测试结果被扣下,智能体在每个阶段之后都带着自己的代码继续。
结果暴露了被评测的编码智能体在演进功能任务上的三个弱点。第一,整项功能的成功不到第一阶段成功的一半:汇总成功率从第一阶段的 62.7% 降到整项功能上的 28.5%,即使最强的智能体 Claude Opus 5.5 [20] 也只完成 49.3% 的功能,尽管它通过了 83.6% 的第一阶段。第二,继承来的错误常常持续存在:一个阶段失败之后,智能体在下一阶段的 F2P 测试上只有 22.6% 的情况通过,而在通过的阶段之后这一比例是 70.2%;相比之下,破坏更早行为只影响 3.3% 的、其新行为能够工作的功能。第三,智能体很少注意到自己更早的失败:在跟随一个失败阶段的阶段里,有 94.9% 智能体从未注意到该错误。因此,在阶段之间没有人工检查的情况下演进一项功能,对当前的编码智能体仍然是一项实质性挑战。
在腾讯,我们用这条流水线把 L4 功能实现加入内部评测,并在外部智能体之外评测 Hunyuan 4 Preview,它是 Hunyuan 家族中一个尚未发布的模型 [21]。评测把实现一条新请求,与发现它所依赖的代码中的错误区分开来。这一区分给混元团队提供了第一阶段分数揭示不了的失败的具体证据,如第 VI 节所讨论。
我们的贡献是:
- 一个基准和一条构造流水线,它们把历史上的同一功能依赖、以需求为依据的验证,以及多样的仓库语境结合起来,用于 L4 功能实现。
- 一项在 FeatureArc 上对编码智能体的实证研究,它量化第一阶段成功与整项功能成功之间的差距,并记录继承错误的持续存在,以及智能体自我验证的局限。
- 腾讯的一项工业应用:把内部评测扩展到 L4,并通过功能级结果和轨迹证据诊断 Hunyuan 的开发需要。
II 任务表述
我们把一个任务定义为一系列阶段,并说明在第 I 节引入的 L4 设定下如何评测智能体。
II-A 任务定义
一个任务跟随一个用户可见的功能,穿过同一仓库中有序的 $n$ 个阶段 $m_{0},\dots,m_{n-1}$。第一阶段实现初始版本,其后每个阶段扩展同一功能。我们把这一序列称为同一功能链。
在图 1 所示的任务里,第一阶段 $m_{0}$ 加入 app.run(),它启动一次运行并返回其任务标识。第二阶段 $m_{1}$ 加入 app.runAndWait(),它调用 app.run() 并等待完成。第三阶段 $m_{2}$ 把该功能扩展为接受文件输入,并加入 files.upload()。每个阶段都建立在智能体对先前需求的实现之上。
任务提供一个初始仓库状态 $S_{0}$、一个带有所需依赖的容器镜像,以及每个阶段的一份规格说明。每份规格说明有两部分:一份描述所请求行为和验收标准的需求文档,以及一份写明使用该行为所需的名称、签名、常量和错误消息的接口契约。智能体一次收到一份规格说明,并在自己更早的工作之上实现每一条新请求。
隐藏的失败转通过(F2P)测试检查一个阶段所请求的新行为,通过转通过(P2P)测试检查既有行为 [19]。另一对链级测试套件在最终工作区上检查完整功能。第 III 节说明我们如何恢复这些阶段、撰写其规格说明,并对照参考代码验证这些测试。
II-B 评测过程
图 2:L4 评测过程。
图 2 展示 L4 评测过程。一个会话和一个工作区在整个任务中持续存在。智能体可以检查自己的代码并运行自己的检查;参考补丁、隐藏测试套件和未来的规格说明保持私有。当智能体完成一个阶段时,一次称为阶段关卡的隐藏验收检查运行其 F2P 和 P2P 套件。阶段是实现请求;关卡检查其结果,两套测试都必须通过,该阶段才算通过。失败的阶段既不回滚,也不报告给智能体:下一阶段从智能体刚刚产出的代码开始。在 $m_{n-1}$ 之后,链关卡在最终工作区上运行链级 F2P 和 P2P 套件,以检查完整功能。
III 基准构建
构造流水线把仓库历史变成这样的任务:要求智能体在自己的代码上扩展同一功能。可靠的评测需要互相依赖的阶段、明确的行为规格,以及能把所请求的新行为与既有行为区分开的可执行测试。如图 3 所示,流水线用五步处理这些要求:仓库收集与历史分析、演进链挖掘、参考状态构造、环境与测试验证,以及规格说明生成。然后我们选择并人工复核评测集。
图 3:基准构建工作流。
III-A 步骤 1:仓库收集与历史分析
要恢复有意义的功能演进,我们需要含有相继扩展的历史,以及能够支持可执行评测的仓库。如图 3 的步骤 1 所示,我们选择至少有 30 颗星、许可宽松、能离线在 Linux 上构建,并且代码主要以 Python、TypeScript、Rust 或 Go 写成的仓库。星数阈值提供社区兴趣的一个基本指示;其他条件支持再分发和可重复执行。仓库历史提供用来构造并验证每个任务的功能变更和参考实现。评测期间,智能体扩展自己更早的代码,因此每一条新需求都必须对照其先前编辑所产生的工作区来实现。
穿过文件重命名和模块移动去跟随一项功能,需要文件名以外的证据:对共享文件的更改暗示一种关系 [22],我们通过模块结构和相关提交的意图来考察它。因此我们从起始检查点的导入建立一张模块图,并在按顺序处理提交时更新它。图 3 中的拓扑智能体和语义智能体检查互补的证据:前者检查模块结构,后者识别提交意图和相关测试。它们的输出提供下一步所用的历史关系。
III-B 步骤 2:演进链挖掘
要评测一项功能的演进,我们必须把它的相继扩展,与时间上邻近或发生在同一批文件里的无关更改区分开。我们在一张证据图中表示候选关系,如图 3 的步骤 2 所示。节点是提交或小的提交组,边通过共享的代码元素、文件历史、引用或导入把更改连接起来。这种表示允许流水线即使在相关更改之间发生了其他开发时,仍能跟随相关更改。
图中所示的四种搜索探索这张图的互补部分:全局束搜索跟随有希望的路径,锚点引导搜索从已识别的功能更改出发,端点桥接连接相关端点,社区引导搜索考察相关更改的组。一个大语言模型复核智能体对照源代码、测试和差异检查所提出的链。只有当每个阶段都以可观察、可测试的行为扩展同一用户可见功能时,一条链才被保留。复核也会补上遗漏的扩展、去掉无关工作,并调整阶段边界。输出是用来构造任务的、挖掘得到的同一功能链。
III-C 步骤 3:参考状态构造
为验证每个阶段的贡献,我们构造成对的参考状态,它们相差所选的那一次扩展,同时保留周围的仓库语境。如图 3 的步骤 3 所示,我们按历史文件补丁在该功能、其测试和必要依赖中的角色来标注它们,并把所选更改分配到阶段补丁。我们从最终检查点去掉这些补丁,得到初始状态 $S_{0}$,再按顺序重新应用它们,得到 $S_{1},\dots,S_{n}$。未被选中的更改作为共享语境保留。这些成对状态让下一步可以直接测试每个阶段的贡献。
III-D 步骤 4:环境与测试验证
要把一次失败归因于所请求的行为,任务必须一致地运行,其检查必须能区分扩展前后的代码。图 3 步骤 4 中的环境智能体为这条链准备一个离线容器镜像,并修复它,直到参考状态能够构建、其测试能够被发现。测试抽取智能体把历史测试连同所需的夹具和辅助程序打包,并按它们在成对状态上观察到的结果选择测试。F2P 测试必须在该阶段之前失败、之后通过;P2P 测试必须在两个状态上都通过。链级套件在 $S_{0}$ 与 $S_{n}$ 之间接受同样的验证,使最终检查能够覆盖跨所有阶段的完整功能。
III-E 步骤 5:规格说明生成
为了让期望行为可以接触到、又不揭示其实现,每个阶段需要一份行为描述和一份明确的接口契约。如图 3 的步骤 5 所示,一个规格说明智能体使用阶段补丁和 F2P 测试来撰写需求文档和契约。前者陈述行为和验收标准;后者规定使用该行为所需的名称、签名、常量和错误消息。发布之前,流水线去掉已登记的、由智能体生成的文档,并把被识别为会揭示后续实现的文档恢复到功能出现之前的状态。图中的两组输出反映这一分离:智能体收到初始代码、顺序规格说明和容器镜像,而参考代码、隐藏测试和验证记录保持私有。
III-F 评测集筛选
多阶段评测需要反复的模型调用,以及每项功能内部的顺序执行,每一个被评测的智能体都会产生费用。鉴于这些经济约束,我们通过三步,从构造出的任务池中选择一个高质量子集作为评测集。
分层抽样。为覆盖不同语言和演进长度,我们抽样 100 个候选任务,每种语言 25 个,按链长度分层。这使候选集中既保留短的、也保留更长的功能演进链。一次扫描找出规格说明中缺少、却被测试使用的标识符,从而标出执行前需要修订的描述和契约。
任务缺陷排除。为识别任务缺陷,我们用若干模型运行候选任务并检查其执行轨迹。我们对照规格说明、隐藏测试和参考实现检查这些轨迹,以区分任务缺陷和智能体错误。这次筛查排除了七个任务:五个其链级套件要求了未说明的行为,一个测试套件有缺陷,一个仓库钩子拦截了提示。
人工检查。为确保所选任务测量的是预期的功能演进设定,我们人工检查规格说明质量、接口契约与隐藏测试之间的对齐,以及相继阶段是否扩展同一功能。所得的 FeatureArc 评测集包含来自 53 个仓库的 73 个任务、263 个阶段。所有报告的智能体比较都使用这同一集合。
III-G 基准特征
图 4:FeatureArc 的特征。
FeatureArc 通过三个互补的性质支持对演进功能实现的评测。图 4 给出支持性的数据集特征。
历史上的同一功能依赖。后续阶段要求智能体回看更早的工作,使继承来的实现决定成为任务的一部分。每个任务都通过共享文件或已验证的调用依赖连接相继阶段。如图 4d 所示,一个后续阶段平均有 54.3% 的被改文件与更早阶段共享;跨任务的中位数是 59.1%。任务跨越 2 到 10 个阶段,平均 3.60 个,既提供短的扩展,也提供更长的依赖开发序列。
以需求为依据的验证。该基准把明确的阶段规格说明,与经过验证的阶段级和整项功能检查结合起来。这些任务涉及仓库范围内的大量更改:图 4c 显示每个阶段参考更改的中位数为 426 行源代码和 416 行测试,须线在第 5 和第 95 百分位;图 4d 显示平均 7.71 个被改的源文件。整项功能更改的中位数是 1,453 行源代码。在这一规模的实现更改上,成对状态验证和人工检查确立了可执行评测与阶段规格说明中所请求行为之间的对齐。
多样的仓库语境。任务覆盖四种语言和七个应用领域,领域按仓库手工指定,使同一评测过程能够考察不同的开发设定。图 4b 显示任务分布在 Python、Go、TypeScript 和 Rust 上(分别为 21、20、18 和 14 个任务)。图 4a 包括人工智能智能体与大语言模型工具,以及云与基础设施,分别为 17 和 14 个任务。共享的任务结构支持在不同的代码、接口和应用需要上评测:每个智能体必须按任务扩展一项功能。
IV 实验设置
我们用第 II-B 节的 L4 过程,在 FeatureArc 上评测编码智能体。我们的研究处理三个互补的问题:
- RQ1:智能体完成演进功能的可靠程度如何?阶段关卡和链关卡度量实现成功、失败位置,以及任务长度的影响。
- RQ2:更早的错误如何影响后续阶段?条件通过率和继承标签把携带向前的缺陷,与后续编辑引入的回归区分开。
- RQ3:智能体检测并验证自己错误的效果如何?察觉标签、自测结果和规格说明检查考察智能体是否认出失败,并是否得到正确性的可靠证据。
IV-A 被评测的智能体
为跨提供方考察这一设定,我们评测建立在 Claude Opus 5.5 [20]、GPT-6 Astra [23]、Hunyuan 4 Preview [21]、GLM-5.3 [24]、Grok 4.7 [25]、Qwen 3.8 [26]、Gemini 3.8 Flash [27]、Doubao 2.1 Pro [28]、Kimi K3 [29] 和 DeepSeek V4 Pro [30] 之上的智能体。Hunyuan 4 Preview 是本研究中评测的内部预发布模型;引文描述的是其模型家族。比较的单位是配置好的编码智能体,包括其模型和脚手架,而不是脱离脚手架的裸模型分数。本次一共评测十个这样的智能体,用来考察不同提供方在同一设定下的表现。
IV-B 轨迹分析
关卡结果定位失败,轨迹则显示智能体检查了什么、以及它是否认出一个更早的错误。我们用轨迹分析为 RQ2 和 RQ3 连接这些观察。过程标签描述规格说明、轨迹和智能体代码中可见的行为;诊断标签额外使用隐藏测试证据来解释所观察到的失败。
我们用下列标签描述验证行为并诊断失败的阶段。
- 最终检查记录智能体所运行的最强检查:相关测试、无关测试、一次手工行为检查、仅构建、没有检查,或没有活动。最后测试结果记录最后一条测试命令是通过、失败、没有收集到测试、没有运行,还是结果不清楚。
- 标准对准记录检查是否演练了全部验收标准、部分标准、仅实现细节,或没有行为。它度量检查演练了什么;它们的期望结果仍可能是错的。
- 停止原因记录智能体是在一次成功的检查之后结束、未经验证就结束、把一次失败打发掉、忽略一次失败,还是没有做工作。打发证据记录一项声称失败无关或早已存在的说法,是由基线测试支持、未经验证,还是被轨迹所反驳。
- 先前察觉记录智能体是错过了一次更早的失败、注意到了但没有修复,还是修复了它。它适用于跟随一个失败阶段的阶段。
- 继承记录一个失败的后续阶段是完全、部分,还是完全不是由一个更早的缺陷引起,并记下引入该缺陷的阶段。
- F2P 原因:细记录一次 F2P 失败的具体原因,例如缺少符号、签名错误、逻辑不正确或漏掉一种情况。F2P 原因:分组把这些标签合并为接口、其他构建和行为失败,同时把超时、与求解器无关的失败和未知原因分开保留。
IV-C 实现细节
任务构造与复核。流水线把图 3 中的五步实现为职责分开的智能体,分别负责历史复核、功能链复核、补丁分类、环境准备、测试抽取和规格说明撰写。已发布的任务清单记录每一步所用的模型和产物。步骤 1–3 我们使用 GPT-5.5 [31],步骤 4 使用 DeepSeek V4.1 Flash [32],步骤 5 使用 Claude Sonnet 5 [33]。一个任务能否被接受,取决于可执行的参考状态验证和对任务材料的复核。
智能体执行与可比性。九个被评测的智能体在 Claude Code 中运行。
脚注 1:Claude Code:https://code.claude.com/docs/en/overview。
而 GPT-6 Astra 使用原生的 Codex CLI。
脚注 2:Codex CLI:https://github.com/openai/codex。
对 GPT-6 Astra,Codex 保留原生的工具调用表示和会话恢复机制,避免了通过 Claude Code 运行它所需要的额外适配。每个脚手架在下一阶段恢复同一会话。每次集成都保留其脚手架对工具调用和对话状态的处理,以及提供方特定的上下文与推理控制。每个智能体都在相同的任务条件下评测:初始代码、阶段规格说明、隐藏验收检查,以及四小时的阶段预算,阶段之间没有外部失败反馈,也不回滚。我们的主要比较让每个智能体从第一阶段走到整项功能,并比较它在通过的阶段与失败的阶段之后的行为,其配置保持固定。跨智能体的分数反映模型与脚手架的联合表现,两者的贡献在这些比较中是耦合的。任务在预装依赖的离线容器中执行,隐藏评分与智能体的工作区分开运行。
轨迹标注。Hunyuan 4 Preview、DeepSeek V4.1 Flash 和 GLM-5.3 Flash [24] 使用一份共享的编码手册独立标注轨迹,遵循以大语言模型为评判的做法 [34]。它们在接触关卡日志、隐藏测试和参考补丁以作诊断之前先指定过程标签,并为每个标签引用轨迹证据。所报告的标签使用多数决定;第一作者裁决三名评判全部不一致的条目。需要缺陷来源的分析使用能够识别其起源阶段的继承失败。为验证标签,第一作者在不看模型标签的情况下独立标注一个分层样本:通过的阶段、此前没有失败的失败阶段,以及跟随一次失败的阶段。一致性在裁决之前度量,只使用适用且已解决的比较;打发证据在两种判断都识别出一次打发时才比较。一个自动分类器把工具调用分成探索、编辑、测试、构建和其他动作。表 II 汇总盲审;第 V 节报告进一步的验证结果。
表 II:轨迹标签的盲法验证。
| 标签 | 一致 / $n$ | % | 95% 区间 |
|---|---|---|---|
| 过程标签 | |||
| 最终检查 | 175/180 | 97.2 | 93.7–98.8 |
| 最后测试结果 | 163/179 | 91.1 | 86.0–94.4 |
| 标准对准 | 161/180 | 89.4 | 84.1–93.1 |
| 停止原因 | 165/180 | 91.7 | 86.7–94.9 |
| 打发证据 | 41/44 | 93.2 | 81.8–97.7 |
| 先前察觉 | 56/60 | 93.3 | 84.1–97.4 |
| 诊断标签 | |||
| 继承 | 90/90 | 100.0 | 95.9–100 |
| F2P 原因:细 | 88/96 | 91.7 | 84.4–95.7 |
| F2P 原因:分组 | 96/96 | 100.0 | 96.2–100 |
规格说明检查。对 RQ3,我们检查自测为绿却与隐藏 F2P 结果冲突的情形。合格阶段从 $m_{0}$ 开始,或跟在一个通过的阶段之后,并且其检查被标为对准每一条验收标准。第一作者在一个随机样本中检查第一个失败的期望,排除用于盲法标签验证的链运行。每个期望按其可见依据分类:写在一份规格说明里、由规格说明所蕴含、由起始仓库所蕴含,或没有这些材料的支持。
IV-D 指标与统计
我们采用下列指标;括号中是表中的缩写。
- 单阶段通过率 $m_{0}$:第一阶段同时通过 F2P 和 P2P 的任务所占比例,从初始状态 $S_{0}$ 开始。
- 链关卡通过率(Gate):链关卡在最终工作区上通过的任务所占比例。
- 延续率(Cont.):在 $m_{1}$ 及以后的阶段通过率,条件是该链所有更早的阶段都已通过。
- 阶段 F2P 率(F2P):F2P 套件通过的、被评测阶段所占比例。
- 前缀深度(Depth):第一次失败之前连续通过的阶段数,除以链长度。
- 在 $m_{k}$ 处的存活:阶段数多于 $k$、且阶段 $m_{0}$ 到 $m_{k}$ 全部通过的任务所占比例。
- 链级 P2P 失败(P2P$\downarrow$):链级 P2P 套件失败的任务所占比例。
- 链内回归率:在每一次阶段完成时都通过了 F2P 的运行中,最终工作区未能通过链级 F2P 的比例。
- 纯回归率:在最终工作区通过链级 F2P 的运行中,链级 P2P 失败的比例。
对同一任务和同一阶段之内的比较,我们按所比较的条件拆分智能体,只保留同时含有两种条件的任务–阶段组。我们在每一组内计算每种条件的 F2P 通过率,再把这些比率在各组上等权平均。每一组里的智能体面对同一被请求的阶段,但保留各自的代码和对话历史。
智能体表现的置信区间是 95% 自助区间 [35],在 FeatureArc 的任务上做 4,000 次重抽样。
V 实验结果
我们报告 L4 评测过程下在 FeatureArc 上的结果。表 III 和表 IV 报告百分比,最佳值用粗体;表 III 按 Gate 排序。分析先考察整项功能的完成(RQ1),再考察更早错误的影响(RQ2),最后考察智能体检测并验证这些错误的能力(RQ3)。
轨迹标签验证。独立的人工标注为用来解释评测结果的轨迹标签提供一次检查。表 II 报告对 180 个阶段的盲审,第 IV-C 节定义的每个抽样组各 60 个。一致/$n$ 在适用比较中计与模型多数一致的次数;区间是 95% Wilson 区间 [36]。在各自适用的比较上,过程标签的一致率是 89.4%–97.2%,诊断标签是 91.7%–100.0%。对 RQ2 和 RQ3 处于中心的标签,该表报告先前察觉的一致率为 93.3%,继承为 100.0%。在三名模型评判之间,Fleiss 的 $\kappa$ [37] 对先前察觉、最终检查、停止原因、最后测试结果、继承和标准对准分别为 0.94、0.92、0.91、0.86、0.84 和 0.80。第一作者在 121 个阶段上裁决了 132 个标签条目,这些条目上评判全部不同。自动工具分类器在双方都识别出最终红/绿测试结果的阶段上,与轨迹标签的一致率为 94.8%。
表 III:L4 上 FeatureArc 的表现。
| 链 | 阶段级 | |||||
|---|---|---|---|---|---|---|
| 模型 | $m_{0}$ | Gate | Cont. | F2P | Depth | P2P$\downarrow$ |
| Claude Opus 5.5 | 83.6 | 49.3 | 79.2 | 68.4 | 64.9 | 5.5 |
| GPT-6 Astra | 67.1 | 37.0 | 76.1 | 55.5 | 50.4 | 20.5 |
| Hunyuan 4 Preview | 60.3 | 34.2 | 75.0 | 49.4 | 44.1 | 8.2 |
| GLM-5.3 | 64.4 | 31.5 | 72.0 | 56.3 | 45.8 | 19.2 |
| Grok 4.7 | 60.3 | 26.0 | 70.9 | 50.6 | 40.9 | 11.0 |
| Qwen 3.8 | 61.6 | 24.7 | 65.4 | 49.0 | 39.5 | 6.8 |
| Gemini 3.8 Flash | 61.6 | 23.3 | 66.2 | 49.4 | 42.0 | 5.5 |
| Doubao 2.1 Pro | 60.3 | 21.9 | 60.0 | 43.0 | 36.1 | 8.2 |
| Kimi K3 | 56.2 | 19.2 | 64.5 | 42.2 | 35.7 | 15.1 |
| DeepSeek V4 Pro | 52.1 | 17.8 | 61.5 | 40.3 | 31.6 | 11.0 |
| 汇总 | 62.7 | 28.5 | 70.1 | 50.4 | 43.1 | 11.1 |
表中十个智能体按链关卡通过率从高到低排列,最后一行是全体智能体的汇总。每一列的最佳值用粗体标出。从左到右,各列依次是第一阶段同时通过两类测试的比率、整项功能的链关卡通过率、更早阶段都已通过时的延续率、阶段失败转通过率、第一次失败前的前缀深度,以及链级既有行为测试失败的比率。
V-A RQ1:完成不断演进的功能
为判断一次请求上的成功能否带到一项演进的功能,我们比较表 III 中的第一阶段表现和链关卡表现。图 5 和图 6 随后把这一差距与阶段位置和任务长度联系起来。图 5 汇总各智能体,在那些阶段使用分别含有 $m_{2}$ 和 $m_{3}$ 的 57 个和 34 个任务。图 6b 比较第一阶段(空心)和链关卡(实心)分数及其任务自助区间;$\Delta$ 是它们的百分点差。
图 5:跨阶段和任务长度的表现。
图 6:任务在何处中断。
发现 1:链关卡通过率降到不到第一阶段通过率的一半。第一阶段从 $S_{0}$ 开始,等价于一个标准的单阶段任务。在智能体上汇总,成功从第一阶段的 62.7% 降到链关卡的 28.5%(表 III)。每个智能体都损失 26.0–38.4 个百分点(图 6b),即使在每一项指标上领先的 Claude Opus 5.5,也有超过一半的任务失败。排名大体保持相似($m_{0}$ 与链关卡之间的 Spearman $\rho{=}0.87$),但第一阶段分数高估了智能体完成一项功能的频率。
发现 2:只检查最后阶段会高估成功。最后阶段关卡用其阶段级 F2P 和 P2P 套件检查最后一次扩展,而链关卡在最终工作区上检查完整功能。在通过最后阶段关卡的 273 次运行中,有 69 次(25.3%)未能通过链关卡。图 2 中单独的整项功能检查发现了这一错配:通过最后一次扩展,并不能确立完整功能在最终代码上能够工作。恢复是可能的,但不常见:在至少有一个失败阶段的 525 次运行中,只有 14 次(2.7%)最终通过链关卡,即图 6a 中标为 “Rec.” 的区段。“Gate fails” 标出通过了每一个阶段关卡、却未能通过链关卡的运行。
发现 3:大多数运行在前两个阶段中断,长任务很少成功。图 6a 显示从未恢复的运行第一次在何处失败。在全部运行的 36.2% 中,智能体已经在 $m_{0}$ 失败;另有 20.7% 第一次失败在 $m_{1}$,即第一个建立在它自己代码上的阶段。只有 13.2% 的运行第一次失败在更后的阶段。图 5a 中下降的存活曲线显示,这些早期失败如何降低随着需求累积而仍然正确的链所占份额。成功也随任务长度陡降(图 5b):链关卡在两阶段任务的运行中有 44.4% 通过,但在五个或更多阶段的任务上只有 1.5%;只有两次运行通过,都是 Grok 4.7。在 L4 完成这些更长的功能仍然困难。
对 RQ1 的回答:在 L4,智能体完成一整项演进功能的频率远低于它们通过其第一阶段的频率:汇总成功从 62.7% 降到 28.5%。大多数运行在 $m_{0}$ 或 $m_{1}$ 中断,有失败阶段的运行很少完全恢复,五个或更多阶段的任务几乎从未被完成。
V-B RQ2:更早错误的影响
图 7:按前一阶段结果划分的下一阶段 F2P 成功。
为解释第一阶段之后的失败,我们考察后续阶段是建立在正确行为之上,还是继承了未解决的缺陷。图 7 比较通过的阶段与失败的阶段之后的下一阶段成功,表 IV 报告轨迹证据。智能体回看更早代码的程度与参考实现相近:它们后续阶段被改文件中有 52.8%–57.7% 在更早被改过,与图 4d 所示的依赖一致。这确立了这样一个设定:一个更早的实现错误可以影响后来的请求。
表 IV:FeatureArc 上的错误继承与自我验证。
| 自测 | 轨迹标签 | |||||
|---|---|---|---|---|---|---|
| F2P 在其后 | 结束于 | 标准 | 先前 | |||
| 模型 | 绿 | 红 | 绿色 | 对准 | 继承 | 察觉 |
| Claude Opus 5.5 | 68.6 | 68.1 | 70.3 | 76.4 | 73.8 | 95.2 |
| GPT-6 Astra | 54.5 | 46.4 | 81.0 | 82.9 | 74.8 | 95.6 |
| Hunyuan 4 Preview | 52.6 | 41.3 | 65.8 | 70.3 | 73.7 | 90.2 |
| GLM-5.3 | 59.0 | 51.0 | 77.9 | 84.8 | 68.2 | 94.5 |
| Grok 4.7 | 57.1 | 38.9 | 70.0 | 62.7 | 77.6 | 99.0 |
| Qwen 3.8 | 51.0 | 42.1 | 77.6 | 78.3 | 71.9 | 93.2 |
| Gemini 3.8 Flash | 49.6 | 20.0 | 97.3 | 77.2 | 71.9 | 97.1 |
| Doubao 2.1 Pro | 47.2 | 34.6 | 68.4 | 70.0 | 73.1 | 90.4 |
| Kimi K3 | 44.9 | 48.0 | 67.7 | 50.6 | 69.7 | 98.2 |
| DeepSeek V4 Pro | 41.5 | 32.4 | 62.4 | 30.4 | 75.0 | 96.6 |
| 汇总 | 52.7 | 45.2 | 73.8 | 68.4 | 72.9 | 94.9 |
发现 4:继承来的缺陷在失败的后续阶段中很常见。下一阶段的 F2P 成功从通过的阶段之后的 70.2% 降到失败的阶段之后的 22.6%(图 7)。这一差距在每个智能体上都出现。使用第 IV-D 节定义的、每个任务和阶段之内的比较,我们保留 109 个同时含有两种前一阶段结果的任务–阶段组。当任务–阶段组被等权时,差距仍然存在:组内平均的 F2P 通过率在通过的阶段之后是 72.6%,在失败的阶段之后是 29.0%。一旦一次运行有一个阶段失败,平均而言其剩余阶段也有 85.1% 失败。表 IV 的继承列把这一表现差距连接到具体缺陷:失败的后续阶段中有 72.9% 涉及留在更早阶段里的错误,这些缺陷完全解释失败的占 47.1%,部分解释的占 25.9%。
我们也考察阶段位置和语境如何与后续阶段的成功相关。在所有更早阶段都通过的运行中,$m_{1}$、$m_{2}$ 和 $m_{3+}$ 的阶段关卡通过率在 66.6% 到 77.7% 之间,没有下降趋势。对有语境测量可用的后续阶段,检测到语境压缩与否之间的 F2P 差距,在工具调用少于 40 次的阶段是 6.2 个百分点,在 40–99 次工具调用的阶段是 5.2 个百分点。在前缀全部通过的后续阶段中,当累计规格说明含有 1,500–2,999 个词时 F2P 成功为 75.0%,当它们至少含有 8,000 个词时为 68.6%,相差 6.4 个百分点。这些差距小于与前一阶段结果相关的 47.6 个百分点差距。
发现 5:阶段通过其测试之后,回归并不常见。回归,即后来的编辑破坏已经能工作的行为,是一条链失败的另一种方式。我们用两种方式度量它。链内回归:每个阶段都通过了自己的 F2P 套件,但最终工作区未能通过链级 F2P 套件;它发生在每个阶段都通过了 F2P 的运行中的 7.3%。纯回归:最终工作区通过链级 F2P,但链级 P2P 失败;它发生在最终工作区通过链级 F2P 的运行中的 3.3%。继承来的缺陷使至少随后一个阶段失败,这发生在 52.9% 的功能运行中,与表 IV 的继承证据一致。确立了所需行为的运行,通常把它保持到最终检查。表 III 中较高的 P2P 失败率(5.5%–20.5%)也包括新功能行为失败的运行;它们回答的问题比纯回归更宽。
对 RQ2 的回答:更早的缺陷经常影响后来的开发:下一阶段的 F2P 成功从通过的阶段之后的 70.2% 降到失败的阶段之后的 22.6%,轨迹分析在 72.9% 的失败后续阶段中识别出继承来的缺陷。在这里所考察的条件度量下,成功实现之后的回归较少见。
V-C RQ3:检测并验证错误
为理解智能体为何从有缺陷的代码继续,我们考察它们是否注意到更早的失败,以及它们自己的检查是否提供正确性的可靠证据。表 IV 把察觉和验证行为连接到隐藏测试结果;较低的继承率和错过先前失败的比率被标为更好。图 8 在智能体上汇总后续阶段,显示以最终自测和前一阶段结果为条件的隐藏 F2P 结果。
发现 6:智能体很少注意到自己更早的错误。对跟随一次失败的阶段,先前察觉标签显示,智能体在 94.9% 的情形中从未注意到更早的错误(每个智能体 90.2%–99.0%,表 IV);盲审在抽样的 60 个阶段中的 56 个上与这些标签一致(表 II)。在智能体确实注意到错误的 50 个阶段中,它在 34 个里修复了错误。这些修复情形表明,一旦错误被认出,纠正是可能的;大得多的错过失败组把更常见的故障放在检测上。
失败阶段之后,工具使用变化不大。对 Claude Code 上的九个智能体,失败阶段之后的工具调用中位数比通过阶段之后高 4%–18%,花在测试上的调用份额几乎不变(Claude Opus 5.5 是 15.0% 对 15.3%)。
图 8:自测与隐藏 F2P 结果。
发现 7:绿色自测几乎不能预测隐藏 F2P 结果,红色自测通常被打发掉。智能体在自己的测试通过时停止,但一次通过的自测对隐藏 F2P 套件说明很少。总体而言,73.8% 的阶段结束于绿色自测,但其中只有 52.7% 通过 F2P,只略高于全部阶段上的 50.4%;结束于红色的阶段仍有 45.2% 通过(表 IV)。表 IV 中的绿/红是条件 F2P 率;结束于绿色是结束为绿色的份额。Grok 4.7 和 Gemini 3.8 Flash 的红色估计使用的阶段少于 20 个。使用同一比较程序,在同时含有两种结果的 161 个任务–阶段组上,组内平均 F2P 通过率对绿色最终自测是 52.9%,对红色最终自测是 47.9%。如图 8 所示,自测在紧接一个失败阶段之后最不可靠:在仍然结束于绿色自测的 713 个阶段中,只有 24.5% 通过 F2P。假绿的份额,即阶段未能通过 F2P 的绿色自测,从通过阶段之后的 28.7% 升到失败阶段之后的 75.5%。
红色自测一旦出现,通常被打发掉。在结束于红色的 367 个阶段中,智能体在 321 个(87.5%)里声称失败无关或早已存在。这 321 个里只有 23 个(7.2%)先在该阶段的起始代码上运行同一测试,以确认它在那里已经失败。因此最终自测结果是正确性的弱信号,而红色结果常常导致打发。
发现 8:对准每一条标准的自测仍然会错过规格说明所要求的东西。标准对准标签把 68.4% 的阶段,以及每个智能体 30.4%–84.8% 的阶段,标为具有演练全部验收标准的检查(表 IV)。对准全部标准提供的保证有限:这些阶段在 54.9% 的情形中通过 F2P,而检查只演练部分标准时是 42.1%。使用同一比较程序,在同时含有两类的 190 个任务–阶段组上,组内平均 F2P 通过率对全部标准是 50.4%,对部分标准是 38.5%。在对准全部标准的阶段中,仍有 45% 未能通过 F2P,而这些失败中有 62% 跟随一个智能体没有注意到的、更早失败的阶段。
这一错配也出现在第一阶段和通过的阶段之后。标准覆盖与测试期望的正确性是不同的:一次检查可以对准所请求的行为,同时编码一个不正确的期望结果。在 239 个阶段中,检查演练了全部标准,阶段从 $m_{0}$ 开始或跟在一个通过的阶段之后,自测结束为绿色,而 F2P 仍然失败;大多数是错误的逻辑或读错了规格说明(54.4%),或漏掉一种情况或部分实现(24.3%)。在第 IV-C 节所述的 60 个阶段的规格说明检查中,第一个失败期望里有 34 个明确写在当前或更早的规格说明里,12 个由这些规格说明推出,14 个由起始仓库推出。
同样的差距出现在任何测试运行之前。在未能通过 F2P 的 1,304 个阶段中,有 236 个(18.1%)失败是因为隐藏套件不能编译;其中 228 个由智能体造成,接口不匹配造成这 228 个中的 61.4%:缺少符号或导出、参数或返回类型错误,以及重复声明。在缺少的名字中,44.1% 出现在当前阶段的规格说明里,30.5% 出现在更早阶段的规格说明里。连同表 IV 的标准对准列和绿色测试列,这些情形说明,为什么检查智能体对一条需求的解释,仍可能错过任务中陈述的行为。FeatureArc 通过明确的契约和分开的验收检查,使这一差异可观察。
对 RQ3 的回答:在跟随一次失败的阶段中,智能体有 94.9% 没有注意到更早的错误。它们的自测提供的保证有限:结束于绿色自测的阶段只有 52.7% 通过 F2P,而在一个失败阶段之后这一比例降到 24.5%。即使被标为对准每一条标准的检查也可能错过已说明的行为,而最终的红色结果通常在没有基线检查的情况下被打发掉。
VI 讨论
VI-A 在腾讯的工业应用
把观察到的使用连接到内部评测。在腾讯 8,881 个 IDE 回合的内部语料中,有有效用户轮次的 8,728 个回合里,有 3,797 个(43.5%)含有后续交互。对第一次后续交互的基于模型的标注识别出约束添加(30.1%)、需求澄清(19.7%)和功能扩展(17.9%)。所观察到的扩展促使我们评测持续的功能开发。要减少扩展之间的用户检查,智能体必须发现自己更早代码中的缺陷。腾讯现有的 L1–L3 评测提供失败反馈,使这种无人帮助的检测能力未经测试。因此我们用我们的流水线和 FeatureArc,在 L4 上把 Hunyuan 4 Preview 与外部智能体一起评测:用户提供相继的需求,而更早的失败不报告给智能体。
诊断超出第一阶段分数的开发需要。表 III 显示,Hunyuan 4 Preview 通过 60.3% 的第一阶段,但只完成 34.2% 的整项功能(95% 区间 23.3%–45.2%)。它 75.0% 的延续率表明,当更早的阶段正确时,它常常能够扩展一项功能。图 7 揭示错误之后的另一种情形:下一阶段的 F2P 成功从通过阶段之后的 71.6% 降到失败阶段之后的 22.5%。表 IV 中的先前察觉证据有助于解释这一差距:Hunyuan 有 90.2% 的更早失败未被注意到。这是被评测智能体中最低的错过失败率;大多数更早的错误在随后的功能开发中仍然未被认出而持续存在。
把评测证据变成开发优先级。流水线把不成功的运行连接到规格说明、代码更改和检查,帮助混元团队把未能实现新行为的失败,与未能认出继承缺陷的失败区分开。例如,Hunyuan 在 46 个阶段中的 44 个里,把一次最终失败的自测归因于无关或早已存在的原因,但只在这 44 个中的 5 个里对照起始代码检查了该解释。这一证据给混元团队提供了具体的失败案例,用以改进对更早需求的检查,以及对失败解释的验证。当用户把中间验证留给智能体时,这些能力是支持持续功能开发所必需的。
VI-B 对效度的威胁
FeatureArc 可能没有覆盖真实世界功能开发中遇到的全部工作流范围。为拓宽覆盖,它包括四种广泛使用的编程语言——Python、TypeScript、Rust 和 Go——以及七个应用领域,任务按语言和链长度分层(图 4)。这一广度,连同从仓库历史挖掘出的任务,帮助该基准反映智能体在实际开发设定中、面对演进需求时的表现。
VII 相关工作
功能与交互式基准。单次请求基准在固定代码库上评测功能实现 [9, 10, 11]。多阶段功能基准 [12, 13, 14, 16] 和顺序开发基准 [38, 39, 40, 41, 42, 43] 把评测扩展到多个开发阶段,阶段来源、功能范围和反馈各不相同。EvoCode-Bench 允许四次尝试,在第一次失败时停止,并与从参考代码开始作比较 [15]。交互式基准加入会回应的用户 [44, 45]、增量需求 [46, 47],或澄清 [48]。
任务构造。环境合成方法准备可执行的仓库 [49, 50, 51, 52],而自动流水线收集或合成单个任务 [53, 54, 55, 56, 57, 58, 59, 60, 61]。DeepCommit [38] 和 WEAVE [62] 从仓库历史恢复依赖;WEAVE 用它们在一个任务内部授予部分分数。
自我验证。执行反馈支持自我修复 [63, 64],但其效果取决于反馈质量 [65]。弱测试会高估正确性 [66],而生成能暴露缺陷的检查仍然困难 [67]。
FeatureArc 的不同之处在于,它把历史上的同一功能依赖,与在智能体自己的代码上继续评测、且没有中间失败反馈结合起来(表 I)。经过验证的阶段检查和整项功能检查度量跨扩展的正确性,而轨迹分析考察继承错误的持续存在和检测。
VIII 结论
我们给出了 FeatureArc,以及一条从其仓库历史构造其可执行功能演进任务的流水线。该基准把历史上的同一功能依赖、以需求为依据的验证和多样的仓库语境结合起来,以评测在没有外部验收反馈的情况下扩展自己代码的智能体。我们的研究揭示第一阶段实现与整项功能完成之间的实质性差距:汇总成功从 62.7% 降到 28.5%。继承来的缺陷在失败的后续阶段中很常见,智能体很少注意到这些错误,或通过自测把它们暴露出来。在腾讯,这条流水线把内部评测扩展到 L4,并提供关于 Hunyuan 在功能开发期间认出错误并从中恢复的能力的证据。FeatureArc 支持在需求演进时进一步研究持续的功能正确性,使用互相依赖的阶段和可执行检查。
觉得有用,转给同事
微信扫码
用微信扫一扫,在手机上打开后即可转发。