Skip to content

AI 生成代码的质量保障 ​

标签
AI/agent/代码质量
字数
2844 字
阅读时间
11 分钟

问题的形状 ​

AI 一次能产出大量代码,正确性怎么保证。真正的难点有两个结构性事实:

一、生成速度与验证速度不匹配。 Agent 30 秒能产出 500 行,人读 500 行要 5 分钟。不细看就接受,等于把一批自己没理解的决策塞进代码库。

二、验证手段本身可能同源。 代码是 AI 生成的,再用同一个模型同一段上下文去 Review,它复用的是自己那条推理路径——生成时没意识到的问题,审的时候同样意识不到。

同源盲区与规避 ​

标准做法是让生成和评审走不同的路径:

   标准做法是让生成和评审走不同的路径

   ┌──────────────────────────────────────────────────────────┐
   │ 生成侧                                                    │
   │   Model A                                                 │
   │   └─ 原始 Context(含生成时的所有假设)                     │
   └──────────────────────────┬───────────────────────────────┘
                              │ 产物:代码
                              ▼
   ┌──────────────────────────────────────────────────────────┐
   │ 评审侧(三个可调维度)                                      │
   │   不同模型      换家族,避免同家族的自我偏好                  │
   │   独立 Context  清空会话,不让评审者继承生成时的假设          │
   │   不同 Prompt   评审提示不复述生成提示里的前提                │
   └──────────────────────────┬───────────────────────────────┘
                              │
                              ▼
   更可靠的独立信号,按可信度分三级
     ① 集成模型之间的分歧 —— 分歧本身携带信息:
        两个不同家族的模型都认可,比同一个模型自评可信
     ② 检索验证 —— 对照外部事实,不依赖模型内部表示
     ③ 确定性检查 —— 根本不需要判断:编译、类型、测试是二值的
        └─ 最强的一级,下一节单独讲

   为什么同源不可信,机制层面也解释得通
     自回归模型对自己生成的文本困惑度更低,
     而困惑度低又往往被当作流畅度、质量的信号 ——
     「读起来顺」被误当成了「写得对」。
     用 LLM 当验证器并不能带来独立信号,
     回路里只是多了一个同类型的过度自信模型。

三个可调维度:

  • 不同模型(换家族,避免同家族的自我偏好)
  • 独立 Context(清空会话,不让评审者继承生成时的假设)
  • 不同 Prompt(评审提示不复述生成提示里的前提)

这不是凭感觉的经验。在 LLM Evaluation 与反馈闭环 里,自我偏好偏差有实测数据:模型对同家族输出的偏好率在 51.4%–86.2% 之间——当测试数据与评估者来自同一模型时,排名会被系统性抬高。

机制层面也解释得通:自回归模型对自己生成的文本困惑度更低,而困惑度低又往往被当作流畅度、质量的信号——「读起来顺」被误当成了「写得对」。

同样地,用 LLM 当验证器并不能带来独立信号——回路里只是多了一个同类型的过度自信模型。更可靠的独立信号来自:

来源为什么独立
集成模型之间的分歧分歧本身携带信息——两个不同家族的模型都认可,比同一个模型自评可信
检索验证对照外部事实,不依赖模型内部表示
确定性检查根本不需要判断——编译、类型、测试是二值的

第三种是最强的,下面单独讲。

两类约束的可靠性不在一个量级。

   做法                                性质          可靠性
   ────────────────────────────────────────────────────────────────
   提示词里要求「遵守规范」              概率性合规    通过率是统计量
   接入违反即阻断的 Linter              确定性约束    该类错误不可能进入主干
   提示词里要求「小步提交」              概率性合规    取决于模型当次表现
   CI 门禁要求构建与测试通过             确定性约束    不通过就合不进去

   类型检查、测试套件、权限边界、审批门控都属于第二类。
   接进来之后,那一类错误的发生概率不是降低,是归零。

   为什么对策只能是结构性拦截
     三组实测数据(Veracode / CodeRabbit / GitClear)指向的都是
     「生成这个动作本身的系统性倾向」,而不是「某次生成写错了」。
     └─ 所以不能是「要求 AI 更认真」,只能是结构性拦截
     └─ Veracode 那条「多轮测试都没改善」尤其关键:
        它不是等待模型升级就能解决的问题

确定性约束优先 ​

比「让 AI 认真 Review」更可靠的是把错误在结构上关掉。这是 Harness Engineering 控制层的核心:

做法性质可靠性
提示词里要求「遵守规范」概率性合规通过率是统计量
接入违反即阻断的 Linter确定性约束该类错误不可能进入主干
提示词里要求「小步提交」概率性合规取决于模型当次表现
CI 门禁要求构建与测试通过确定性约束不通过就合不进去

类型检查、测试套件、权限边界、审批门控都属于第二类。接进来之后,那一类错误的发生概率不是降低,是归零。

问题有多严重:三组实测数据 ​

这一节是「为什么值得建门禁」的量化依据(详细来源见 AI Coding 工作流):

来源发现
Veracode 2025(测 100+ LLM)45% 的 AI 生成代码样本引入 OWASP Top 10 漏洞;AI 代码的 XSS 防护失败率 86%;Java AI 代码失败率 70%+。而且这个比例从 2025 到 2026 初多轮测试都没改善
CodeRabbit 2025-12(470 个开源 PR)AI 合著代码的「major」问题多 1.7 倍,安全漏洞多 2.74 倍,配置错误多 75%
GitClear(纵向分析)重构占比从 25% 降到 10% 以下,代码重复约 4 倍,churn(写了又被快速改掉或删除)接近翻倍

GitClear 那组最该被读进工程直觉:重构占比腰斩 + 重复翻倍 + churn 翻倍,说的是同一件事——代码在被生成,但很少被整理。

这条直接决定了门禁该拦什么:上面三类问题都是「生成这个动作本身的系统性倾向」,而不是「某次生成写错了」。所以对策不能是「要求 AI 更认真」,只能是结构性拦截——也就是下一节。

Veracode 那条「多轮测试都没改善」尤其关键:它不是等待模型升级就能解决的问题。

质量门禁链路 ​

完整的门禁链路:

   完整的门禁链路

   AI Coding
        │
        ▼
   AI Review          ┐
        │             │ 这两级是自动的
        ▼             │
   Human Review       ┘ ← 成本瓶颈在这一级
        │
        │  人工评审关注四个面:架构 / 数据流 / 调用链 / 注释
        ▼
   Build
        │
        ▼
   Test
        │
        ▼
   Fix ──▶ 回到 AI Coding,或直接提交

   瓶颈在最下游,所以置信度分层那套降级路由在这里同样适用:
   把「AI 自己也不确定」的部分优先推给人,其余自动放行。

   门禁要分层,而且每层都要按切片看 —— 见下一节

人工评审关注四个面:架构、数据流、调用链、注释。

这条链路的成本瓶颈在最下游——人工评审。所以 置信度分层与 Human-in-the-loop 那套降级路由在这里同样适用:把「AI 自己也不确定」的部分优先推给人,其余自动放行。

门禁要分层,而且每层都要按切片看 ​

参照 LLM Evaluation 与反馈闭环 里那条实证——注入回归后聚合通过率只动 1.7–5.9 个百分点,而受影响切片掉了 25–91 个百分点——门禁的设计要满足两条:

一、每层各测一个面,全部通过才放。 混在一起测会得到一个「综合分」,而综合分会掩盖单点崩塌:

层测什么
工具使用是否调了正确的工具、参数对不对
推理质量中间步骤是否成立
输出质量最终结果
安全性策略与合规
延迟与一致性性能与稳定性

二、每个指标按有意义的切片检查(按模块、语言、调用路径切)。「总体通过率没问题」和「退款流程只在分期付款时失败」可以同时成立。

需要人工兜底的原因有量化上限 ​

SWE-bench Pro(1,865 个任务、41 个专业仓库、平均需改 107 行、跨 4 个以上文件)上最强模型的解决率约 23%。

METR 的随机对照实验(arXiv:2507.09089)——16 名资深开源开发者、246 个真实任务、在他们平均工作 5 年的成熟项目里——用 AI 工具平均慢 19%。

这两个数字说明当前模型在复杂仓库里的可靠边界在哪:能独立完成的是少数,而在开发者已经熟悉的代码库里,AI 甚至可能拖慢。

SWE-bench Pro 的那组数字转引自技术博客,未回溯原始报告,标为待验证。**METR 那条已核到一手来源**(`arXiv:2507.09089`,2025-07),数据与 [[15-AI Coding 工作流|AI Coding 工作流]] 里的一致。

另外要留意基准时效:SWE-bench Verified 已于 2026 年 2 月被 OpenAI 弃用(污染顾虑),所以「SWE-bench 上多少分」这类引用需要指明具体是哪个变体。

量化基线 ​

性能优化必须给出可比的数字。没有基线,就无法判断一次生成是改进还是回退。至少覆盖三组:

  • 分位数:改动前后的 P50 / P90 / P99——只看均值会掩盖长尾
  • 关键路径:首屏耗时、图片加载耗时、主线程阻塞时间
  • 资源:内存占用、GC 次数、FPS

AI 生成代码的性能问题通常出在整体架构选择上,不会只退化在某个单点,所以「打过分耗时日志、体感变快」这种描述不足以支撑结论。

相关 ​

参考 ​

贡献者 ​

文件历史 ​