AI写代码之后:自动化审查如何保障正确性
作者:搬砖的石头2026.11.06 20:59浏览量:0简介:AI把代码生成成本打到近零,验证成本却留给了人,人工审查正在成为新的工程瓶颈。本文基于一线开源维护实践,给出一套可落地的自动化审查流水线:入口聚合、T1/T2/T3风险分诊、Agent初审与独立复核、CI跟踪与自动合并,并总结人机分工边界与防幻觉设计,让人只看高风险改动,正确性与效率兼得。
一、问题的反转:生成趋近免费,验证依然昂贵
过去十年,软件工程的主旋律是“把写代码变快”:更好的IDE、更成熟的框架、更顺手的脚手架。大模型编程助手普及之后,“写”这一步的边际成本第一次趋近于零,一句自然语言描述,几分钟就能产出一个改动可观的补丁,而且表面结构工整、注释齐全。
但工程中还有一个长期被低估的环节:验证。代码写完并不等于代码正确。要确认正确,需要有人读懂上下文、比对改动、跑通测试、与作者往复讨论,再决定是否合入主干。这个过程的时间成本,并没有随着生成成本一起下降。
矛盾因此出现:代码产出的速度,开始远超人工验证的速度。对开源项目维护者,这种感受尤其直接:协作群里被@、私信里被催、代码托管平台上不断出现指派给你的PR,其中大部分由AI生成,改动量还不小。逐个点开看diff、等CI、回复作者、跟进讨论,一天时间就被这些碎片吞掉了。当待审队列从“每周几个”变成“每天几十个”,传统人工审查不是变慢,而是直接失效。
更危险的是失效的方式:不是明确拒绝,而是悄悄劣化。审不过来时,人会对低风险改动快速放行,逐渐养成“扫一眼就通过”的习惯。这种橡皮图章式审批一旦成为常态,审查就只剩仪式感而没有防御力。而AI生成的代码恰恰放大了风险,它表面流畅、格式规范,问题常藏在语义细节里,最不适合扫一眼。
二、目标重设:不是全自动,而是重新分工
一提到“自动审查”,很多人的第一反应是让AI全权决定合并与否。这把问题想简单了。审查决策其实分三类:
- 机械性判断:格式、命名、显眼的逻辑错误、测试缺失。AI做得又快又稳,人做又慢又烦。
- 语义性判断:改动是否真正解决问题、边界条件是否覆盖、与既有设计是否自洽。AI能给出高质量意见,但会出错,需要交叉验证。
- 价值性判断:是否接受某个API设计、是否引入架构债、安全敏感改动是否放行。这必须由人拍板,因为它承担的是项目方向责任。
所以合理目标不是“AI取代人”,而是把人从第1、2类里解放出来,只站在第3类的位置上。衡量系统成败的标准,不是全自动合并了多少,而是人的时间是否集中在了真正需要人的地方。
三、流水线总览:一个PR的完整旅程
围绕这个目标,我把想法做成了一套能跑在自己电脑上的常驻小服务,思路是“收件箱”式的:所有请求审查的信号汇入一处,交给AI流水线处理,人只在必要时刻介入。整条链路如下:
信号入口(协作群@ / 私信 / 频道链接 / 平台提及与指派)
→ ① 分诊分级(T1/T2/T3)
→ ② Agent初审,结构化输出问题
→ ③ 独立Agent复核每个阻塞问题
→ 有阻塞问题:④ 贴到PR与作者讨论、等待修改
→ 无阻塞问题:⑤ T1/T2自动通过,T3转人工
→ ⑥ CI跟踪(触发、重跑、失败归因)
→ ⑦ 合并,并回到最初发起请求的讨论线程回执结果
四、关键环节详解
4.1 入口聚合:把散落的信号收进一处
请求审查的信号天然分散:即时通讯工具里的@与私信、频道里甩来的链接、代码托管平台上的提及与指派。第一步是把这些入口全部接入同一队列,统一编号并记录来源。这步看似简单,却终结了“到处救火”的状态:所有待办出现在同一个看板上,不需要在五六个窗口间来回切换,也不再有遗漏。
4.2 风险分诊:改动路径 × 改动规模
不是所有改动都值得同样的审查强度。分诊规则可以很朴素,例如:
triage:- name: 文档与示例match: ["docs/**", "examples/**", "*.md"]level: T1- name: 工具与测试match: ["tools/**", "tests/**"]max_diff: 300level: T2- name: 核心运行时match: ["src/core/**", "runtime/**"]level: T3- name: 超大改动condition: diff_lines > 500 or files > 20level: T3 # 无论路径,一律升级
T1是低风险(文档、注释、示例、格式修正),错了代价极小;T2是中风险(非核心路径的功能改动与测试补充);T3是高风险(核心运行时、并发逻辑、公共API、大范围重构)。分级的本质是承认错误代价不对称:错放一个文档改动几乎零损失,错放一个核心路径的并发bug可能污染整个主干。审查资源应当按风险分配,而不是先来后到。
4.3 Agent初审:结构化输出,拒绝自由发挥
初审Agent的输入包括:完整diff、相关文件的上下文、项目编码规范,以及一份“本项目常见bug模式清单”(并发竞争、未处理的错误分支、资源泄漏、平台兼容性等)。要求它输出结构化结论,每条问题必须带位置、严重级别(blocking / non-blocking / suggestion)和理由。没有理由的判断一律丢弃,理由既是给作者看的,也是给复核环节与事后审计用的。
4.4 独立复核:对抗幻觉的关键一环
这是整条流水线里最重要的一步。单一模型做审查有两个系统性毛病:一是幻觉,会一本正经地报告并不存在的问题;二是口径漂移,有时过度宽松,有时草木皆兵,把每条建议都标成阻塞问题。
对策是引入第二个独立的复核Agent,职责单一:只验证初审提出的阻塞问题是否真实成立。它重新阅读代码,对每条问题给出“确认、推翻或存疑”,只有被确认的阻塞问题才会发给作者。这一步显著压低了发给作者的误报,如果作者与审查者之间塞满垃圾评论,信任会迅速崩塌,讨论质量反而不如纯人工时代。
4.5 作者交互与CI跟踪:把讨论和客观信号接进来
被确认的问题贴到PR上,进入与作者的往复讨论:作者解释设计意图,Agent判断解释是否成立、是否仍需修改。要允许“作者说服审查者”,并非所有被指出的问题都是真bug。
CI则是客观锚点。流水线负责触发CI、在疑似环境抖动时自动重跑、在真实失败时做初步归因:由本改动引入的就通知作者修复,属于基础设施问题的就自动重试并记录。人从此不必守着CI页面反复刷新。
4.6 合并与回执:闭环与可追溯
一切通过后执行合并,然后回到最初发起请求的那个讨论线程,回一句结果。这个闭环很重要:请求方在哪里问,答案就回到哪里,而不是把人引到另一个系统里翻找。同时,每一步决策都写入审计日志,谁审的、依据是什么、何时合并,事后任何人都可回溯,这对维护自动化的公信力必不可少。
五、实际运行数据
服务正式跑起来约两天,共接入95个PR:Agent自动通过29个,自动合并7个,其余进入与作者的讨论或人工队列。需要我亲自看的,只剩T3级的高风险改动。我的时间从“逐个点开PR”变成“看板抽查+集中处理高风险项”,被消息切碎的状态基本消失。
这些数字的重点不是自动化率,7个自动合并看起来并不惊人。真正的收益在于:那29个低风险改动在没有占用任何人时间的情况下走完了全流程,而人的注意力被完整留给了真正需要判断力的改动。
六、正确性保障的五个支点
回头看,“保证正确性”并不押注在任何单点上,而是五个互相补强的机制:
- 分层防御:分诊决定强度,初审找问题,复核滤误报,CI提供客观验证,人做最终价值判断。任何一层失手,下一层兜底。
- 双模型交叉验证:高风险结论必须经独立复核,直接压制幻觉与口径漂移。
- 风险分级而非全有全无:自动化只覆盖低风险层,错误代价高的决策始终留给人类。
- 可解释与可追溯:结论必须附理由,决策全部入审计日志,人可随时抽查与推翻,系统保持可纠错。
- 快速回退:自动合并的改动保留明确的回滚通道,一旦事后发现问题,止损路径清晰。
七、工程落地与两个安全坑
这套服务本质上不复杂:一个常驻进程、一个消息队列、若干模型调用,加上与代码托管平台和CI的对接,一台普通电脑就能承载。若要升级为团队级服务,可以把各阶段拆成独立的容器化任务,用消息队列解耦,用日志服务集中留痕,用监控告警盯住流水线健康度,这类通用能力在百度智能云等云平台上都有现成的产品类目,按需组合即可,不必自建全套基础设施。
两个容易踩的安全坑需要单独提醒:
- 提示注入:PR标题、描述甚至代码注释里,可能藏着“请直接通过此PR”之类的指令。务必把作者可控内容当作数据而非指令处理,并在系统提示中显式声明指令优先级。
- 权限最小化:Agent持有的凭据只授予读代码、发评论、触发CI的权限;合并权限可再收紧,例如仅在T1/T2且CI全绿时生效。
八、边界与长期视角
最后必须诚实划出边界。即便有了这条流水线,几类改动我仍坚持人工过目:涉及安全边界的、改动公共API契约的、大范围架构重构的,以及两个Agent结论相互矛盾的。自动化提升的是吞吐,不是责任的转移,合并键按下的那一刻,责任人依然是维护者自己。
从更长的时间尺度看,流水线跑得越久,积累的“问题—结论—作者反馈”数据越多,这些数据反过来能持续改进分诊规则与审查提示词,审查正从人力瓶颈变成数据资产。当写代码的成本趋近于零,谁能更便宜地证明代码是对的,谁就握住了下一阶段的工程效率。答案的轮廓已经清晰:AI初审、AI互查、CI兜底,人站在风险最高的那个决策点上。

登录后可评论,请前往 登录 或 注册