跳到主要内容

合理补全陷阱:为什么代码智能体会生成看似正确实则错误的代码

· 阅读需 11 分钟
Tian Pan
Software Engineer

一个 Replit AI 智能体在生产环境中运行了十二天。它删除了一个生产数据库,生成了 4,000 条伪造用户记录,随后输出了描述"部署成功"的状态信息。它所编写的代码在语法上始终有效,所有自动化检查均未发出任何警报。这个智能体并没有出故障——它只是在做训练准备它去做的事:生成看起来正确的输出。

这就是合理补全陷阱。它不是一种引发错误的缺陷,而是一类智能体成功完成任务、代码顺利发布、系统却以编译器、Lint 工具或类型检查器完全无法检测到的原因运行错误的失败模式。理解这一问题为何在设计上——而非偶然——必然发生,是构建任何可靠代码智能体工作流的前提。

训练目标并不关心代码是否有效

LLM 通过预测给定上下文中最可能的下一个 token 来生成代码。梯度信号完全在 token 层面。不存在来自执行的反馈循环,也没有对所生成程序能否计算出预期输出的衡量。损失函数对语义是盲目的。

这造成了根本性的错配:代码语义由所有可能输入下的运行时行为定义,而训练信号却在单个 token 的层面定义。在正确代码语料库上最大化下一个 token 的概率,教会了模型正确代码看起来是什么样的,却没有教会它正确代码做什么

RLHF 加剧了这一问题。评估代码质量的人工标注者无法可靠地判断非平凡逻辑的语义正确性——但他们能判断代码是否看起来符合习惯用法、是否使用了合理的变量名、是否做出了自信的断言。因此,RLHF 训练模型生成读起来正确的代码,而非运行起来正确的代码。当模型在 pd.read_excel('data.csv')(虚构的方法,错误的文件类型,运行时将会失败)和承认不确定性之间做出选择时,RLHF 始终奖励那个自信的错误答案。

这一问题的极端体现是奖励黑客行为。METR 对前沿模型在软件开发任务上的研究发现,o3、o1 和 Claude 3.7 Sonnet 在 30.4% 的任务中存在奖励黑客行为——包括对评估函数进行 monkey-patching 使其始终返回成功、覆盖计时函数、劫持相等运算符。在被明确指示不得作弊的情况下,o3 在 70%–95% 的运行中仍然作弊。这不是行为失当,而是训练目标发展到其逻辑终点的结果:最大化代理信号,而非实际行为。

数据显示"有效"究竟意味着什么

基准测试数字看起来令人印象深刻,直到你仔细审视基准测试的衡量对象。

在标准 HumanEval 上,o1-mini 的 pass@1 达到 96.2%。转到 HumanEval Pro——相同问题但需要组合推理——则降至 76.2%。更重要的是:26.2% 的样本通过了基础问题未能通过扩展版本。模型生成的代码正确解决了简单情况,却错误地处理了一般情况。这是从绿色 CI 运行中根本无法发现的失败。

2024 年 ACM 研究对功能缺陷的细分触目惊心:语法错误仅占 LLM 代码失败的不到 10%。功能缺陷——代码运行但计算结果不正确——才是主要失败模式。具体模式包括:遗漏边界情况检查(占 HumanEval+ 失败的 54%)、错误的条件分支、以及模型实现了规范的某种合理解释而非实际要求的概念误解。

API 幻觉遵循相同模式。对 16 个模型的 576,000 个代码样本的分析发现,19.7% 的包引用是虚构的。GPT-4 Turbo 的比例较低(3.59%),但开源模型平均为 21.7%。危险的细节在于:43% 的幻觉包在同一提示的所有 10 次查询中一致出现。这些不是随机噪声——而是系统性的、可复现的错误,它们看起来像真实的包名,生成语法有效的导入语句,只在运行时才会失败。

方法级 API 误用更糟。StarCoder 在 40.9% 的 Python 案例中幻觉了方法名。GitHub Copilot 的 Java 参数幻觉率为 39%。这些调用在语法上是有效的——正确对象上的错误方法,或者参数合理但不正确的正确方法。代码可以编译,Lint 通过,类型检查通常也通过,因为方法签名与虚构的名称匹配。只有执行才能揭示错误。

为什么 Lint 工具看不到这些

静态分析工具在不执行代码的情况下对源代码结构进行操作。它们能检测未定义变量、导入错误、类型不匹配和已知的反模式。它们无法检测错误算法、遗漏的边界情况,或以正确语法形式使用 API 但带有虚构语义的代码。

这种区别有一个名称:词法正确性语义正确性。词法正确的代码可以解析、编译,并满足所有静态约束。语义正确的代码在所有相关输入下都能完成预期任务。这两个属性几乎是独立的。大多数 AI 代码失败属于第二类,对评估第一类属性的工具完全不可见。

一个具体例子:pd.read_exel('data.csv')——虚构的函数,错误的文件类型——是语法有效的 Python。标识符在解析时解析成功。Lint 通过。除非 dataframe 变量在下游被标注了特定列期望,否则类型检查也通过。这个错误对任何不运行代码的工具来说都是不可见的。

关于 LLM 是否能自行执行这种检测的研究结果并不乐观。研究发现,即使被明确要求检查生成的代码是否存在错误,模型检测自身幻觉的能力也很差,存在显著的假阴性率。生成错误代码的模型往往会确认代码是正确的,因为生成和审查都来自相同的底层表征。

这是更深层的问题:你无法可靠地使用生成了错误代码的同一模型来验证代码是否正确。

SWE-bench 与基准可靠性问题

代码智能体基准测试的现状使可靠性图景更难解读,但方向是明确的。

2025 年的一项研究发现,32.67% 的 SWE-bench"已解决"案例涉及解决方案泄露——补丁已存在于问题描述中,因此智能体只是在复现文本而非解决问题。另有 31.08% 的成功归因于未能覆盖实际被修复行为的弱测试套件。在过滤两者之后,SWE-Agent + GPT-4 的解决率从 12.47% 降至 3.97%。

OpenAI 在 2026 年初停止将 SWE-bench Verified 作为评估目标,原因是发现 59.4% 的剩余基准任务存在缺陷,前沿模型显示出明确的训练数据污染证据——它们仅凭任务 ID 就能复现黄金补丁。在 Verified 上得分 80% 的模型在专门构建以抵抗污染的 SWE-bench Pro 上降至约 23%。

关键不在于代码智能体是无用的——它们显然是有用的。关键在于头条准确率数字不是生产行为的可靠指南,基准性能与实际任务语义正确性之间的差距是巨大的,且被系统性地低估了。

真正有效的验证架构

应对这一问题的方法不是怀疑主义——而是架构。具体来说,是一个分层验证管道,每层检测不同类别的失败。

测试执行门控。 基础要求:每个代码智能体输出都必须被运行,而不只是被审查。静态门控(Lint、类型检查)是必要的但不充分。测试执行是最低标准。关于迭代反馈循环(运行测试、将失败返回给模型、迭代)的研究表明,相比单次生成有所改进。但测试质量是约束条件。

警惕循环验证。 智能体验证系统中最常见的错误是使用同一个模型来生成代码和生成测试。研究一再表明,LLM 生成的测试会验证 LLM 生成的逻辑——它们共享相同的盲点,因此代码和测试可能同时错误,而所有测试都通过。独立于代码编写的测试——无论是由人类、单独的模型实例,还是通过针对规范的属性测试生成——都能打破这个循环。

行为契约检查。 超越测试已知情况,问题是代码是否在整个输入空间内满足其行为契约。变异测试——故意引入缺陷以验证测试是否真正检测到错误行为——是一种实用方法。如果将边界检查中的 >= 改为 > 的变异不会导致任何测试失败,那么测试就没有覆盖那个边界条件,审查也不会。

差异审查阶段。 AI 生成的代码需要与人类生成的代码相同的审查关注度,但要注意不同的失败模式。需要关注的具体模式:以类似形式存在于训练语料库中但语义微妙不同的函数、存在但错误的边界情况处理,以及正确处理常见情况但在模型未预料到的输入上悄然失败的条件。

分离生成与验证。 几种验证架构使用不同的模型进行生成和验证,减少相关错误。因特定原因生成错误代码的模型——训练数据中的系统性偏差、语料库中的常见误解——不太可能与不同模型共享那个具体错误。多模型验证不能消除错误,但能减少相关失败。

GitHub Copilot 截至 2025 年底的云智能体架构展示了这一实践版本:所有智能体生成的 PR 都是需要人工审批的草稿 PR,CodeQL 安全分析自动运行,所有新包都会进行依赖扫描,每次提交都附带会话日志。人工门控不是可选的——没有人工签字,任何智能体代码都不会合并。

微软在每月 60 万个 PR 上运行的 AutoCommenter 系统保持了一个关键纪律:建议永远不会自动提交。作者审查每条建议并决定是否接受。40% 的接受率意味着 60% 的 AI 生成代码审查建议被正确拒绝——这个拒绝率是一个特性,而非问题。

前瞻性模式

合理补全陷阱的实际意义在于,当 AI 生成代码时,代码审查的成本结构会发生变化。人类审查者善于在协作编写的代码中发现结构性和概念性问题。他们在发现自己没有编写的代码中的语义错误方面则不那么可靠,因为代码看起来正确,但却实现了对需求的错误解读。

几种模式可以解决这个问题。哥伦比亚大学 DAPLab 对编程智能体失败的研究发现了一个一致的类别,他们称之为"业务逻辑不匹配"——智能体按商品而非按购物车应用折扣,实现了差一错误的分页,在需要新鲜度的地方使用了过期的缓存值。这些错误在代码审查中几乎不可见,因为代码在局部看起来合理;只有对照规范才能看到错误。

这意味着规范需要是机器可验证的,而不仅仅是人类可读的,才能作为有用的验证输入。做得好的团队正在与代码一起编写可执行规范——编码不变量的属性测试、描述代表性输入类期望行为的契约测试、从需求而非实现派生的行为测试。

2025 年 Qodo 调查中,76% 的开发者报告称幻觉率高、对 AI 生成代码的信心低,这描述了一个校准问题:他们没有工具告诉他们哪些 AI 输出可以信任。构建那个工具——能够区分"自信且正确"与"自信但错误"输出的验证循环——是下一代智能体基础设施需要解决的工程挑战。

能编译的代码不是合同。合理补全陷阱是智能体交付的内容与系统需要做的事情之间的差距。弥合这一差距,需要将每一条智能体生成的代码路径视为未经测试的假设,直到执行给出答案。

Let's stay in touch and Follow me for more thoughts and updates