news 2026/10/19 3:28:16

Git + CLI + LLM Agent:自建 open-code-review 自动化审查流程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Git + CLI + LLM Agent:自建 open-code-review 自动化审查流程

1. 为什么我要自己搭一套 open-code-review 流程

团队里代码合并请求越堆越多,人工逐行看 diff 这件事,说实话,早就变成了走马观花。一个中等规模的仓库,一天十几个 PR,每个 PR 几百行改动,指望 reviewer 每一行都认真看,不现实。漏掉的空指针、忘记处理的异常分支、复制粘贴留下的硬编码密钥,基本都是在这种“看一眼就点通过”的节奏里溜进主干的。

open-code-review这个标题,我理解成两层意思:一层是“开放的代码审查”,也就是不依赖某个闭源平台的审查能力,自己用命令行工具加 LLM Agent 把审查流程跑起来;另一层是“把代码审查这件事打开”,让审查规则、提示词、模型选择都透明可控。我最终落地的方案,核心就是Git + CLI + LLM Agent这三件套:用 Git 拿到变更范围,用 CLI 做流程编排,用 LLM Agent 做语义级的审查判断。

这套东西能解决什么问题?最直接的是把“人盯 diff”变成“机器先过一遍,人只看机器标出来的可疑点”。它适合谁?适合那些团队规模不大、没有专门代码质量平台、但又想给合并请求加一道自动防线的开发者。你不需要很深的 AI 背景,只要会基本的 Git 命令、能在终端里跑脚本,就能把这套流程搭起来。下面我把自己踩过的坑、选型的理由、以及可以直接抄的配置,完整讲一遍。

2. 整体设计与选型思路拆解

2.1 为什么是 CLI 而不是插件或平台

一开始我也想过直接用现成的代码托管平台自带的审查功能,或者装个 IDE 插件。但实际用下来,平台自带的能力要么规则固定、改不动,要么把模型调用藏在黑盒里,你根本不知道它为什么标这一行、为什么不标那一行。IDE 插件的问题更明显:它绑死在某个编辑器上,团队成员用的编辑器五花八门,有人用 VS Code,有人用 JetBrains 系列,统一不起来。

CLI 的好处是它站在所有工具的交汇点上。Git 本身就是命令行的,CI 流水线也是命令行的,本地终端更是命令行的。我把审查逻辑写成一个 CLI 脚本之后,本地能跑、CI 能跑、甚至挂到提交钩子里也能跑,一套逻辑三处复用。这就是我选 CLI 作为编排层的根本原因:它不挑环境,也不挑编辑器。

至于 LLM Agent,我把它定位成“审查员的大脑”。传统静态检查工具(比如各种 linter)擅长的是语法层面、格式层面的问题,但像“这个函数在并发场景下会不会有竞态”“这个错误处理是不是把异常吞掉了”这类需要理解上下文的问题,静态工具基本无能为力。LLM Agent 的价值就在于它能读懂代码意图,再结合我给的审查规则做判断。

2.2 审查范围怎么界定:diff 才是核心输入

很多人一上来就把整个仓库丢给模型,让它“看看有没有问题”。这个做法我试过,效果很差:一是 token 消耗巨大,二是模型面对几千行代码会抓不住重点,三是它会把大量已经稳定运行的老代码也翻出来说事,噪音太多。

正确的做法是只审查本次变更。Git 提供了非常干净的变更获取方式,核心就是拿到两个提交之间的 diff。这里有个细节:直接git diff拿到的是工作区和暂存区的差异,而在审查场景下,我们通常要的是“这个分支相对于目标分支改了什么”。所以我用的是三点语法:

git diff origin/main...HEAD

三个点...表示取两个分支的共同祖先到当前 HEAD 的差异,也就是这个分支真正引入的改动。如果用两个点..,会把目标分支上别人新提交的内容也算进来,导致审查范围被污染。这个坑我踩过一次,当时审查报告里冒出一堆跟我这次改动无关的文件,排查了半天才发现是 diff 语法用错了。

拿到 diff 之后,还要做一层过滤。二进制文件、锁文件(比如package-lock.json、yarn.lock)、自动生成的代码,这些都不该进审查队列。我的做法是在脚本里维护一个忽略列表,按文件后缀和路径模式过滤。

2.3 模型选型:不是越贵越好

关于模型,热词里有人问“agent 和 llm 和 ai 模型有什么区别,比如常说的 deepseek 是属于哪个”。这里顺手澄清一下:LLM 是模型本身,比如 DeepSeek、GPT 系列、Claude 系列,它们是“会说话的大脑”;Agent 是在 LLM 外面套的一层调度逻辑,它决定什么时候调用模型、给模型喂什么上下文、拿到结果后怎么处理。所以 DeepSeek 属于 LLM,而我这套 open-code-review 里的审查器属于 Agent。

选型上我的原则是:审查任务不需要最强的模型,需要的是稳定、便宜、响应快的模型。代码审查本质上是“给定 diff 和规则,输出问题列表”,任务边界很清晰,不需要模型做复杂的多步推理。我用过几个不同档位的模型做对比,结论是中等能力的模型配合好的提示词,效果已经足够,成本却只有顶级模型的零头。如果你的团队预算充足,用更强的模型当然更好,但没必要为了审查这一个场景去追最贵的。

3. 核心细节解析与实操要点

3.1 Git 环境准备与常见配置

要跑这套流程,Git 是地基。Windows 上装 Git 我推荐直接下官方安装包,安装时注意几个选项:默认编辑器选你顺手的(我选 VS Code),换行符处理选“Checkout as-is, commit as-is”避免跨平台协作时行尾混乱,其余一路默认即可。装完在终端里跑git --version能出版本号就说明成了。

配置这块,最少要设两样东西:

git config --global user.name "你的名字" git config --global user.email "你的邮箱"

如果是接公司内网的代码托管服务,还要配 SSH 密钥。生成密钥用ssh-keygen -t ed25519 -C "你的邮箱",然后把公钥内容贴到托管平台的密钥设置里。这里有个高频坑:生成密钥后一定要确认 ssh-agent 已经加载了私钥,否则每次拉代码都提示权限拒绝。Linux 和 macOS 上跑ssh-add ~/.ssh/id_ed25519,Windows 上用 Git Bash 执行同样的命令。

还有一个容易被忽略的配置是core.quotepath。默认情况下 Git 会把中文文件名转义成八进制,导致 diff 里文件名显示成一堆\xxx。加上这个配置就正常了:

git config --global core.quotepath false

热词里出现的git -c diff.mnemonicprefix=false -c core.quotepath=false --no-optional-locks这种长命令,其实是某些工具在调用 Git 时临时覆盖配置的写法,理解成“临时关掉前缀提示、关掉路径转义、不加可选锁”就行,日常手动操作不需要这么写。

3.2 用 git worktree 隔离审查环境

审查脚本要读代码、跑 diff,如果直接在开发者的工作目录里操作,很容易和正在进行的开发互相干扰。我的做法是用git worktree开一个独立的工作树专门给审查用。

git worktree add ../review-workspace origin/main

这条命令会在上级目录创建一个review-workspace,检出origin/main的内容,但它和主工作目录共享同一个.git仓库,不占额外空间。审查脚本在这个隔离目录里跑,改什么都不影响主目录。用完删掉:

git worktree remove ../review-workspace

这个技巧在 CI 里尤其有用,因为 CI 环境经常需要同时处理多个分支,worktree 能让它们互不打架。

3.3 提示词设计:审查规则要写死

LLM Agent 的审查质量,八成取决于提示词。我见过太多人只写一句“帮我看看这段代码有没有问题”,然后抱怨模型输出全是废话。问题不在模型,在提示词太模糊。

我的提示词结构是这样的:先给角色定位,再给审查清单,最后给输出格式约束。审查清单是核心,我把它拆成几个维度:

  • 正确性:空指针、越界、未处理的异常、错误的边界条件
  • 安全性:硬编码密钥、SQL 拼接、未校验的用户输入
  • 可维护性:重复代码、过长的函数、魔法数字
  • 性能:循环里的重复查询、不必要的全表扫描

输出格式我强制要求模型返回结构化数据,每条问题包含文件路径、行号、问题类型、严重程度、修改建议。这样脚本才能解析,才能把结果渲染成可读的报告。如果让模型自由发挥,它一会儿写散文一会儿写列表,后续处理会非常痛苦。

提示:提示词里一定要明确“只审查 diff 中新增或修改的行”,否则模型会顺手把上下文里的老代码也点评一遍,噪音会淹没真正的问题。

3.4 上下文窗口的控制技巧

diff 太长会超出模型的上下文窗口,这是绕不开的问题。我的处理策略是按文件切分,逐个审查。一个 PR 改了 20 个文件,我就拆成 20 次调用,每次只喂一个文件的 diff。这样做的好处是每次调用的上下文都很干净,模型注意力集中,输出质量明显更高。

代价是调用次数变多,但审查任务本来就不追求实时性,多花几十秒完全可以接受。如果某个文件的 diff 本身就超长(比如重构了整个模块),我会进一步按 hunk 切分,每个 hunk 单独审查。切分的时候要注意保留足够的上下文行,Git diff 默认带 3 行上下文,我一般调到 5 行,让模型能看清改动前后的逻辑关系。

4. 实操过程与核心环节实现

4.1 从零搭起审查脚本的完整步骤

先说整体流程,我用一张表把各个环节和对应工具列清楚:

环节做什么用到的东西
1确定审查范围git diff 三点语法
2过滤无关文件忽略列表 + 路径匹配
3拆分 diff按文件、按 hunk
4调用模型CLI 发请求
5解析结果JSON 解析
6输出报告Markdown 渲染

第一步,确定范围。脚本接收两个参数:目标分支和当前分支,默认是origin/main和HEAD。

TARGET=${1:-origin/main} CURRENT=${2:-HEAD} git diff "$TARGET...$CURRENT" > /tmp/raw.diff

第二步,过滤。我用一个简单的 grep 排除锁文件和二进制:

grep -v -E '\.(lock|png|jpg|svg|min\.js)$' /tmp/raw.diff > /tmp/filtered.diff

第三步,拆分。按diff --git这个标记切分,每个文件一段:

awk '/^diff --git/{n++} {print > "/tmp/chunk_" n ".diff"}' /tmp/filtered.diff

第四步,逐个文件调用模型。这里我用一个循环,把每个 chunk 的内容拼进提示词模板,发给模型。调用方式取决于你用的模型服务,命令行工具、HTTP 接口都行,核心是把提示词和 diff 一起传过去。

第五步,解析。模型返回的应该是 JSON 数组,每条包含file、line、severity、message、suggestion。解析失败的话,我会做一次重试,把“请只返回 JSON”再强调一遍。

第六步,渲染报告。把解析出来的问题按严重程度排序,输出成 Markdown,高严重度的排最前面。

4.2 参数选择与成本估算

模型调用有两个关键参数:温度和最大输出长度。审查任务我建议温度设成 0 或接近 0,因为我们要的是稳定、可复现的判断,不需要模型发挥创造力。温度高了,同一个 diff 跑两次结果不一样,团队会失去信任。

最大输出长度要留够,因为一个文件可能有好几条问题。我一般设成 2000 token 左右,够输出十几条问题。如果设太小,模型输出到一半被截断,JSON 就不完整了,解析直接失败。

成本估算方面,假设一个 PR 改了 10 个文件,每个文件平均 500 token 的 diff,加上提示词 300 token,单次调用约 800 token 输入,输出约 300 token。10 个文件就是 8000 token 输入、3000 token 输出。按中等价位模型算,一个 PR 的审查成本大概几分钱到一毛钱。一天 20 个 PR,一个月也就几十块钱。这个投入换来的漏检率下降,我觉得非常划算。

4.3 把审查挂进提交流程

本地手动跑脚本容易忘,我的做法是挂一个 Git 钩子。在.git/hooks/pre-push里加一段,推送前自动跑审查,有问题就打印出来提醒,但不强制阻断(阻断太激进,容易引起团队反感)。

#!/bin/bash echo "正在审查即将推送的改动..." bash ./scripts/review.sh origin/main HEAD

记得给钩子文件加执行权限:chmod +x .git/hooks/pre-push。钩子文件默认不会被 Git 跟踪,所以团队协作时要把脚本本体放在仓库里,钩子只做调用。

如果团队用 CI,那就更简单了,在流水线里加一个审查步骤,把报告作为构建产物存下来,或者直接评论到 PR 上。这里要注意 CI 环境的模型凭证管理,别把密钥硬编码在流水线配置里,用环境变量注入。

5. 常见问题与排查技巧实录

5.1 模型输出不是合法 JSON 怎么办

这是最高频的问题。模型有时候会在 JSON 外面包一层解释文字,比如“好的,以下是审查结果:”,导致解析失败。我的处理是三步走:第一,提示词里明确要求“只返回 JSON,不要任何额外文字”;第二,解析前先做一次清洗,用正则把第一个[到最后一个]之间的内容抠出来;第三,如果还是失败,把原始输出和“请修正为合法 JSON”一起再发一次,让模型自己修。

实测下来,加了清洗逻辑之后,解析成功率能到 99% 以上。剩下那 1% 基本是模型服务本身抽风,重试一次就好。

5.2 diff 里出现乱码或文件名转义

前面提过core.quotepath的问题,这里再补充一个:如果 diff 里出现大量^M或者行尾符号异常,多半是跨平台换行符不一致导致的。解决办法是在仓库根目录加一个.gitattributes文件,统一声明文本文件的换行符处理方式:

* text=auto *.sh text eol=lf *.bat text eol=crlf

这样 Git 在检出和提交时会自动做转换,diff 就干净了。

5.3 审查结果误报太多

误报是劝退团队的头号杀手。如果模型天天报一堆“这个变量名不够清晰”这种无关痛痒的问题,大家很快就会无视整个报告。我的应对是分级 + 白名单。严重程度只保留三档:阻断、警告、建议。报告默认只展示阻断和警告,建议级别的折叠起来。同时维护一个白名单,把团队公认的“这样写没问题”的模式加进去,让模型跳过。

另外,提示词里要明确告诉模型“不要对格式、命名风格做评论,这些交给 linter”。把职责边界划清楚,误报能降一大半。

5.4 常见问题速查表

现象可能原因解决方向
解析 JSON 失败模型输出带额外文字加清洗逻辑 + 重试
diff 范围不对用了两点语法改成三点...
文件名乱码quotepath 未关设core.quotepath false
行尾符号异常换行符不统一加.gitattributes
误报过多提示词边界不清分级 + 白名单 + 明确职责
调用超时diff 太长按文件或 hunk 拆分
结果不可复现温度太高温度设为 0

5.5 几个我踩过的坑

第一个坑是在错误的目录跑脚本。有次我在一个子目录里执行审查,Git 找不到仓库根,diff 输出为空,脚本却“成功”返回了空报告,我还以为代码没问题。后来在脚本开头加了git rev-parse --show-toplevel检查,确认在仓库内才继续。

第二个坑是忽略了重命名文件。Git 默认能识别文件重命名,diff 里会显示rename from和rename to。如果脚本只按+和-行解析,重命名会被当成“删了一个文件又加了一个文件”,审查结果就乱了。解决办法是解析时识别 rename 标记,单独处理。

第三个坑是模型对注释里的代码也做审查。有次 diff 里加了一段被注释掉的旧代码,模型煞有介事地分析了半天。后来在提示词里加了一句“忽略注释掉的代码块”,问题解决。

6. 关于这套流程我的一些真实体会

搭这套 open-code-review 流程,前后折腾了大概两周,中间推翻过两次方案。最大的感受是:工具本身不难,难的是让团队愿意用。一开始我追求大而全,想把所有检查都塞进去,结果报告又长又吵,没人看。后来做减法,只保留最高价值的几类检查,报告控制在半屏以内,大家反而开始认真看了。

另一个体会是,LLM Agent 做代码审查,它的定位应该是“辅助”而不是“替代”。它能帮你抓住那些明显的、模式化的问题,但涉及业务逻辑是否合理的判断,还是得人来。把它当成一个不知疲倦、但经验尚浅的初级审查员,心态就对了。

最后分享一个实用的小技巧:审查报告里,我会给每条问题附上“为什么这是个问题”的一句话解释。别小看这一句话,它让报告从“命令”变成了“教学”,团队成员在修问题的同时也学到了东西,长期看比单纯报错有价值得多。这套流程后续还可以往“审查规则版本化”的方向扩展,把提示词和规则当成代码一样管理,每次调整都记录变更原因,这样审查质量本身也能被持续优化。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/19 3:27:57

Linux下用MinGW交叉编译VLC DLL的完整实践指南

1. 项目概述:为什么在 Linux 上用 MinGW 编译 VLC 的 DLL 是个“硬核但值得啃”的活儿VLC 的 DLL 编译这件事,表面看只是把一个开源播放器的动态链接库在非原生 Windows 环境下打出来,但实际操作中,它几乎是一面照妖镜——照出你对…

作者头像 李华
网站建设 2026/10/19 3:27:57

齿轮参数计算脚本化:公法线、跨齿数与变位系数的防错指南

简介:齿轮参数计算小工具是一款面向机械设计、自动化及汽车制造等领域工程师与学习者的实用辅助程序,针对齿轮几何参数计算与建模时频繁涉及的核心尺寸需求,提供快速准确的结果。工具覆盖齿数、模数、压力角、螺旋角、中心距等关键参数&#…

作者头像 李华
网站建设 2026/10/19 3:27:56

CentOS命令合集:高频实用命令与故障排查指南

记得刚接触服务器那会儿,我对着屏幕上黑底白字的终端窗口一脸茫然。后来在CentOS上折腾了几年业务系统,踩了无数坑,才慢慢攒出一套真正顺手、实用的命令清单。所谓“centos 命令合集”,网上能搜到一大堆,但多数要么太零…

作者头像 李华
网站建设 2026/10/19 3:27:37

AI数字员工实战指南:从任务编排到自动化落地

1. AI数字员工,到底是什么角色——以及它为什么值得折腾1.1 从聊天机器人到自主工作者的进化先说一个最直观的变化:以前我们聊AI,默认场景是打开对话框,把问题丢进去,等它吐一段回答,然后你复制粘贴、手动整…

作者头像 李华
网站建设 2026/10/19 3:27:37

基于Python和CNN的蔬菜新鲜度识别:从数据集到答辩的完整实战

“基于python-CNN训练识别蔬菜是否新鲜”这个课程设计/毕业设计题目,近几年在我接触过的不少选题列表里反复出现。很多同学第一反应是:又要调参、又要炼丹,头发怕是不保。但如果你真把它当成一个独立的深度学习项目来做,会发现它的…

作者头像 李华
网站建设 2026/10/19 3:27:08

open-code-review 落地实践:从工具选型到流程自动化的完整指南

1. 从零搭建 open-code-review 的完整思路第一次听到“open-code-review”这个词,很多人会下意识以为它是一个现成的开源工具,或者某个代码托管平台的内置功能。实际上,它更像是一种工程实践理念的具象化表达——把代码评审这件事从“闭门造车…

作者头像 李华