1. 为什么我要自己搭一套 open-code-review 流程
团队里代码合并请求越堆越多,人工逐行看 diff 这件事,坦白讲,早就成了瓶颈。一个中等规模的仓库,一天十几个合并请求,每个请求动辄几百行改动,光靠两三个资深工程师轮着看,眼睛看花了不说,漏掉的边界条件、空指针、资源没释放这类问题,事后复盘时经常拍大腿。我试过纯靠人工加检查清单,也试过只挂一个静态扫描工具,效果都不理想——前者不稳定,后者太死板,理解不了业务上下文。
open-code-review这个方向,说白了就是拿大语言模型当“第一道审阅人”,把代码变更喂给它,让它先过一遍,输出结构化的意见,人再去做最终判断。它解决的不是“替代人”,而是“把人从重复劳动里捞出来”。适合谁来参考?我觉得三类人最合适:一是小团队里没有专职代码审阅角色的开发者,二是想给自己开源项目加一道自动检查的维护者,三是单纯想搞明白 CLI 工具怎么跟 LLM Agent 串起来的技术爱好者。哪怕你之前只听过git、cli这些词,没真正动过手,跟着走也能搭起来。
我先把结论摆前面:整套流程的核心就三块——用 git 拿到变更、用 CLI 把变更和提示词打包、调用 LLM 拿回结构化审阅结果。听起来简单,但每一块都有坑,下面我按自己实际搭的过程,一块一块拆开讲。
2. 整体设计思路与方案选型
2.1 为什么选 CLI 而不是做个网页服务
一开始我也想过做个 Web 界面,点一下按钮就出审阅结果,多直观。但真动手就发现,代码审阅这个动作天然发生在开发者的终端里。你写完代码,git commit之前或者git push之后,顺手敲一条命令就能看到意见,这个路径最短。要是切到浏览器、登录、粘贴 diff,多出来的每一步都会让人放弃使用。
CLI 还有个好处是可组合。它能塞进 git hook,能写进 CI 脚本,能跟git worktree配合在独立目录里跑,不污染主工作区。我实测下来,一个纯 CLI 的工具,团队里推广的阻力比网页小得多,因为大家不用改习惯,只是多敲一行命令。
提示:如果你团队已经在用某些代码托管平台的合并请求功能,CLI 工具依然有价值——它能在提交前就给出反馈,而不是等到请求创建之后。
2.2 LLM Agent 在这里扮演什么角色
这里得先把几个容易混的词说清楚,因为热词里agent、llm、ai模型、embedding全冒出来了。我的理解是这样:
- LLM(大语言模型)是底层能力,负责理解和生成文本,比如常见的那些对话模型。
- AI 模型是个更大的筐,LLM 只是其中一类,图像模型、语音模型都算。
- Agent是在 LLM 之上加了一层“会自己决定下一步做什么”的逻辑,比如它能自己决定去读哪个文件、跑哪条命令。
- Embedding是把文本转成向量,用来做相似度检索,跟“审阅”这件事关系不大,除非你要做代码库的语义搜索。
在open-code-review里,我用的其实是轻量 Agent 思路:不是让模型自由发挥,而是给它固定的输入(diff + 规则)和固定的输出格式(问题列表),它只负责判断和描述。这样可控性高,不会出现模型自己跑去改代码的情况。热词里提到的codex cli、claude cli、trae cli这些,本质都是“把模型能力包装成命令行工具”的不同实现,选哪个看你的账号和网络条件,逻辑是通的。
2.3 数据流设计:从 git diff 到审阅报告
我把整条链路画成文字版,方便你对照:
- 确定审阅范围:是看暂存区、看某次提交、还是看两个分支之间的差异。
- 用
git diff拿到统一格式的补丁文本。 - 对补丁做裁剪和分块,避免超出模型上下文长度。
- 拼接系统提示词,明确审阅规则和输出格式。
- 调用 LLM,拿到 JSON 或 Markdown 格式的意见。
- 在终端渲染结果,或者写入文件供后续处理。
这个设计里,第 3 步最容易被忽略。很多人直接把整个 diff 丢进去,结果要么超长被截断,要么模型注意力被稀释,漏掉关键问题。我后面会专门讲怎么分块。
3. 环境准备与 git 基础配置
3.1 git 安装与最小配置
不管你用 Windows、macOS 还是 Linux,第一步都是把git装好。Windows 上直接下安装包,一路下一步就行,装完在终端敲git --version能看到版本号就成。macOS 一般自带,没有的话装一下命令行工具。Linux 用包管理器装。
装完之后有两件事必须做,否则后面提交记录会很难看:
git config --global user.name "你的名字" git config --global user.email "你的邮箱"这两条是告诉 git 每次提交是谁干的。我见过有人忘了配,结果提交记录里全是默认主机名,团队协作时根本分不清谁改的。
注意:如果你同时用多个代码托管平台,建议给不同仓库配不同的邮箱,用
git config --local在仓库级别覆盖全局配置,避免邮箱泄露或者提交被拒。
3.2 生成并配置访问密钥
要往远端推代码,得先有访问凭证。现在主流做法是生成一对密钥,把公钥贴到托管平台的设置里。生成命令:
ssh-keygen -t ed25519 -C "你的邮箱"一路回车,默认存在用户目录的.ssh下。然后把.pub结尾的公钥内容复制出来,贴到平台的密钥管理页面。配完用ssh -T测一下,看到欢迎信息就说明通了。
这一步的坑在于:私钥绝对不能外传,也不要提交到仓库里。我见过有人把整个.ssh目录不小心git add进去,虽然及时删了,但历史记录里还留着,处理起来很麻烦。建议在仓库根目录放一个.gitignore,把敏感文件排除掉。
3.3 常用 git 命令速查
搭这套流程,下面这些命令你得混个脸熟:
| 命令 | 用途 | 我的使用频率 |
|---|---|---|
git status | 看当前工作区状态 | 极高 |
git diff | 看未暂存的改动 | 极高 |
git diff --staged | 看已暂存的改动 | 高 |
git log --oneline | 看提交历史 | 高 |
git worktree add | 在独立目录检出分支 | 中 |
git commit --amend | 修改最近一次提交 | 中 |
git worktree这个命令值得单独说。它允许你在不切换当前分支的情况下,把另一个分支检出到独立目录。我跑自动审阅时,经常需要对比两个分支,用 worktree 就能在一个干净目录里操作,不影响手头的活。
4. 核心实现:把 diff 喂给 LLM
4.1 提取变更:diff 的三种取法
审阅范围不同,取 diff 的命令也不同。我整理成三种常见场景:
场景一:审阅还没提交的改动
git diff这条看的是工作区和暂存区之间的差异。适合“我改完了,提交前先让模型看一眼”。
场景二:审阅已经暂存的改动
git diff --staged这条看的是暂存区和上次提交之间的差异。适合“我已经git add了,准备提交”。
场景三:审阅两个分支之间的差异
git diff main...feature-branch三个点表示从共同祖先开始比,比两个点更符合“这个分支引入了什么”的语义。做合并请求审阅时,我基本都用三个点。
提示:diff 输出里如果包含大量二进制文件或者自动生成的文件,建议先过滤掉,否则会白白消耗模型额度。可以用
-- .加路径限定,或者用.gitattributes标记。
4.2 分块策略:别让上下文爆掉
模型能吃的上下文是有限的,一个几百行的 diff 加上提示词,很容易就顶到上限。我的做法是按文件分块,再按 hunk 细分。
具体逻辑:先解析 diff,按diff --git切分成文件级块;如果单个文件的改动超过阈值(我设的是 200 行),就按@@开头的 hunk 再切。每块单独送审,最后把结果合并。这样既不会超长,也能让模型聚焦在局部改动上。
分块还有个好处是并行。多个块可以同时发给模型,整体耗时从“串行累加”变成“取最慢的那块”,体验提升明显。我用一个简单的并发池控制同时请求数,避免触发限流。
4.3 提示词设计:让输出稳定可解析
提示词这块我踩过不少坑。最早我写得很随意,结果模型一会儿输出散文,一会儿输出列表,格式完全不固定,后面根本没法自动处理。后来我改成强约束:
- 明确角色:你是一个严格的代码审阅者。
- 明确输入:下面是一段代码变更。
- 明确任务:找出潜在缺陷、风格问题、安全隐患。
- 明确输出:必须是 JSON 数组,每个元素包含文件、行号、严重级别、描述。
给个我实际用的简化版模板:
你是一名资深代码审阅者。请审阅以下代码变更。 只报告确定的问题,不要臆测。 输出格式为 JSON 数组,每个对象包含字段: file, line, severity (high/medium/low), message。 不要输出 JSON 以外的任何内容。 变更内容: {diff}关键是最后那句“不要输出 JSON 以外的任何内容”。加上之后,解析成功率从大概七成提到了九成五以上。剩下那点失败,我在代码里做了容错,用正则把 JSON 部分抠出来。
4.4 调用模型:CLI 工具的接入方式
热词里codex cli、claude cli这些,接入方式大同小异:装好命令行工具,配好访问凭证,然后用管道把提示词传进去,或者用参数指定输入文件。我一般把提示词写到临时文件,再用重定向传:
your-llm-cli --prompt-file prompt.txt > result.json如果你用的是带 Agent 能力的 CLI,注意它可能会自己决定去读别的文件。做审阅这种任务,我建议关掉自动工具调用,只让它做纯文本推理,避免它跑偏去改代码或者执行命令。
注意:有些 CLI 工具默认每次操作都要确认,批量跑的时候会很烦。查一下它的文档,通常有跳过确认的参数,但用之前想清楚风险,别在敏感目录里乱跑。
5. 实操全流程:从零跑通一次审阅
5.1 准备一个测试仓库
我建议先拿一个小仓库练手,别一上来就在生产代码上跑。建个目录,初始化:
mkdir review-demo && cd review-demo git init写一个简单文件,提交一次,然后再改几行,制造出 diff。这样你就有干净的实验环境了。
5.2 写一个包装脚本
手动敲命令太累,我写了个 shell 脚本把流程串起来。核心逻辑:
#!/bin/bash # 1. 取 diff git diff --staged > /tmp/change.diff # 2. 判断是否为空 if [ ! -s /tmp/change.diff ]; then echo "没有暂存的改动" exit 0 fi # 3. 拼接提示词 cat prompt_template.txt /tmp/change.diff > /tmp/full_prompt.txt # 4. 调用模型 your-llm-cli --prompt-file /tmp/full_prompt.txt > /tmp/review_result.json # 5. 渲染结果 cat /tmp/review_result.json这个脚本虽然简陋,但把核心链路跑通了。后面你可以逐步加错误处理、结果美化、严重级别过滤。
5.3 结果渲染与人工复核
模型返回的 JSON,直接cat出来很难看。我写了个小解析器,把每条意见按严重级别着色输出,high 用红色,medium 用黄色,low 用灰色。这样一眼就能看到重点。
但千万别把模型输出当最终结论。我的做法是:模型意见只作为参考,人工复核时重点看 high 级别的,medium 和 low 快速扫过。实测下来,模型对空指针、未处理异常、资源泄漏这类模式化问题识别率不错,但对业务逻辑错误基本无能为力,那部分还得靠人。
5.4 集成到提交前钩子
想让流程真正落地,最好挂到 git hook 上。在.git/hooks/pre-commit里调用上面的脚本,这样每次提交前自动跑一遍。但要注意:钩子失败会阻断提交,所以脚本里对模型调用失败的情况要优雅处理,不能因为网络抖动就让人提交不了代码。
我的处理方式是:模型调用失败时打印警告,但不阻断提交,让人自己决定。毕竟审阅是辅助,不是门禁。
6. 常见问题与排查实录
6.1 模型返回格式不对怎么办
这是最高频的问题。表现是返回一堆解释性文字,JSON 藏在中间。解决办法有两层:一是提示词里反复强调“只输出 JSON”,二是代码里做容错解析,用正则匹配第一个[到最后一个]之间的内容。我实测这套组合下来,基本不会因为格式问题卡住。
6.2 diff 太大导致超时或截断
前面说的分块策略就是解这个的。如果懒得实现分块,至少做个长度判断,超过阈值就提示用户“改动太大,建议分批审阅”。硬塞进去的结果往往是模型只看了前半段,后半段完全没审,比不审还危险。
6.3 CLI 工具找不到或版本不对
热词里unable to locate the codex cli binary这个报错很典型,本质是环境变量没配好,或者装完之后没重开终端。排查顺序:先which your-cli看能不能找到,找不到就检查安装路径有没有加进 PATH,加了还不行就重开终端。Windows 上尤其容易出这个问题,装完记得重启终端甚至重启系统。
6.4 访问凭证失效
表现是调用模型时报鉴权失败。检查凭证有没有过期,有没有配错环境变量。有些工具读的是特定名字的环境变量,名字对不上就静默失败,很坑。建议在脚本开头加一句检查,凭证为空就直接报错退出,别等到调用时才失败。
6.5 常见问题速查表
| 现象 | 可能原因 | 处理方式 |
|---|---|---|
| 返回非 JSON | 提示词约束不够 | 强化格式要求 + 容错解析 |
| 审阅结果为空 | diff 为空或超长被截断 | 检查 diff + 实现分块 |
| 命令找不到 | PATH 未配置 | 检查安装路径 + 重开终端 |
| 鉴权失败 | 凭证过期或变量名错 | 核对凭证 + 检查环境变量 |
| 提交被阻断 | 钩子脚本报错 | 钩子内做失败降级处理 |
7. 我踩过的坑和几条实在建议
第一个坑是过度信任模型。早期我几乎不看模型意见,直接按它说的改,结果有几次它把正确的代码“改错”了。后来我定了规矩:模型意见只做参考,任何改动都要人确认。
第二个坑是忽略成本。每次提交都跑一遍,模型调用次数上去了,费用和耗时都不低。我的优化是只在改动超过一定行数时才触发,小改动人工扫一眼更快。
第三个坑是提示词一成不变。不同项目、不同语言,审阅重点不一样。前端项目关注状态管理,后端项目关注并发和资源,我把提示词做成可配置的,按项目类型加载不同模板,效果明显更好。
最后分享一个实用技巧:把模型返回的意见按文件聚合,同一个文件的问题放一起看,比按严重级别排序更符合审阅习惯,因为人看代码是文件为单位的。这个改动虽小,但团队反馈说体验提升很大。