简介:面向编程新手与AI辅助编程实践者,这是一份围绕审查AI生成代码的5个核心检查点的项目资源,覆盖功能完整性、安全隐患、性能优化、可维护性与依赖管理,适用场景从个人代码自查延伸到评审会议与教学培训,帮助开发者建立系统化审查思维,规避盲目信任AI代码的风险。压缩包共3个文件,大小仅7KB,以HTML说明页面为主体,配合.inscode项目配置与.gitignore版本管理文件,轻量易读,可快速在InsCode环境打开并对照练习。已有78人学习下载。资源通过实际案例逐项演示每个检查点的常见问题与改进方向,涵盖安全层面的输入验证与数据加密、性能层面的循环与资源使用优化,并给出实用工具与工作流程建议,让读者既能定位漏测、注入等典型缺陷,也能从架构和依赖角度提升代码质量,实现从被动接受AI输出到主动掌控质量的转变。
1. 先想清楚:AI代码审查到底在审什么
这些年我用AI做过不少代码审查的尝试,踩过很多坑,最后沉淀下来一套相对稳定的用法。先说说背景,我手里维护着一个中等规模的项目,代码量在几十万行上下,团队五个人,每个迭代的MR(Merge Request)少则十几个,多则几十个。人工review的痛苦大家都懂:改了一百行代码,review的人可能只看了关键逻辑,其他全是“LGTM”。不是大家不认真,是真的没有精力把每个diff都吃透。
后来我开始把AI代码审查嵌入流程,用了一段时间,坦白讲效果非常两级分化:用得好,它能在几分钟内找出你漏掉的分支、边界、并发隐患;用不好,它会给你刷屏式地提一堆“建议把这个变量名改得更语义化”这种废话,甚至还会一本正经地推荐一个根本不存在的API。问题不在AI不行,而在我们怎么定义审查的目标、怎么喂上下文、怎么过滤结果。
这篇文章我整理了五个实操要点,都是我真实项目里验证过的。不谈大道理,只讲怎么落地。
2. 要点一:上下文怎么给,决定AI是“瞎猜”还是“真审查”
这是最根本的一点。很多人拿AI审代码,就是把一个文件整段丢进去,然后问“这段代码有什么问题”。这种用法不是完全没用,但效果一定不稳定。原因很简单:代码审查的核心是看“这段代码放进整个系统里,会不会出问题”,而单个文件里根本看不到系统的全貌。
我自己实验下来,给AI喂上下文有三个层次:
- 单文件模式:适合查语法、查明显的逻辑错误、查代码风格,相当于一个带语义理解的linter。
- MR diff模式:把本次改动的所有文件、以及它们之间的调用关系一起丢给AI,让它理解“你这次改动到底动了哪些关联”,这是性价比最高的模式。
- 仓库级模式:把整个项目结构、关键模块、核心数据流都塞进上下文。这种模式最理想,但token消耗非常大,一般跑一趟要好几万token,不适合每次提交都做。
我现在的做法是默认走MR diff模式。具体操作是把git diff保存下来,再加上本次改动涉及的关键函数定义、相关数据结构、依赖关系说明,一起作为提示词输入。这里有个小技巧:在diff前面加一段“项目背景”,用两三句话说明这个服务是干什么的、技术栈是什么、有没有特殊的规范。别小看这几句话,AI对“这是一个给电商订单用的服务”和“这是一个数据处理脚本”的理解完全不同,给出来的建议质量差很多。
另外还有一点要特别提醒:一定要把“只审修改的部分”这个约束写清楚。AI有个毛病,上下文里出现了旧代码,它会忍不住对旧代码也发表意见。你必须明确告诉它“本次审查只关心diff中改动的内容,旧代码的问题不属于本次范围”,否则你的评论区会被陈年旧账淹没。
提示:如果用的是支持多文件的AI编程助手(比如Cursor这一类),可以直接把涉及的文件加进对话上下文,再用“请只审查本次改动”来限定范围。效果比自己手动拼diff好很多,因为它能自动追踪文件间的引用关系。
3. 要点二:审查标准要写在提示词里,不能靠AI自由发挥
第二点,很多AI审查工具默认输出的内容是“AI认为有问题的地方”。但问题在于,AI对“问题”的理解和你团队的标准差距很大。它可能觉得“函数太长”是问题,而你们团队最担心的却是“缓存失效策略有没有考虑并发”。
所以在做AI审查之前,先要花时间写一份审查规则。我把它分成四个档次,对应不同的严重级别:
| 严重级别 | 含义 | 示例 |
|---|---|---|
| P0级问题 | 必现的bug、安全隐患、数据丢失风险 | 空指针、未处理异常导致整个服务崩掉 |
| P1级问题 | 特定场景下会出问题的逻辑缺陷 | 边界条件没考虑、并发场景下的竞态 |
| P2级问题 | 代码质量隐患,后续维护容易踩坑 | 魔法数字、重复代码、接口设计不合理 |
| P3级建议 | 可改可不改的优化点 | 命名可读性、注释是否充分 |
在提示词里,我会明确告诉AI:“请优先找P0和P1级问题,P2可以提但不用展开,P3级别的问题不要提”。这一句话能把无效评论砍掉一大半。
还有一个很实用的做法:把你的历史review经验翻译成规则写进提示词。比如我们这个项目历史上吃过“金额计算用了浮点数”的亏,我就会在提示词里专门加一条:“本项目中所有金额计算必须使用decimal或整数分,如果diff中出现float类型参与金额计算,请标记为P0级问题”。又比如“所有外部接口调用必须设置超时时间”。这些是你团队的血泪史,AI不可能自己知道,但你写进去了,它就能在每个MR里帮你盯着这些红线。
下面是我项目里实际在用的一个提示词模板,可以直接参考:
你现在是一个资深的代码审查专家,正在审查一个[项目类型]的MR。 只审查以下git diff中修改的代码,不要评价未修改的部分。 审查要求: 1. 优先找出P0级问题(致命bug、安全漏洞、数据丢失)和P1级问题(边界条件、并发竞态、资源泄漏)。 2. 本项目特殊规则: - 金额计算一律使用decimal,float视为P0; - 所有外部调用必须设置超时时间; - 新增数据库查询必须确认有索引支持,否则标记P1; - 日志中不得打印用户敏感信息(手机号、身份证)。 3. 对于P2级及以下的风格类问题,只列出条目不要展开。 4. 每个问题的输出格式为:【级别】文件名:行号 - 问题描述 - 修改建议。 5. 如果某个疑似问题你不确定是否真实存在,请在描述末尾标注“待确认”,不要直接下结论。这个模板看起来简单,但它把“AI的通用能力”和“你团队的领域知识”结合起来了。这是AI代码审查真正有价值的地方:它不是一个普通的代码分析器,而是一个不用睡觉的、永远记得你们团队所有规则的Reviewer。
4. 要点三:AI也会编API,验证结果比结果本身更重要
这点我想重点说一说,因为它是AI审查中最容易被忽略、也最致命的坑。AI有一个老毛病——幻觉。它可能会在审查意见里写“建议使用getExecutor().shutdownQuietly()”,但这个方法在你的项目依赖里根本不存在。它在训练语料里见过这个方法,就以为你的代码里也有。
我吃过一次大亏。某次AI在评论里建议我用某个框架的“官方推荐写法”,我没验证就直接改了代码,结果编译都过不了,CI直接挂了。浪费了整整一个上午,最后还是回滚了。从那以后我立了一个规矩:AI审查输出的每一句“应该改成xx”,都必须拿着去代码库里搜索验证一遍,确认这个API真的存在、这个写法真的可用,才允许上MR。
不是说AI的建议不能用,而是要建立一个三层过滤机制:
- 第一层:自动过滤。对于AI输出中提到的API、类名、函数名,写一个脚本去项目源码和依赖库里搜索,找不到的直接标记为“疑似幻觉,待人工确认”。
- 第二层:静态检查过滤。让AI审查通过的代码再过一遍现有的linter和编译器。如果编译器报错了,无论AI说得多么头头是道,以编译结果为准。
- 第三层:人工抽检。每个MR里,AI标记的P0和P1问题,要求必须由人工确认后再走流程。P2及以下的可以自动忽略。
另外还有一个技巧:让AI自己给自己纠错。我会在审查完之后追加一句:“以上你的建议中有哪些是你不能100%确定在当前代码库中存在的API?请单独列出来。”AI在知道后续要“自己交代”的时候,反而会更谨慎一些,幻觉率会下降不少。这个现象我不确定是模型本身的机制还是心理作用,但实测下来确实有效。
顺带提一下,现在也有些团队用“多引擎交叉验证”的方式:用两个不同的模型(比如Claude和GPT系)分别审查同一份diff,只采纳两边都报的问题。这种方式能显著降低幻觉率,但成本也会翻倍。如果你们项目预算充裕,可以试试。如果预算有限,就老老实实用“静态检查兜底+人工抽检”这套方案。
注意:AI审查永远只能作为“提词器”,不能作为“裁判”。最终裁决权必须在编译器和人类手上。我见过一些人把AI审查意见当作圣旨,直接照单全收,最后代码被改成了一坨“看起来很先进但跑不起来”的东西。记住,AI的建议是启发式的,不是事实。
5. 要点四:把AI放进流程,而不是替代流程
AI审查怎么嵌入到开发流程里,这个设计得好不好,直接决定了团队愿不愿意用。我最早是让开发自己拿AI工具审,结果就是有的人用、有的人不用,用了的标准也不一样,最后review还是回到了人工全看的状态。后来我把AI审查做成了流水线上的一个固定环节。
我们现在的流程是这样的:
- 开发者把代码推到远程分支,创建MR。
- CI里触发一个自动任务,拉取diff,调用AI审查,生成审查意见。
- 审查意见以机器人的身份自动评论在MR下面,并且把P0/P1级问题关联到MR的Thread上。
- 开发者在机器人评论下面逐一回复“已修复”或“这是误报”,这个回复记录会保留下来。
- 最后人工Reviewer只需要关注AI标记的问题+没被AI覆盖到的部分(比如整体架构、接口设计审不出来的东西)。
这个流程跑起来之后,人工review的时间大概省了六成左右。原来一个MR可能要花40分钟看,现在大概15分钟就搞定,主要集中在确认AI意见是否成立和看架构层面的东西。
这里涉及一个时间点的问题:AI审查应该放在人工review之前还是之后?我们试过两种方案,最终选择放在人工review之前。原因很朴素:AI先过一遍,把那些低级问题都挑出来改掉,人工再看的时候diff已经干净很多,重复劳动少了。如果放在人工review之后,AI提的问题人工早就提过了,价值感就很弱。
还要注意CI里跑AI审查的超时时间。我们最早用的是同步方式,MR创建后阻塞等待AI审查完再放行,结果高峰期排队排队,一个MR要等十分钟才能收到意见,开发都在骂。后来改成异步——MR创建后先放行,AI审查完再以机器人评论的形式把意见贴上来,开发手头的活可以继续干,不用干等。两者体验差距非常大。除非你们要求“审查不过不能合入”这种强约束,否则建议用异步。
设置超时时间还有一个附带的好处:避免AI审查成为CI的瓶颈。有一次上游模型服务波动,请求全部超时,我们的CI任务也跟着集体失败。后来我在代码里对所有外部模型的调用统一加了18秒超时,超时直接跳过该步骤并在MR里留言“本次AI审查暂不可用,请人工review注意”,这样就不会因为第三方服务抖动而阻塞整条流水线。
6. 要点五:算清成本账,别让AI审查变成吞金兽
聊AI审查,必须把成本问题摆到桌面上。这一块很多文章不提,但如果你真要在项目里长期跑,成本一定绕不开。
成本主要分两部分。首先是token消耗。现在主流的大模型收费是按token算的,输入和输出价格不一样。你可能在界面上看到的是“credits”或者“积分”,但本质上就是token的计量体系。一次MR审查大概消耗多少token呢?我拿我们项目的一个中等规模MR(改动500行,涉及8个文件)实测过:
- 输入:你把diff、项目背景、审查规则都拼进去,大概6000~8000 token。
- 输出:AI的审查意见,如果限制它只提问题不展开,大概1000~2000 token。
- 合计:单次审查约8000~10000 token。
如果一天有20个MR,按当前主流模型的价格估算,一天的token成本大概在两到三美元左右,一个月五六十美元。这个账我觉得是划算的,因为它省下的是至少两个开发每天各一小时的人工review时间。但如果你们团队一天有上百个MR,或者每次审查都开了仓库级模式,成本就会快速增长。仓库级模式一次可能吃掉5万到10万token,只适合在关键模块变更的时候用,不能默认开。
除了token成本,还有两个容易被忽视的隐性成本:
- 维护审查规则的投入。你写审查规则、根据漏报误报去调整规则,这个时间成本其实比token更贵。但这类成本是一次性投入,规则体系搭好之后,边际成本很低。我们团队大概花了两周时间把规则库从无到有建立起来,之后每周只花半小时微调。
- 误报带来的沟通成本。AI提了20条意见,有15条是误报,开发得一个个去回复“误报”,这也是时间。所以我在提示词里强调“不确定的就标注待确认”,并且把P3级意见直接禁掉,就是为了把误报率压下去,减少这种沟通摩擦。
最后给一个度量建议:别只看AI审出了多少问题,要看每天人工review时平均每个MR花的时间有没有下降。这个指标才能反映AI审查的真实价值。我们跑了一个多月,平均每个MR的人工review时间从40分钟降到了15分钟左右,同时线上bug率没有上升,这才说明这套流程是真的可用的。
如果希望进一步压缩成本,可以尝试对MR分级:大改动的核心模块用强模型做全量审查,小改动或者文档类改动,用便宜的小模型或者干脆静态检查工具(比如Semgrep这类)过一遍就行。给不同风险等级的MR分配不同的审查预算,整体成本能再降不少。
7. 常见问题与排查技巧实录
最后整理一下我实际使用AI审查时碰到的典型问题和对应的处理方法。这些问题如果你也跑AI审查,大概率会遇到。
问题一:AI审查太慢,提交后迟迟不出结果。
我们之前也遇到过,后来定位下来主要两个原因:一是提示词太长,每轮请求处理时间自然变长;二是同步阻塞模式导致排队。解决方式是改成异步评论,再把超时时间卡死,从“无条件等待”改成“超时降级”。处理后单条审查请求的耗时稳定在30秒以内,大部分场景下甚至不到10秒。
问题二:AI老是提交风格类废话评论,真正的问题反而没提。
这是提示词里没有明确“优先级”导致的问题。AI默认会把所有觉得“不够好”的东西都列出来,而不是按“严重度”排序。把“P0/P1优先,P3禁止”写进系统提示词,并且给一个输出模板约束格式,废话评论会显著减少。我见过有些团队直接在提示词里写“如果某条意见的级别低于P2,请不要输出”,效果更激进,副作用是可能漏掉一些还算有价值的小优化建议。
问题三:AI意见很多,但不知道哪些可信。
给AI的每条意见打上“待确认”标签是一个解决办法。更进一步,可以对AI评论做二次扫描:把所有评论里涉及的具体API、函数名提取出来,在代码库里跑一遍搜索。搜不到的自动标记为“疑似幻觉”,人工review时优先跳过。这个思路其实很朴素——AI说谎的时候往往在“编造引用”,而代码库里的真实符号是不会骗人的。
我用一个简单的脚本来做这件事,核心逻辑是正则+文件搜索,类似这样:
import re import subprocess comments = [] # AI审查意见列表,每个元素包含文件名、行号、描述 # 从意见中提取疑似API名称 pattern = re.compile(r'\b([a-zA-Z_][a-zA-Z0-9_]*)\s*\(') for c in comments: for match in pattern.findall(c['description']): # 在项目源码中递归搜索该API是否存在 result = subprocess.run( ['grep', '-rn', match, 'src/'], capture_output=True, text=True ) if result.returncode != 0: print(f"可疑API: {match} 在源码中不存在,来自 {c['file']}:{c['line']}")这只是个示例,实际跑的时候还要处理跨文件引用、动态调用等情况,但思路就是这个:AI说的每个具体引用,都让它在代码里找到落点才算数。找不到落点的,别问为什么,先标为可疑。
问题四:AI没有审出来团队规则里明确禁止的代码。
这类漏报比误报更危险,因为误报你还能看到,漏报你是不知道的。处理方式是把团队规则既写进AI的提示词,也写进一个自动化的静态规则文件(比如Semgrep或者eslint自定义规则)。AI负责理解语义层面的问题,静态规则负责守住硬性红线。两个工具互相兜底。测试下来,硬规则类的漏报率大幅下降,因为这类问题本来就不该依赖AI来发现。
| 常见问题 | 主要排查方向 | 推荐解法 |
|---|---|---|
| 审查结果慢 | 同步阻塞、提示词过长 | 改异步模式,限制提示词长度 |
| 废话评论太多 | 没有定义严重级别 | 按P0~P3分级并写入提示词 |
| 意见不可信 | 幻觉API、过度自信 | 代码库搜索验证,加“待确认”标签 |
| 漏报团队规则 | 规则没进上下文 | AI规则+静态红线规则双通道 |
8. 最后说点实在的
总有人问我“AI代码审查到底能不能替代人工review”。目前我的判断是:不能完全替代,但它可以帮你省掉大量重复劳动。AI擅长的是在几百行diff里找出你视觉盲区里的边界条件,擅长在你凌晨两点提交代码的时候还保持清醒的状态,一条条把你定的规则过一遍。但这些事情都是“执行层”的,最终这个改动合不合入、架构上有没有问题、未来维护成本高不高,还是要人来判断。
我个人实操中最大的体会是,AI代码审查工具本身不是重点,重点是你怎么定义标准和怎么验证结果。定义标准靠的是你自己踩坑踩出来的规则,验证结果靠的是静态分析和人工抽检。这两个环节做好了,AI才能从一个“会说话的linter”升级成“团队的第二双眼睛”。
最后再分享一个小技巧:如果你们团队刚准备引入AI审查,不要一上来就全量铺开。挑一个改动比较频繁、历史上有过线上事故的模块,先跑两周。把这两周内AI提的意见全部存档,周末花半小时看一下哪些是有效的、哪些是废话、哪些是你希望它能提但没提的。有了这份清单,再完善规则、调整提示词,然后在全项目铺开。这样推进的阻力会小很多,团队接受度也会高很多。
本文还有配套的精品资源,点击获取