【论文阅读】SWE-CI: Evaluating Agent Capabilities in Maintaining Codebases via Continuous Integration
基于大语言模型(LLM)的智能体已在自动化软件工程任务(如静态缺陷修复)中展现出强大能力,SWE‑bench 等基准测试已充分证明这一点。但在实际场景中,成熟软件的开发通常建立在复杂的需求变更与长期功能迭代之上 —— 这一过程是静态、一次性的修复范式所无法刻画的。为弥补这一差距,我们提出 SWE‑CI,这是首个基于持续集成(CI)流程构建的代码库级基准测试,旨在将代码生成的评估范式从静态、短期的功
SWE-CI:基于持续集成评估智能体在代码库维护中的能力
论文链接
https://arxiv.org/pdf/2603.03823
摘要
基于大语言模型(LLM)的智能体已在自动化软件工程任务(如静态缺陷修复)中展现出强大能力,SWE‑bench 等基准测试已充分证明这一点。但在实际场景中,成熟软件的开发通常建立在复杂的需求变更与长期功能迭代之上 —— 这一过程是静态、一次性的修复范式所无法刻画的。为弥补这一差距,我们提出 SWE‑CI,这是首个基于持续集成(CI)流程构建的代码库级基准测试,旨在将代码生成的评估范式从静态、短期的功能正确性转向动态、长期的可维护性。该基准包含 100 个任务,每个任务平均对应真实代码仓库中长达 233 天、71 次连续提交的项目演进历史。SWE‑CI 要求智能体通过数十轮分析与编码迭代,系统性地完成这些任务,从而为评估智能体在代码长期演进过程中维持代码质量的能力提供有价值的参考。
1. 简介
自动化软件工程一直是人工智能领域的核心目标。近年来,大语言模型(LLM)的突破性进展为这一目标提供了强劲动力 —— 从代码补全、测试生成到端到端程序修复,基于大语言模型的智能体已在多项基准测试中展现出可与人类开发者相匹敌的能力。编码基准测试的同步发展在这一进程中起到了关键作用,既提供了严谨的能力评估手段,也指明了清晰的研究方向。
在代码生成层面,HumanEval [1]、MBPP [2] 和 LiveCodeBench [3] 确立了单文件代码合成的评估范式。在代码库层面,SWE-bench [4] 提出了 “Issue 到 PR”范式,要求模型在完整代码库环境中生成补丁。在智能体交互层面,Terminal-bench [5] 和 τ-bench [6] 进一步将评估范围拓展至终端操作与多轮工具使用 。这些工作共同构建了一个多粒度、多场景的代码智能评估体系。
尽管这一评估体系具备广度与深度,但其底层范式仍存在一个根本性局限:现有基准几乎只关注评估智能体编写功能正确代码的能力。然而在现实场景中,成功的软件很少是一蹴而就的,它是长期维护的结果。Lehman 定律表明,软件质量会随着维护过程自然下降 [7];而经典文献早已证实,维护活动占软件整个生命周期成本的 60%~80%[8]。因此,亟需设计新的基准,以有效衡量模型对代码的长期维护能力。
这种能力长期未被纳入评估,其根源在于主流基准测试范式本身。从 HumanEval、LiveCodeBench 到 SWE‑bench 和Terminal‑Bench,现有基准普遍采用快照式评估流程:智能体接收一次完整的需求,并给出一次性解决方案。在这种范式下,一个写出硬编码、脆弱修复的智能体,与一个写出整洁、可扩展代码的智能体,可能都能通过同一套测试用例—— 二者在可维护性上的差异完全无法体现。只有当代码库需要持续演进时(新需求出现、接口变更、模块必须扩展),这种差异才会显现。此时,早期设计决策带来的代价会不断累积。一个经常生成结构糟糕代码的智能体,会发现后续修改越来越困难,最终无法跟上迭代节奏。由此得到一个关键结论:智能体的代码维护能力,只能通过长期演进过程来体现—— 在持续的代码变更中,历史决策的后果会不断累积并显现。
基于这一认识,我们提出 SWE‑CI(软件工程–持续集成),这是一个用于评估智能体在长期代码演进过程中维护代码能力的全新基准。SWE‑CI 包含 100 个任务,每个任务均来自真实代码库,由一个起始提交(base commit)和一个目标提交(target commit)定义,平均覆盖 233 天 的真实演进历史与 71 次连续提交。SWE‑CI 采用架构师–程序员双智能体评估机制:从起始提交开始,智能体执行持续集成循环,迭代生成需求、修改源码并运行测试,最终目标是通过与目标提交相关的所有测试。SWE‑CI 提出 EvoScore(演进得分) 作为代理指标:它衡量智能体在后续代码修改中的功能正确性,因此早期决策更利于后续演进的智能体会获得更高分数,而不断累积技术债的智能体则会表现持续下降。
我们开展了大规模实验,总 token 消耗量超过 100 亿。结果表明,尽管模型在功能正确性上已取得显著进步,但当前最优模型在长期代码演进中维持代码质量的任务上仍面临较大困难。我们进一步对评估结果进行了全面、细粒度的分析,为基于大语言模型的智能体的编码能力提供了有价值的见解,并证明了 SWE‑CI 独特的诊断价值。
2. 评估智能体维护代码库的能力
2.1 任务形式化
我们首先为智能体编码任务建立统一的形式化定义。设 t t t 表示单个单元测试, T = { t 1 , t 2 , … , t ∣ T ∣ } T = \{t_1, t_2, \dots, t_{|T|}\} T={t1,t2,…,t∣T∣} 为我们关注的所有测试构成的集合。设 C C C 为代码库空间, R R R 为需求空间。我们进一步定义两个函数:
- requireT : C × C → R \text{requireT}: C \times C \rightarrow R requireT:C×C→R,该函数用于识别两个代码库之间关于测试集 T T T 的功能差异,并据此生成需求文档。
- codeT : R × C → C \text{codeT}: R \times C \rightarrow C codeT:R×C→C,该函数根据给定需求对代码库进行修改,并返回更新后的代码库。
基于上述定义,我们发现目前许多主流的代码基准测试[1,2,3,4,5,6]都遵循图1所示的基于快照的评估范式。在该范式中,需求仅依赖于基础代码库 c 0 c_0 c0 与“标准答案”代码库 c ∗ c^* c∗,即 r ≡ requireT ( c 0 , c ∗ ) r \equiv \text{requireT}(c_0, c^*) r≡requireT(c0,c∗)。在实际使用中,基准维护者会预先生成需求 r r r 并将其保存为提示词,因此基准使用者无需重新生成。然而,本文转而考虑基于演进的评估范式。该范式中的需求是从当前代码库动态推导而来: r i = requireT ( c i , c ∗ ) r_i = \text{requireT}(c_i, c^*) ri=requireT(ci,c∗),代码库也随之更新: c i + 1 = codeT ( c i , r i ) c_{i+1} = \text{codeT}(c_i, r_i) ci+1=codeT(ci,ri)。这一迭代循环保证了早期修改产生的影响会传递到后续迭代中,从而使得智能体的长期决策质量可被观测。

图1:与以往基准评测不同,SWE‑CI 提出了基于演进的评估方式。红色箭头与蓝色箭头分别表示函数 require \text{require} require 和 code \text{code} code 的执行过程。虚线表示对用户不可见的过程。
2.2 归一化变更
大多数基准测试将通过所有测试用例作为功能正确性的黄金标准。然而在软件工程中,部分功能需要长期规划与增量开发,而非一次性实现。此外,在代码演进过程中,原本通过的测试很容易被意外破坏——这种现象被称为回归(regression)。因此,我们需要一种更细粒度的指标来反映代码库 c c c 的当前状态,而非简单的“通过/失败”二值判断。为此,我们提出归一化变更(normalized change)。
设 n ( c ) n(c) n(c) 为代码库 c c c 通过的测试用例数量:
n ( c ) = ∑ t ∈ T I ( t , c ) (1) n(c) = \sum_{t\in T} \mathcal{I}(t, c) \tag{1} n(c)=t∈T∑I(t,c)(1)
其中指示函数 I ( t , c ) \mathcal{I}(t, c) I(t,c) 当且仅当单元测试 t t t 在代码库 c c c 上通过时取值为 1,否则为 0。
归一化变更 定义如下:
a ( c ) = { n ( c ) − n ( c 0 ) n ( c ∗ ) − n ( c 0 ) if n ( c ) ≥ n ( c 0 ) , n ( c ) − n ( c 0 ) n ( c 0 ) else . (2) a(c) = \begin{cases} \dfrac{n(c) - n(c_0)}{n(c^*) - n(c_0)} & \text{if } n(c) \geq n(c_0),\\[6pt] \dfrac{n(c) - n(c_0)}{n(c_0)} & \text{else}. \end{cases} \tag{2} a(c)=⎩
⎨
⎧n(c∗)−n(c0)n(c)−n(c0)n(c0)n(c)−n(c0)if n(c)≥n(c0),else.(2)
当智能体在基础代码库上有所改进时( n ( c ) ≥ n ( c 0 ) n(c) \geq n(c_0) n(c)≥n(c0)),分子通过总差距 n ( c ∗ ) − n ( c 0 ) n(c^*) - n(c_0) n(c∗)−n(c0) 进行归一化,因此当且仅当智能体完全消除了差距时, a ( c ) = 1 a(c) = 1 a(c)=1。当智能体出现回归且低于基线时( n ( c ) < n ( c 0 ) n(c) < n(c_0) n(c)<n(c0)),分子改用 n ( c 0 ) n(c_0) n(c0) 归一化,因此 a ( c ) = − 1 a(c) = -1 a(c)=−1 对应破坏了所有初始可通过的测试。这种非对称归一化是刻意设计的:无论 n ( c 0 ) n(c_0) n(c0) 和 n ( c ∗ ) n(c^*) n(c∗) 多大或多小,改进与回归都能在统一、可比较的尺度上表示——即 a ( c ) ∈ [ − 1 , 1 ] a(c) \in [-1, 1] a(c)∈[−1,1]。
2.3 EvoScore(演进得分)
ISO/IEC 25010 标准将可维护性定义为:软件能够在不引入缺陷、不降低现有质量的前提下被有效修改的程度[9]。其核心含义是:可维护性无法在单一快照中体现,它只能通过持续的迭代修改表现出来。基于这一原则,给定从 N N N 轮迭代中得到的代码库序列 ( c 1 , … , c N ) (c_1,\dots,c_N) (c1,…,cN),我们通过未来加权平均将其聚合为一个标量指标——EvoScore(演进得分):
e = ∑ i = 1 N γ i a ( c i ) ∑ i = 1 N γ i (3) e = \frac{\sum_{i=1}^N \gamma^i a(c_i)}{\sum_{i=1}^N \gamma^i} \tag{3} e=∑i=1Nγi∑i=1Nγia(ci)(3)
在 EvoScore 中,我们设置 γ ≥ 1 \gamma \ge 1 γ≥1,从而给后续迭代更大的权重。其设计思想与 ISO 定义直接对应:一个真正具备可维护性的代码库,应当在持续演进中依然保持易于修改。相比于那些急于通过早期测试、却不断累积技术债务进而阻碍后续迭代的智能体,为更清晰、可扩展的设计而牺牲短期速度的智能体将获得更高分数。当 γ = 1 \gamma=1 γ=1 时,EvoScore 退化为归一化变更的平均值;随着 γ \gamma γ 增大,该指标会更看重长期稳定性,而非短期收益。

图2:SWE‑CI 的数据构建流程
3 SWE-CI
3.1 数据构建(Data curation)
如图1所示,我们的目标是获取多组基础代码库/标准答案代码库对,并让智能体将前者迭代演进至后者,以此衡量其在整个过程中的代码维护能力。每一组这样的配对都可以看作是同一代码库中按时间顺序排列的两次提交。具体而言,SWE‑CI 的构建过程精心设计如下:
Step 1: Repository Collection
与 SWE-Bench 及同类基准仅从少数知名开源项目中选取数据不同,我们通过在 GitHub 上搜索所有 Python 代码库来扩大数据范围。随后我们应用以下筛选条件:
- 代码库至少已持续维护三年以上;
- 获得超过 500 星标;
- 包含配置与依赖文件(如
pyproject.toml、锁文件等)以及完整的单元测试集; - 采用 MIT 或 Apache-2.0 等宽松开源协议。
经过这些筛选后,剩余4923 个代码库
Step 2: Commit Span Extraction
对于每个通过筛选的代码库,我们仅保留其主分支,将提交历史简化为线性序列。随后,我们沿着该序列比较连续提交之间的依赖关系,并找出所有依赖保持不变的极大子序列。每个这样的子序列的两个端点自然构成一组候选的基础代码库/标准答案代码库对。我们进一步剔除总修改代码行数低于 1000 行的配对,因为这类配对的演进距离不足。该过程最终得到 8311 组候选配对。
Step 3: Environment Construction
对于每一组候选配对,我们基于标准答案代码库的配置与依赖,自动生成 Dockerfile,并对构建出的运行环境进行快照。随后在该环境中执行标准答案代码库的单元测试集,以验证其正确性。为了提高数据留存率,我们引入了自修复机制:当测试集因缺失依赖而无法启动时,系统会检测故障并动态将所需依赖注入 Dockerfile,以构建新环境。该机制大幅提升了有效候选配对的数量。因其他原因导致测试失败的配对则被丢弃。此步骤结束后,剩余 1458 组候选配对及其运行环境快照。
Step 4: Case Filtering
最后,我们再进行三轮过滤以保证最终数据集的质量。首先,在步骤 3 构建的运行环境快照中,我们使用标准答案代码库的测试集对基础代码库进行测试,任何无法启动测试的候选配对均被剔除。其次,我们对比基础代码库与标准答案代码库在同一测试集上的测试报告;通过测试数量之差少于 5 个的候选配对被移除。经过这两步自动化过滤后,剩余 137 组候选配对。在最后一轮中,我们按照时间跨度与中间提交次数对剩余候选配对进行排序,并选取前 100 组构成最终的 SWE-CI 基准评测集。

最终的 SWE‑CI 基准评测包含来自 68 个不同代码库的 100 个样本。平均每组基础/标准答案代码库对覆盖 233 天的真实开发周期,包含 71 次连续提交。在每组代码库对中,从基础版本到标准答案版本的变更至少涉及 500 行源码修改(测试文件修改不计入)。每个样本都附带完整源码与预构建的 Docker 环境,以保证实验可复现。这些数据表明,SWE‑CI 捕捉的是真实、大规模、长期的代码演进过程,而非微小的增量改动。
3.2 双智能体评估协议
如图1所示,SWE‑CI 采用基于演进的评估。为支持这一设定,我们提出了架构师–程序员双智能体协议。架构师负责识别功能差距并提出需求;程序员负责实现这些需求。二者的协作复现了真实开发中的持续集成(CI)循环,从而能够细粒度地观测智能体维护代码的能力。
架构师智能体(Architect agent)
根据当前代码与标准答案代码之间的测试差距,架构师负责以自然语言生成一份高层次需求文档。我们通过提示词让架构师按三步执行:
❶ 总结(Summarize):审查所有失败的测试,定位根本原因,并识别需要进一步检查的源码文件;
❷ 定位(Locate):分析源代码,将失败归因于当前实现中的具体缺陷;
❸ 设计(Design):根据这些缺陷制定改进方案,并生成最终的需求文档。
需求文档还遵循两条撰写规范:
➀ 增量式(Incremental):文档只包含最多 5 个最紧急的需求,避免单次迭代过度设计;
➁ 高层次(High-level):需求只需用自然语言描述代码的预期行为,将具体实现选择交给程序员。
这些规范的核心目的,是确保需求文档符合真实世界持续集成流程的实际需要。
程序员智能体(Programmer agent)
程序员的职责是根据需求文档对代码进行维护。其行为同样被规范为三个步骤:
❶ 理解(Comprehend):理解高层次的自然语言需求,并将其转化为明确的代码规范。
❷ 规划(Plan):规划实现这些规范所需的开发工作。
❸ 编码(Code):将规划付诸实践,尽力完成需求。
在该协议中,程序员由需求文档驱动,而非直接由测试差距驱动——这是一个刻意的设计选择,与持续集成的快速迭代理念保持一致。为此,架构师需要从全部失败用例中提炼出最紧迫的需求,让程序员专注于快速、有针对性的开发,而不会被整体变更规模压垮。
4 Experiments
4.1 Experiment setting
我们使用 pytest 和 pytest-json-report 作为测试框架,每次测试运行的超时时间为 3600 秒。iFlow CLI [10] 作为默认的智能体框架,双智能体评估协议中的最大迭代次数设置为 20。除非另有说明,架构师智能体与程序员智能体共享相同的底层基座模型。
4.2 结果
观察 1:大语言模型的代码维护能力正呈加速提升趋势(图 4)
我们对来自 8 个厂商的 18 个模型进行了全面评估,结果呈现出一致规律:在同一厂商的模型系列中,新版本模型总能取得更高分数,2026 年之后发布的模型相比前代提升幅度尤为明显。这表明,当前大语言模型的代码能力正快速从静态缺陷修复,向持续、长期的代码维护方向演进。在所有评估模型中,Claude Opus 系列在整个观测周期内均保持显著领先,GLM-5 同样表现突出。

观察 2:不同厂商对代码可维护性的重视程度存在差异(图 5)
我们通过改变 γ 的取值来观察模型排名的变化。当 γ < 1 时,EvoScore 会对早期迭代赋予更高权重,更青睐那些能通过代码修改快速获得即时收益的模型。反之,当 γ > 1 时,后期迭代会获得更高奖励,更有利于面向长期优化(即更重视代码可维护性)的模型。我们发现,不同厂商的模型偏好差异显著,而同厂商的模型则表现出一致的倾向。具体来说:MiniMax、DeepSeek 和 GPT 更偏向长期收益;Kimi 和 GLM 更偏向短期收益;而 Qwen、豆包(Doubao)与 Claude 在不同设置下表现相对稳定。我们推测这反映了不同厂商在训练策略上的差异,而同一家厂商内部模型的一致性则说明其内部训练流程相对稳定。

观察 3:当前大语言模型在长期代码维护中,仍难以有效控制回归问题(图 6)
回归(regression)是衡量软件质量稳定性的核心指标——如果某个单元测试在代码修改前能通过,修改后却失败,就认为本次修改引入了回归。在软件维护中,回归问题必须被严格监控。一旦发生回归,不仅会直接影响用户体验,在长期维护中,随着修改次数的累积,还可能导致系统质量持续下降。为此,我们在 SWE-CI 中统计了在整个代码维护过程中完全没有出现回归的样本占比,称为零回归率(zero-regression rate),用于评估模型在持续维护场景下的稳定性。实验结果表明,大多数模型的零回归率都低于 0.25,只有 Claude-opus 系列中的两个模型超过 0.5。这说明当前大语言模型在长期代码维护中,仍难以可靠地避免回归问题。这意味着,尽管大语言模型在基于单轮快照的代码修改任务上已取得显著提升,但在全自动、长期、多轮的软件开发与维护场景中,仍面临巨大挑战。

更多推荐

所有评论(0)