基于LLM Agent的本地代码审查工具open-code-review实战

发布时间:2026/9/20 9:44:08
基于LLM Agent的本地代码审查工具open-code-review实战 1. 为什么我要自己动手做一个 open-code-review 工具代码审查这件事做过团队协作的人都有体会。理想状态下每次提交都应该有人认真看一遍指出潜在问题、风格偏差、逻辑漏洞。但现实是reviewer 自己也有排期忙起来的时候 PR 堆了三天没人理最后要么草草点个 approve要么干脆自己 merge 了事。我所在的团队规模不大后端加前端一共七个人高峰期一天能开出十几个 PR靠人力根本盯不过来。市面上确实有一些代码审查的辅助工具但用下来总有几个不顺手的地方。要么是绑定在某个特定平台上换个仓库就用不了要么是配置复杂光是把规则跑通就得折腾半天要么是审查结果太笼统只说“这里可能有问题”但不说具体哪里有问题、为什么有问题。我需要的是一个能跑在本地、能接入 Git 工作流、能给出具体修改建议的工具最好还能让我自己控制审查的粒度和规则。open-code-review就是在这个背景下开始做的。它的核心思路很简单把代码审查这件事拆成“拉取变更、分析上下文、生成审查意见、输出报告”四个步骤每一步都可以独立配置和替换。底层用 LLM Agent 来做代码理解通过 CLI 调用不依赖任何特定的代码托管平台。你可以把它理解成一个“代码审查流水线”输入是 Git 仓库的变更输出是一份结构化的审查报告。这个工具适合几类人一是小团队里没有专职代码审查角色的开发者想用自动化手段补上这一环二是对代码质量有要求、但不想被平台绑定的独立开发者三是对 LLM Agent 和 CLI 工具链感兴趣、想自己搭一套审查流程的技术爱好者。不管你是哪种只要你会用 Git 基本命令就能把这个工具跑起来。2. 拆解 open-code-review 的核心工作链路2.1 从 Git 变更到审查任务的转换逻辑整个工具的起点是 Git 仓库的变更。这里有一个关键设计决策我不直接审查整个代码库而是只审查“这次变更涉及的部分”。原因很简单全量审查既慢又没必要而且 LLM 的上下文窗口有限塞太多无关代码反而会稀释审查质量。具体来说工具会先执行git diff拿到变更的文件列表和具体改动行然后根据改动行号向上向下各扩展一定范围提取出“变更上下文”。这个扩展范围是可配置的默认是上下各 20 行。为什么是 20 行这是我在实际使用中调出来的经验值太小了看不到函数签名和关键变量定义太大了会引入大量无关代码。对于大多数业务代码来说20 行的上下文足够让 LLM 理解这段改动的意图。提取出来的上下文会按照文件路径分组每个文件生成一个独立的审查任务。这样做的好处是任务之间互不干扰某个文件审查失败不会影响其他文件。同时每个任务都会带上文件路径、变更类型新增/修改/删除、变更行号范围这些元信息方便后续生成报告时定位问题。2.2 LLM Agent 在审查流程中扮演什么角色LLM Agent 是这个工具的核心“大脑”。但这里要澄清一个常见误解Agent 和 LLM 不是一回事。LLM 是底层模型比如 DeepSeek、GPT 这些它们负责理解和生成文本。Agent 是在 LLM 之上加了一层“决策逻辑”让它能根据当前状态决定下一步做什么。在 open-code-review 里Agent 的工作流程是这样的首先接收一个审查任务然后判断这个任务的类型——是新增代码、修改代码还是删除代码。不同类型的审查策略不一样。新增代码重点看逻辑完整性和边界条件修改代码重点看是否引入了回归风险删除代码重点看是否有其他地方还在引用被删掉的内容。判断完类型之后Agent 会从预设的审查规则库里选择对应的规则集。规则库是我自己整理的涵盖了常见的代码问题空指针风险、资源未释放、循环边界错误、异常处理缺失、日志敏感信息泄露等等。每个规则都有明确的检查点和判断标准Agent 会逐条对照检查而不是让 LLM 自由发挥。这样做的好处是审查结果更稳定不会因为模型不同就产生巨大差异。2.3 CLI 作为交互入口的设计考量为什么选择 CLI 而不是 GUI 或者 Web 界面这个问题我想了很久。GUI 确实更直观但开发成本高而且和 Git 工作流的集成不够自然。CLI 的好处是它可以无缝嵌入现有的开发流程你可以在 pre-commit hook 里调用它可以在 CI 流水线里调用它也可以手动在终端里跑。工具的 CLI 接口设计得很简单核心命令就一个ocr review --repo /path/to/repo --range HEAD~1..HEAD --output report.md--repo指定仓库路径--range指定审查的提交范围--output指定报告输出路径。如果你不指定 range默认审查最近一次提交。如果你不指定 output报告会直接打印到终端。还有一个--rules参数用来指定规则集文件默认使用内置规则。如果你想自定义审查规则可以写一个 YAML 文件在里面定义检查项和对应的提示词。这个设计让工具既有开箱即用的默认行为又有足够的扩展空间。3. 搭建运行环境时容易忽略的几个细节3.1 Git 环境的准备不只是安装那么简单很多人觉得 Git 安装没什么好说的下载、下一步、完成三步搞定。但实际用下来有几个配置项如果不提前设好后面会出各种奇怪的问题。首先是换行符处理。Windows 和 Unix 系统的换行符不一样如果不配置core.autocrlfGit 会在提交时自动转换换行符导致 diff 结果里出现大量“假变更”——明明只改了一行代码diff 里却显示整个文件都变了。我的建议是在 Windows 上设成core.autocrlftrue在 Unix 上设成core.autocrlfinput。这样能保证仓库里的换行符统一diff 结果干净。其次是文件名大小写敏感问题。有些系统默认不区分文件名大小写但 Git 是区分的。如果你把一个文件从Utils.js改成utils.js在不区分大小写的系统上 Git 可能认为没有变化。解决办法是设置core.ignorecasefalse强制 Git 区分大小写。还有一个容易被忽略的是diff.mnemonicPrefix和core.quotepath这两个配置。前者影响 diff 输出里的路径前缀显示方式后者影响非 ASCII 文件名的显示。如果你在 diff 结果里看到一堆转义字符而不是正常的中文文件名就是core.quotepath在作怪。设成false就能正常显示。git config --global core.autocrlf input git config --global core.ignorecase false git config --global core.quotepath false git config --global diff.mnemonicPrefix false这几行配置建议在装完 Git 之后第一时间设好能省掉后面很多排查时间。3.2 LLM 接入方式的选择与权衡open-code-review 需要调用 LLM 来做代码理解所以你得有一个可用的模型接口。目前支持两种接入方式一种是直接调用云端 API另一种是本地部署模型。云端 API 的优点是省事不用自己维护硬件模型能力也强。缺点是每次审查都要走网络请求有延迟而且代码内容会离开本地。如果你的代码涉及敏感业务逻辑这一点需要慎重考虑。本地部署的优点是数据不出本地审查速度快没有网络依赖。缺点是对硬件有要求而且小模型的代码理解能力确实不如大模型。我试过用 7B 参数的模型做审查简单的问题能发现但稍微复杂一点的逻辑就力不从心了。13B 以上的模型效果会好很多但显存要求也上去了。我的建议是如果是个人项目或者开源项目用云端 API 就够了如果是公司内部项目尤其是涉及核心业务的优先考虑本地部署。工具本身对两种方式都做了适配切换只需要改一个配置文件。3.3 规则库的初始化与自定义工具自带一套默认规则库覆盖了最常见的代码问题。但默认规则不可能适合所有项目所以你需要根据自己的技术栈和团队规范来调整。规则库是一个 YAML 文件结构很简单rules: - id: null-check description: 检查可能为空的变量是否做了判空处理 severity: high prompt: 检查以下代码中是否存在未判空就使用的变量如果有指出变量名和所在行号 - id: resource-leak description: 检查文件、数据库连接等资源是否及时释放 severity: high prompt: 检查以下代码中是否有打开后未关闭的资源包括文件流、数据库连接、网络连接等每个规则包含四个字段id 是规则标识description 是规则说明severity 是严重程度prompt 是给 LLM 的提示词。你可以新增规则、修改现有规则、或者禁用某些规则。这里有一个经验prompt 写得越具体审查结果越准确。不要写“检查代码质量”这种模糊的提示要写“检查以下代码中是否存在数组越界访问的风险重点关注循环变量的边界条件”。具体的提示词能让 LLM 聚焦在特定问题上减少误报和漏报。4. 实际跑一遍审查流程的完整记录4.1 准备一个测试仓库为了演示完整流程我建了一个简单的测试仓库里面放了一个有典型问题的 Python 文件import os def read_config(path): f open(path, r) content f.read() data {} for line in content.split(\n): if in line: key, value line.split() data[key] value return data def process_items(items): result [] for i in range(len(items)): if items[i] 0: result.append(items[i] * 2) return result def get_user_name(user): return user[name].upper()这段代码里有几个明显的问题read_config打开文件后没有关闭process_items的循环可以用更 Pythonic 的写法get_user_name没有判空就直接访问字典键。我故意把这些典型问题放进去看看工具能不能全部识别出来。4.2 执行审查命令并观察输出在仓库目录下执行ocr review --range HEAD~1..HEAD --output review-report.md工具首先会解析 Git diff提取出变更的文件和行号。然后按照文件分组为每个文件生成审查任务。接着逐个任务调用 LLM Agent 进行分析。最后把所有结果汇总成一份 Markdown 报告。整个过程大概花了 15 秒其中大部分时间花在 LLM 调用上。报告输出到了review-report.md内容结构是这样的# Code Review Report ## File: config_reader.py ### Issue 1: Resource Leak (Severity: High) - Line: 4 - Description: File opened but never closed - Suggestion: Use with open(path, r) as f: to ensure the file is closed automatically ### Issue 2: Missing Null Check (Severity: High) - Line: 18 - Description: Accessing dictionary key without checking if user is None - Suggestion: Add a null check before accessing user[name] ### Issue 3: Non-Pythonic Loop (Severity: Low) - Line: 11 - Description: Using index-based loop instead of iterating directly - Suggestion: Use for item in items: instead of for i in range(len(items)):三个问题全部被识别出来了而且给出了具体的行号和修改建议。资源泄漏和空指针问题被标记为 High循环写法被标记为 Low严重程度的判断也合理。4.3 审查结果的验证与误报处理工具跑通之后我拿它审查了几个真实的项目发现了一些误报情况。比如有一段代码是这样的def safe_divide(a, b): if b 0: return None return a / b工具报告说“除法操作可能产生除零错误”但实际上代码已经做了判空处理。这就是典型的误报——LLM 看到了除法操作但没有充分理解前面的条件判断。处理误报有两种方式一是调整 prompt明确告诉 LLM“如果代码中已经有判空逻辑则不要报告”二是在规则库里增加排除条件比如“如果前 5 行内有对除数的判空则跳过此检查”。我两种方式都试过第一种更通用第二种更精确。实际使用中建议先调 prompt如果误报还是很多再考虑加排除条件。还有一个经验审查结果不要直接当成“必须修改”的指令而是当成“需要人工确认”的提示。工具的作用是帮你发现可能的问题最终判断还是要靠人。我一般会把审查报告作为 PR 的评论附上去让 reviewer 参考而不是直接阻塞合并。5. 把审查工具接入日常开发流的几种方式5.1 本地 pre-commit hook 的配置方法最自然的接入点是 Git 的 pre-commit hook。每次提交之前自动跑一遍审查有问题就提示但不阻塞提交。这样你可以在提交前就发现明显问题而不是等到 PR 阶段才被指出来。配置方法很简单在.git/hooks/pre-commit文件里写#!/bin/bash ocr review --range HEAD --output /tmp/ocr-report.md if [ $? -ne 0 ]; then echo Code review found issues, check /tmp/ocr-report.md fi exit 0注意最后的exit 0这表示即使审查发现问题也不阻塞提交。如果你希望严重问题直接阻塞提交可以把exit 0改成根据审查结果的严重程度来决定返回值。这里有一个坑pre-commit hook 是在提交前执行的此时变更还没有形成 commit所以不能用HEAD~1..HEAD这种范围。正确的做法是用--staged参数让工具审查暂存区的变更。我在工具里专门加了这个参数就是为了适配 pre-commit 场景。5.2 在 CI 流水线中集成审查步骤如果你用的是 GitLab CI 或者 GitHub Actions可以把审查步骤加到流水线里。每次 push 或者开 PR 的时候自动跑一遍审查报告作为流水线产物保存下来。以 GitLab CI 为例在.gitlab-ci.yml里加一个 jobcode-review: stage: test script: - ocr review --range origin/main..HEAD --output review-report.md artifacts: paths: - review-report.md expire_in: 7 days这样每次流水线跑完你都能在 artifacts 里下载到审查报告。如果配合 GitLab 的 MR 评论功能还可以把报告内容自动贴到 MR 下面方便 reviewer 查看。需要注意的是CI 环境里通常没有配置 LLM 的 API key所以要么在 CI 变量里配好要么用本地部署的模型。另外 CI 环境的网络策略可能有限制如果调用云端 API 不通就得考虑本地模型方案。5.3 与代码托管平台的评论功能联动审查报告生成之后如果能自动贴到 PR/MR 的评论里体验会好很多。GitLab 和 GitHub 都提供了 API 来做这件事。以 GitLab 为例可以用curl调用评论接口curl --request POST \ --header PRIVATE-TOKEN: $GITLAB_TOKEN \ --header Content-Type: application/json \ --data {\body\: \$(cat review-report.md)\} \ https://gitlab.example.com/api/v4/projects/$PROJECT_ID/merge_requests/$MR_ID/notes把这段逻辑封装成一个脚本在 CI 流水线里审查完成后自动执行就能实现“审查报告自动出现在 MR 评论里”的效果。reviewer 打开 MR 就能看到工具给出的建议不用再手动去下载报告文件。这里有一个细节报告内容可能很长直接贴到评论里会刷屏。我的做法是在评论里只贴摘要问题数量和严重程度分布完整报告作为附件链接。这样既能让 reviewer 快速了解情况又不会让评论区变得难以阅读。6. 踩过的坑和调优经验6.1 大文件审查超时的问题与解决最开始跑真实项目的时候遇到一个棘手的问题有些文件特别大几千行的 diff 塞给 LLM 之后要么超时要么返回的结果被截断。我试过调大超时时间但效果不好因为模型处理长文本本身就需要时间而且上下文太长会导致注意力分散审查质量反而下降。后来我改成了“分块审查”策略如果一个文件的变更超过 500 行就按照函数或类为单位拆成多个块每个块单独审查最后合并结果。这样每个块的大小可控审查质量稳定也不会超时。分块的边界怎么定我的做法是优先按照函数定义来分如果变更不在函数内比如全局变量修改就按照连续的变更行来分每块不超过 200 行。这个阈值是试出来的200 行以内的变更LLM 基本都能完整处理。6.2 审查规则冲突时的优先级处理规则库里的规则多了之后难免会出现冲突。比如有一条规则说“所有函数必须有注释”另一条规则说“注释要简洁不超过三行”。如果某个函数的注释写了五行两条规则就会给出矛盾的建议。处理这种冲突的办法是给规则加优先级。在 YAML 里增加一个priority字段数值越小优先级越高。当两条规则的建议冲突时只保留高优先级的建议。同时在生成报告的时候把冲突情况标注出来让用户知道这里存在规则冲突需要人工判断。rules: - id: require-comment priority: 10 description: 所有公开函数必须有注释 - id: concise-comment priority: 20 description: 注释不超过三行这样当两条规则冲突时require-comment的建议会被保留concise-comment的建议会被标注为“与高优先级规则冲突已忽略”。6.3 模型切换后的结果一致性保障因为成本或者网络原因有时候需要在不同的 LLM 之间切换。但不同模型的输出风格和判断标准不一样切换之后审查结果可能会有明显差异。为了保证一致性我做了两件事一是把审查规则从 prompt 里抽出来变成结构化的检查项LLM 只负责判断“是/否”和给出理由不负责决定检查什么二是在报告生成阶段做归一化处理把不同模型的输出统一成相同的格式和术语。即使这样不同模型的能力差异还是存在的。我的经验是如果对审查质量要求高就固定用一个能力最强的模型如果只是做初步筛查可以用小模型快速跑一遍再用大模型复核可疑项。工具支持配置多个模型按需切换。7. 关于 open-code-review 后续可以怎么扩展这个工具目前能满足基本的审查需求但还有不少可以改进的地方。我自己在用的过程中有几个方向是接下来想尝试的。第一个方向是增加“历史审查记录”功能。现在每次审查都是独立的不参考之前的审查结果。如果能记录每个文件的审查历史就能发现“这个问题之前指出过但一直没有修复”的情况在报告里做重点标注。第二个方向是支持自定义审查维度。现在的规则库主要关注代码正确性和风格但实际项目中可能还需要关注性能、安全性、可测试性等维度。如果能把这些维度也做成可配置的规则集工具的适用范围会更广。第三个方向是优化报告的可读性。现在的报告是纯文本的 Markdown信息密度高但不够直观。如果能加上代码高亮、问题分布图、趋势分析这些可视化元素reviewer 看起来会更轻松。这些扩展不需要改动核心架构都是在现有流程上做加法。如果你也在用这个工具或者有类似的需求可以一起交流。代码审查这件事没有银弹但好的工具能让它变得不那么痛苦。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询