
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 喂给 LLM4.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. 我踩过的坑和几条实在建议第一个坑是过度信任模型。早期我几乎不看模型意见直接按它说的改结果有几次它把正确的代码“改错”了。后来我定了规矩模型意见只做参考任何改动都要人确认。第二个坑是忽略成本。每次提交都跑一遍模型调用次数上去了费用和耗时都不低。我的优化是只在改动超过一定行数时才触发小改动人工扫一眼更快。第三个坑是提示词一成不变。不同项目、不同语言审阅重点不一样。前端项目关注状态管理后端项目关注并发和资源我把提示词做成可配置的按项目类型加载不同模板效果明显更好。最后分享一个实用技巧把模型返回的意见按文件聚合同一个文件的问题放一起看比按严重级别排序更符合审阅习惯因为人看代码是文件为单位的。这个改动虽小但团队反馈说体验提升很大。