近期在参与实现本地 AI Code Review 的事情,以下是一些思考输出。感兴趣的小伙伴可以在评论区一起讨论~
引言
从 AI Code Review 的目的上看,我们更多的是需要增强代码的健壮性和稳定性,然后是代码的可读性及保证风格统一,持续推进项目标准化、规范化。
这样既能保证发布后的产品稳定,又能确保项目可以有节奏地、清晰地进行演进,还能让其他同学在 CR 过程中取长补短、查漏补缺,进行自我提升。
目标
那有哪些问题是我们需要在 CR 中找出并必须让同学进行修改的?我认为有以下几种:
- 明显的语法问题、边界问题、异常处理、竞态问题等;
- 潜在的逻辑漏洞或者其他 bug;
- 业务逻辑耦合,可读性和可维护性差!
- 不符合项目规范,代码风格差异大;
- 存在安全漏洞;
- 代码变更风险等级:主要通过静态分析来进行评估,分为深度和广度。
- 深度:比如该代码属于基础函数,被多个其他函数所使用;
- 广度:比如该代码属于公共函数,被多个模块所使用;
- 其实从业务层面来讲,这里也可以 hack 一些风险数据,不同的模块会命中不同的风险等级;
而 CR 本身也应该从两个维度进行:
- 个人本地 CR(AI 主力 - 模型为 GLM 4.6)
- 缺点:高频触发 CR,耗费时间
- 解决:制定一些软链、工具或者直接脚本,将是否触发交给开发人员。但默认需要触发!
- 团队 CR(AI + 人工协作)
应该
在实际过程中,我们应该参考或者遵循以 Spec 驱动的方式来制定 CR 规范。比如通用的 CR 规则 + 项目编码规范和工作流程 + 团队内部知识库积累。
如果并没有项目规范和知识库,我们需要同时推动规范落地和知识积累。从长远收益来看,它是非常有必要的。
这里列举一些比较常规的 Spec:
- 项目编码规范;
- 内部框架或当前使用框架文档;
- 最佳 Code Style 以及优秀的案例文档;
- 遵循 MR(Merge Request)规则,明确规定需要使用 Git 的哪些命令获取正确的 diff 文件和内容;
- 其他
需要了解的前置知识
既然要实现 Code Review,那么就需要知道 Code Review 的时机以及内容。
通常来说,我们一般只有在提交完代码,并发起一个 Merge Request (MR)的时候,才会触发 Code Review。而需要评审的内容:是自开发分支从指定分支(比如 master 或者 main)分叉以来的增量代码(避免把指定分支上最新的变更都算进来)。
可以认为是在本地以 merge-base 为基准的三点比较,这是与 PR/MR 最接近的 Diff 手段。同时还需要启用 -M(重命名检测)和 -C(复制检测),避免混入一些不必要的文件内容到 CR 当中。
对于本地 AI CR 来说,我们把 CR 时机放在 pre-commit 这一环节,那 CR 的内容就是「已提交的内容 + 暂存区」的内容,最简单的实现方式就是:
shell
# 计算变更基线
BASE=$(git merge-base origin/master HEAD)
# 查看差异文件
git diff --name-only --cached "$BASE"
# 查看完整补丁
git diff --cached -M -C "$BASE"
用 merge-base 作为变更基线的什么意思呢?
要知道在做分支比较时,我们不会直接拿 master 的快照来当左侧基线,而是先找到 master 与当前分支的"共同祖先"(通常来说就是分支分叉点),使用它来作为对比起点。这样得到的差异就是------从分支创建以来你真正引入的改动,从而避免被 master 分支上后续 push 进去的代码提交所污染。
用 merge-base 就是获取该分叉点的主要手段,git diff master...HEAD (或者 git merge-base master HEAD) 只会展示------从分叉点到你当前分支头部的增量,在 PR/MR 中基本都采用这种三点(...)语义。
为什么要在 pre-commit 发起 AI CR?
- 很多开发者都有一些"陋习",只管码代码,不自测。这就导致一些很低级的代码问题被提交到仓库;
- 开发任我行,和项目编码规范偏差十万八千里,在整个项目"一枝独秀";
- 能 "run" 不能看,业务耦合度堪称防御性输出典范------谁敢动我的代码试试!
- 「commit-push -> CR -> 修改」流程,往返好几遍才达到发布标准;评审人员也无法保证立即 CR 你的代码,整个流程下来费时费力
综上,我们在 pre-commit 环节借助 AI CR,可以缩短整个评审周期和发布周期。既减少了 commit 次数,又能保证代码质量和功能稳定,还能减轻评审人的压力,何乐而不为?
落地
我们直接使用 Shell 脚本的方式搭配 Claude Code 或者 iflow 来实现本地 AI Code Review。以 iflow 为例:
- 首先需要进行安装
npm install -g iflow; - 然后在项目根目录中的
.husky/pre-commit文件中增加调用脚本- 先设定获取 diff 的脚本,主要是上述内容中 Git diff 的命令;
- 再通过
iflow -y -p "your_prompt"的形势,触发 iflow 终端运行 - 通过"必须通过项"或者 AI 打分的形势,在不符合预期时进行拦截,直至开发者修改通过后方可 commit 成功;
- iflow 报错不可 block 用户 commit 操作;
- 需要提供跳过 AI CR 的能力,防止在一些紧急状况下拦截开发者提交;
- 基于上一条,可以选择继续评审,但将评审结果和代码一起提交至仓库
- 最终的形式是脚本 + AI CR
附加项
- 是否增加 RAG 和内部知识库
这个是扩展项,如果从知识库的角度来进行 Code Review,可以有效地提高准确率(预期)。