跳到主要内容

AI 编程代理在遗留代码库上的表现:为什么在你最需要它们的地方,它们往往会失败

· 阅读需 12 分钟
Tian Pan
Software Engineer

最迫切需要 AI 编程帮助的团队,通常并不是那些正在构建全新服务(greenfield services)的团队。他们往往正在维护 2012 年产出的 50 万行 Rails 单体应用,或是处理过数十亿笔交易的 COBOL 支付系统,亦或是架构师早在三次收购前就已离职的微服务网格。在这些代码库中,一个位置不当的重构就可能引入隐蔽的数据损坏漏洞,而这些漏洞往往在三周后的生产环境中才会浮现。

而这恰恰是目前的 AI 编程助手(agents)失败得最惨烈的地方。

令人沮丧的是,这种失效模式在爆发前是隐形的。AI 助手生成的代码可以通过编译,通过现有测试,并在审查中看起来非常合理。问题往往出现在预发环境(staging)、深夜的批处理作业,或者是某个客户在月份特定日期才会触发的边缘情况中。

全新项目基准测试陷阱

现代 AI 编程助手在 HumanEval(根据文档字符串实现函数)和 SWE-bench(修复孤立的 GitHub 问题)等任务上进行基准测试。这些基准测试几乎已经饱和——前沿模型在 SWE-bench Verified 上的得分超过 80%,而 HumanEval 已被基本攻克。

但最近发布的一项名为 SWE-EVO 的基准测试衡量了不同的维度:在真实遗留系统上的长周期软件演进。目前最好的模型只能完成 21% 的任务,而相比之下,它们在 SWE-bench Verified 上的完成率为 65%。这 21% 与 65% 之间的差距,真实地反映了当 AI 助手离开受控、自洽的孤立错误报告世界时,其性能是如何退化的。

原因在于上下文(context)。全新代码在机械意义上是自描述的:约定是明确的,依赖图能装进上下文窗口,没有缺失的内部知识。遗留代码则恰恰相反。关于一个函数可以安全执行什么的实际约束,散落在事故后分析(postmortems)、Slack 讨论串、2017 年的注释以及一位在 2020 年离职的开发者的记忆中。

AI 助手是在“能运行的代码”上训练出来的,而不是在“能存活的代码”上。

实践中的“似是而非”是什么样子的

CodeRabbit 对 470 个开源拉取请求(PR)的分析发现,AI 编写的代码每 PR 产生的问题比人工编写的代码多 1.7 倍。详细分类揭示了真相:逻辑错误增加了 75%,安全漏洞出现的频率是 2.74 倍,I/O 性能问题频繁了 8 倍,并发/依赖错误大约翻了一番。这些类别的问题通常无法通过审查时的惊鸿一瞥发现。它们是那种会静静地潜伏在生产环境中数周的漏洞。

失效模式通常可以归纳为几种典型的模式:

未记录的不变量(Undocumented invariants)。 每个成熟的代码库都有必须在特定条件下调用的函数——例如在特定的初始化序列之后、绝不能从多个 goroutine 调用、或仅在某些配置下使用非空参数。这些不变量不在函数签名中。它们在编写者的脑海里。一个将该函数移动到新模块的 AI 助手看到了干净的代码和类型签名。它看不到那些不变量。

隐式依赖顺序(Implicit dependency ordering)。 服务 A 写入队列。服务 B 从中读取。服务 A 恰好在服务 B 检查之前刷新(flush)。没有人记录这种时间依赖性,因为它一直有效且从未崩溃。重构刷新逻辑的 AI 助手改变了时序。现在,服务 B 在生产环境的负载下,会断断续续地看到空队列。

看起来不像是测试缺口的测试缺口。 遗留代码通常有 60–80% 的行覆盖率,但这几乎毫无意义,因为测试的编写初衷是覆盖代码行而非行为。一个通过了测试套件的 AI 助手,对于它是否保留了系统的实际行为几乎没有验证。Meta 发现,在他们构建预计算系统来记录隐性知识之前,其 4,100 多个流水线模块中只有约 5% 具有 AI 助手可访问的上下文。

基于 DRY 错觉的过度抽象。 当两个函数看起来相似时,AI 助手会合并它们。通常它们相似只是偶然的——底层的领域概念不同,随着需求演变,相似性会发生分歧。合并后的版本充满了条件判断。在 AI 参与度高的项目中,重复代码率从 3.1% 跃升至 14.2%,平均 file size 几乎翻倍。代码看起来“更干净”了,但也更难修改了。

为什么标准的防御措施无法捕捉这些漏洞

最显而易见的反应是:代码审查(code review)。但在遗留代码库中,代码审查在面对 AI 生成的更改时往往会失效。审查者依赖于 AI 助手所缺乏的上下文——AI 助手输入中缺失的那些内部知识,同样也缺失在审查者检查代码时的心理模型中。

在 AI 编程助手普及后的 12 个月里,每个 PR 的事故增加了 23.5%,变更失败率上升了 30%。在 AI 密集的仓库中,静态分析警告增长了 18%,认知复杂度分值上升了 39%。这些指标并不像是一个如宣传般奏效的技术所应有的。

加载中…
References:Let's stay in touch and Follow me for more thoughts and updates