news 2026/10/19 17:05:11

开源 CLI 代码审查工具:基于 Git 与本地 LLM 的轻量级自检方案

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
开源 CLI 代码审查工具:基于 Git 与本地 LLM 的轻量级自检方案

1. 项目概述:一个真正能落地的开源代码审查 CLI 工具

“open-code-review”这个名字乍看平平无奇,但拆开来看——open不是指“开源”,而是指“开放上下文”;code-review也不是走形式的 PR 点赞,而是让大模型真正理解你改了什么、为什么这么改、有没有踩坑。它不是一个玩具项目,而是一套面向真实开发流的 CLI 工具链,核心目标就一个:在 git commit 前、push 之前、甚至 IDE 编辑过程中,用 LLM 做一次轻量但有上下文的“自检式代码审查”。我从去年开始在三个团队内部试用这个模式,不是把整个仓库丢给模型读,而是精准截取git diff --cached的变更块 + 当前文件的局部上下文(前后 20 行)+ 提交信息草稿,喂给本地或可控 API 的 LLM,生成带依据的 review comment。关键词里反复出现的CLI、git、LLM、code review全部不是虚词——它必须命令行可触发、能嵌入 pre-commit 钩子、能识别 git 分支差异、能规避密钥泄露风险,且不依赖任何闭源服务。适合两类人:一是每天要写 5+ 个 commit 却没时间细读自己代码的中高级开发者;二是技术负责人想在不增加流程负担的前提下,把 code review 的“第一道防线”前移到开发者本地。它不替代人工 review,但能把 30% 的低级错误(空指针、未处理异常、硬编码 token、API 调用漏 await)挡在 CI 之前。实测下来,接入后团队 PR 中被人工指出的“基础规范类问题”下降了 62%,reviewer 节省出的时间更多用于架构讨论和边界 case 探讨。

2. 整体设计思路与方案选型逻辑

2.1 为什么不做 Web UI 或 IDE 插件?——回归 CLI 的本质价值

很多人一听到“LLM + code review”,第一反应是做个 VS Code 插件或者网页平台。但我坚持从 CLI 入手,原因很实际:CLI 是唯一能天然融入现有开发工作流、零学习成本、且权限可控的入口。Web UI 需要部署、鉴权、跨域;IDE 插件要适配多版本、处理编辑器生命周期、可能拖慢响应;而open-code-review只需要你在终端敲一条命令,它就能立刻读取当前 git 状态、提取 diff、调用模型、输出结构化建议——整个过程不打开浏览器、不弹窗、不申请额外权限。更重要的是,CLI 天然支持管道(pipe)、重定向(>)、脚本集成(比如写进.husky/pre-commit),这是其他形态无法比拟的工程友好性。我试过把同类功能做成插件,结果发现:80% 的用户只在“第一次安装时点开过一次”,后续全靠命令行触发。所以设计之初就定下铁律:所有能力必须可通过ocr(open-code-review 的缩写) 命令直接调用,UI 是可选附加层,不是主干。

2.2 模型调用策略:本地优先,API 降级,绝不裸奔

热搜词里高频出现“密钥泄露”“llm 代理地址”“prompt injection”,这恰恰是我们设计模型层时最警惕的红线。open-code-review的模型调用不是简单封装curl,而是分三级策略:

  • L1:本地小模型兜底(默认启用)
    内置Phi-3-mini或TinyLlama的 GGUF 格式量化模型(< 2GB),通过llama.cpp运行。它不擅长写诗,但足够识别if (user == null) return;后面是否跟了user.getName()这类空指针链。好处是:0 网络请求、0 密钥、0 数据出域,连公司内网断开都能跑。

  • L2:可控 API 网关(需显式配置)
    支持 OpenRouter / Ollama / 自建 vLLM 服务,但强制要求用户自行填写 base_url 和 API key,并在首次使用时进行“密钥安全测试”:工具会模拟构造含GITHUB_TOKEN=的字符串输入,验证模型输出是否包含该 token 字符串——若包含,则立即阻断调用并告警。这是防止 prompt injection 导致密钥回显的核心机制。

  • L3:禁用远程模型(企业版默认)
    在~/.ocr/config.yaml中可设disable_remote: true,彻底屏蔽所有 HTTP 调用,只走本地模型。我们给某金融客户部署时,就是靠这一条满足了等保三级对“敏感数据不出内网”的硬性要求。

提示:不要相信任何声称“自动脱敏”的黑盒模型接口。真正的安全是控制输入源——open-code-review默认只传 diff 片段和函数签名,绝不会发送整文件、环境变量、.env内容。你可以在--debug模式下看到它实际发送的 payload,长度严格控制在 4KB 以内。

2.3 Git 集成不是“调用 git 命令”,而是深度理解 git 语义

很多 CLI 工具只是git diff | your-tool这样粗暴管道,但open-code-review把 git 当作一级公民来设计。它能区分三种典型场景:

  • 场景 A:pre-commit 审查(最常用)
    此时git status显示 staged 文件,工具会精确提取git diff --cached --no-color --unified=0的 hunk 级别变更(不是整文件),并为每个 hunk 关联其所在函数名(通过ctags或tree-sitter解析 AST 获取),这样模型提示词就能写成:“你正在审查函数calculateTax()的修改,原逻辑是……新逻辑是……请指出潜在风险”。

  • 场景 B:branch-diff 审查(CR 前预检)
    运行ocr diff main feature/login时,它不简单 diff 两个分支 tip,而是找出共同祖先(git merge-base),再计算ancestor..feature/login的增量变更集,排除掉main分支已存在的旧问题,只聚焦本次引入的改动。

  • 场景 C:commit-range 审查(批量复盘)
    ocr range HEAD~3 HEAD会解析每个 commit 的 message、author、diff,并按语义聚类(如“修复空指针”“新增日志”“重构工具类”),避免模型对重复模式疲劳。

这种设计让工具不是“git 的装饰品”,而是真正理解 git 的拓扑结构和开发意图——这也是它比单纯diff + LLM方案准确率高 3.2 倍的关键。

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

3.1 安装与初始化:三步完成,但每步都有门道

安装看似简单,实则藏着关键决策点:

# 第一步:安装二进制(macOS/Linux) curl -fsSL https://get.open-code-review.dev | sh # 第二步:初始化配置(会引导你选择模型策略) ocr init # 第三步:验证(不是跑 hello world,而是真跑一次 review) echo "if (user != null) { user.getName(); }" > test.java git add test.java ocr review --dry-run

但第二步ocr init的交互式引导才是重点。它不会问“你要用哪个模型”,而是问三个实质问题:

  1. 你的网络环境是否允许外呼?(决定默认启用 L1 还是 L2)
  2. 你是否已有 Ollama 服务在本地运行?(若有,自动检测http://localhost:11434并列出可用模型)
  3. 你是否需要审计日志?(开启后所有 review 请求/响应存本地 SQLite,供合规检查)

注意:ocr init生成的~/.ocr/config.yaml是纯文本,你可以直接编辑。其中context_window: 2048参数不是随便设的——它对应模型实际能接收的 token 数。我们实测发现,当 diff 片段超过 120 行时,Phi-3-mini 的推理质量断崖下跌,所以工具会自动做“hunk 切片”:把超长 diff 拆成多个 ≤100 行的块,分别 review 再合并结论。这个切片逻辑写在src/git/diff_processor.rs里,不是 magic,是可验证的确定性行为。

3.2 提示工程:不是写 prompt,而是构建“审查契约”

open-code-review的核心不是模型多强,而是提示词(prompt)如何让模型“守规矩”。我们不采用通用 instruction tuning,而是定义了一套Code Review Contract(CRC),每个 review 请求都强制包含:

  • Role:你是一个有 10 年 Java 开发经验的 senior engineer,专注找 bug,不写文档,不提风格建议。
  • Input Format:严格按--- FILE: xxx.java ---\n@@ -10,5 +10,7 @@\n...格式提供 diff,附带函数签名和 Javadoc(若有)。
  • Output Format:必须是 JSON Array,每个 item 包含line_number,severity(critical/warning/info),message,suggestion(可执行的代码修正),且suggestion必须是单行、可直接 patch 的格式(如"user.getName()" → "Optional.ofNullable(user).map(User::getName).orElse(null)")。
  • Forbidden:禁止输出任何解释性文字、禁止猜测业务逻辑、禁止要求用户提供更多信息。

这套 CRC 经过 27 轮 A/B 测试迭代——最初版本模型常回复“请提供更多上下文”,后来我们加入suggestion字段的 schema 强约束,并在 post-process 阶段用正则校验 JSON 结构,才把格式错误率从 41% 降到 0.3%。你可以在templates/review.jinja里看到完整模板,它不是魔法字符串,而是可调试、可替换的 Jinja2 模板。

3.3 安全防护:密钥泄露防控的四道防火墙

热搜词里“使用 LLM 时如何防止密钥泄露”被问了 127 次,这不是焦虑,是真实血泪。open-code-review实施了四层防护:

防护层实现方式触发时机效果
L1:输入过滤正则扫描*.env,config.yml等敏感文件路径,若出现在 git diff 中,直接跳过该文件 reviewocr review执行前阻断 92% 的误提交风险
L2:diff 清洗对git diff输出做 AST-aware 清洗:移除注释、字符串字面量中的疑似密钥(匹配AKIA[0-9A-Z]{16}等模式)diff 解析阶段防止模型看到明文密钥
L3:模型沙箱在 L2 级别 API 调用时,注入 system prompt:“你绝不能在输出中包含任何形如sk-、ghp_、-----BEGIN RSA PRIVATE KEY-----的字符串,否则将被惩罚”模型请求头降低回显概率至 <0.01%
L4:输出校验用secret-scanner库扫描模型返回的 JSON,若suggestion字段含密钥模式,整条 comment 标记为blocked并告警response 解析后最后一道人工可见防线

实操心得:我们曾在线上环境发现某次 review 返回了suggestion: "return config.get('AWS_SECRET_KEY')"—— 这不是模型胡说,而是 diff 里真有这行代码!L4 层立刻拦截并邮件告警,团队当天就修复了配置管理漏洞。安全不是靠模型“自觉”,而是靠层层校验的确定性机制。

3.4 Git 钩子集成:pre-commit 不是“加个脚本”,而是精细控制

把ocr review塞进.husky/pre-commit很容易,但真实项目需要更精细的控制。open-code-review提供了ocr hook install命令,它生成的钩子不是简单ocr review,而是:

#!/bin/sh # .git/hooks/pre-commit set -e # 仅对 Java/Python/TS 文件触发 CHANGED_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep -E '\.(java|py|ts)$') if [ -z "$CHANGED_FILES" ]; then exit 0 fi # 跳过 test 目录和 generated 代码 CHANGED_FILES=$(echo "$CHANGED_FILES" | grep -v -E '(/test/|/gen/|\.d\.ts$)') if [ -n "$CHANGED_FILES" ]; then # 设置超时:单个文件 review 不超过 15 秒,超时则警告但不中断 commit timeout 15s ocr review --files $CHANGED_FILES --quiet || echo "⚠️ open-code-review 超时,commit 继续" fi

这个钩子做了三件事:文件类型过滤、路径白名单、超时熔断。我们刻意不设--fail-on-warning,因为 LLM review 是辅助,不是 gatekeeper。如果模型卡住,commit 不能被阻塞——这是保障开发者体验的底线。另外,ocr hook install会检测你是否用了 pnpm/yarn/npm,并在package.json的scripts里自动添加"precommit": "ocr hook run",兼容所有主流包管理器。

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

4.1 从零开始一次完整 review:以 Java Spring Boot 项目为例

假设你正在开发一个订单服务,刚写了如下代码并git add:

// src/main/java/com/shop/order/OrderService.java public class OrderService { public Order createOrder(User user) { if (user == null) { throw new IllegalArgumentException("user cannot be null"); } // TODO: call payment service return new Order(user.getId(), "PENDING"); } }

执行ocr review后,实际发生的过程是:

Step 1:Git 状态解析
工具运行git diff --cached --no-color --unified=0 src/main/java/com/shop/order/OrderService.java,得到:

--- a/src/main/java/com/shop/order/OrderService.java +++ b/src/main/java/com/shop/order/OrderService.java @@ -5,0 +6,10 @@ public class OrderService { + public Order createOrder(User user) { + if (user == null) { + throw new IllegalArgumentException("user cannot be null"); + } + // TODO: call payment service + return new Order(user.getId(), "PENDING"); + }

Step 2:上下文增强
工具用tree-sitter-java解析该文件,定位到createOrder函数的 AST 节点,提取:

  • 函数签名:public Order createOrder(User user)
  • 返回类型:Order
  • 参数类型:User
  • 所在类:OrderService
  • Javadoc(空)

Step 3:构建 prompt
将上述信息填入 CRC 模板,生成约 850 token 的输入:

You are a senior Java engineer reviewing code changes. Focus on bugs, not style. --- FILE: src/main/java/com/shop/order/OrderService.java --- @@ -5,0 +6,10 @@ public class OrderService { + public Order createOrder(User user) { + if (user == null) { + throw new IllegalArgumentException("user cannot be null"); + } + // TODO: call payment service + return new Order(user.getId(), "PENDING"); + } Function signature: public Order createOrder(User user) Return type: Order Parameter type: User Class: OrderService Output ONLY valid JSON array. Each item must have: - line_number: integer (1-based, relative to file) - severity: "critical" | "warning" | "info" - message: concise problem description - suggestion: single-line fix, executable as patch

Step 4:模型调用与响应处理
本地 Phi-3-mini 加载后,推理耗时 2.3s,返回:

[ { "line_number": 9, "severity": "warning", "message": "TODO comment indicates incomplete implementation", "suggestion": "// TODO: call payment service → paymentClient.process(user);" }, { "line_number": 10, "severity": "critical", "message": "Null check does not prevent NPE in user.getId() if user is not null but getId() returns null", "suggestion": "return new Order(Objects.requireNonNull(user).getId(), \"PENDING\");" } ]

Step 5:结果渲染
工具将 JSON 转为终端彩色输出:

src/main/java/com/shop/order/OrderService.java:9: ⚠️ warning: TODO comment indicates incomplete implementation → // TODO: call payment service → paymentClient.process(user); src/main/java/com/shop/order/OrderService.java:10: ❌ critical: Null check does not prevent NPE in user.getId() if user is not null but getId() returns null → return new Order(Objects.requireNonNull(user).getId(), "PENDING");

整个过程平均耗时 3.8s(含模型加载),比人工快速扫一遍还快,且能发现人眼易忽略的Objects.requireNonNull缺失问题。

4.2 模型切换实战:从本地 Phi-3 到云端 DeepSeek-Coder

热搜词里“deepseek 是属于哪个”常被问,DeepSeek-Coder 确实是当前代码领域 SOTA 模型之一,但它不是拿来即用的。open-code-review的模型切换不是改个配置就行,而是涉及三层面适配:

① API 兼容层
DeepSeek-Coder 的/v1/chat/completions接口要求model: "deepseek-coder:33b",而 Ollama 要求model: "deepseek-coder:33b",OpenRouter 则要model: "deepseek/deepseek-coder-33b-instruct".ocr的src/llm/client.rs用 trait object 封装了不同 provider,你只需在config.yaml里写:

llm: provider: openrouter model: deepseek/deepseek-coder-33b-instruct api_key: sk-or-v1-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

② 提示词微调
DeepSeek-Coder 对 instruction 更敏感,原 CRC 模板里 “you are a senior engineer” 这类 role play 会降低其准确率。我们为它单独准备了templates/review_deepseek.jinja,去掉 role 描述,强化 format constraint:

<|im_start|>system You are a code review assistant. Output ONLY JSON array with keys: line_number, severity, message, suggestion. <|im_end|> <|im_start|>user {{ diff_block }} Function: {{ function_signature }} <|im_end|> <|im_start|>assistant

③ 输出解析适配
DeepSeek-Coder 有时会在 JSON 前加\n或 ````json,ocr的 parser 会自动 trim 和 strip code fence,确保serde_json::from_str总能成功。这部分逻辑在src/llm/output_parser.rs`,有 17 个正则变体覆盖常见污染模式。

实测对比:同一段 Java diff,Phi-3-mini 发现 2 个问题,DeepSeek-Coder 发现 4 个(多了 SQL 注入风险提示和事务缺失警告),但耗时从 2.3s 升到 8.7s(网络 RTT 占 6.2s)。所以我们在config.yaml里设了timeout: 10,并默认对单个文件只调用一次,避免雪崩。

4.3 企业级配置:Gitee 私有化部署与密钥管理

热搜词里“git 配置 gitee 密钥”“git 安装及配置教程”说明国内开发者对私有化有强需求。open-code-review支持 Gitee 企业版部署,关键在三点:

① Git 认证适配
Gitee 的 SSH key 和 HTTPS token 机制与 GitHub 不同。ocr的git_auth.rs模块会自动检测 remote URL:

  • 若为git@gitee.com:org/repo.git,则读取~/.ssh/id_rsa并验证权限;
  • 若为https://gitee.com/org/repo.git,则查找~/.git-credentials或git config credential.helper配置。

② 审计日志对接
企业要求所有 review 操作留痕。ocr的 SQLite 日志表review_logs包含commit_hash,reviewer_model,input_tokens,output_tokens,duration_ms,is_blocked字段。你可以用ocr log export --format csv > audit.csv导出供 SOC 审计。

③ 密钥隔离策略
Gitee 企业版常要求 API key 与代码库分离。ocr支持从 Vault 或本地加密文件读取 key:

# 用 age 加密 key 文件 echo "sk-gitee-xxxxxxxx" | age -r age1xxx > ~/.ocr/api_key.age # config.yaml 中指定 llm: api_key_source: "age://~/.ocr/api_key.age"

这样即使配置文件被误传,密钥也不会泄露。

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

5.1 模型返回空或乱码:先查 token 截断,再查 context overflow

这是新手遇到最多的报错。典型现象:ocr review输出空白,或返回{"error":"invalid json"}。排查路径必须按顺序:

  1. 确认 diff 是否为空
    运行git diff --cached,若无输出,说明没暂存文件。ocr不会主动git add,这是设计使然——它只审“已决定提交”的代码。

  2. 检查 token 截断
    加--debug参数:ocr review --debug。查看日志末尾是否有truncated input at 2048 tokens。若有,说明 diff 太大。此时用ocr review --max-hunk-lines 50限制单个 hunk 行数,或手动git add -p分块暂存。

  3. 验证模型加载
    本地模型需ocr model list查看状态。若显示phi3-mini: not downloaded,则运行ocr model download phi3-mini。注意:下载的是 GGUF 文件,不是 HuggingFace 原始权重,大小约 1.8GB,需稳定网络。

  4. API key 权限检查
    对于 OpenRouter,访问https://openrouter.ai/api/v1/models确认deepseek-coder是否在列表中,且你的 plan 有调用权限。免费 tier 默认禁用 33B 模型。

独家技巧:我们写了个ocr diagnose命令,它会自动执行上述 4 步并给出修复建议。比如检测到truncated input,它会建议:“检测到 diff 超过 2048 tokens,推荐运行ocr review --max-hunk-lines 30 --files src/main/java/YourFile.java”。

5.2 pre-commit 钩子不生效:90% 是 husky 版本或 shell 环境问题

ocr hook install生成的钩子在某些环境下失效,根本原因常是:

  • Husky v8+ 的 node_modules 限制
    Husky v8 默认不加载项目node_modules/.bin,导致ocr命令找不到。解决方案:在package.json的preparescript 里加husky set .husky/pre-commit "npx ocr hook run"。

  • Zsh/Bash 环境变量差异
    开发者 terminal 用 zsh,但 git 钩子默认用 bash,导致~/.local/bin不在 PATH。ocr hook install会自动在钩子开头加export PATH="$HOME/.local/bin:$PATH",但若你用asdf管理工具链,还需加source "$HOME/.asdf/asdf.sh"。

  • Windows CRLF 换行符破坏脚本
    .git/hooks/pre-commit在 Windows 上可能被写成 CRLF,bash 解析失败。ocr hook install会自动dos2unix .git/hooks/pre-commit,但需确保系统装了dos2unix。若未装,工具会 fallback 到 Python 实现的换行转换。

实操心得:我们给某银行客户部署时,发现他们的 Jenkins agent 用的是 Alpine Linux,缺少bash。最终方案是ocr hook install --shell sh,生成 POSIX 兼容脚本,所有[[ ]]改成[ ],$(...)改成`...`。这个 flag 现在已成为企业版标配。

5.3 审查结果误报率高:不是模型问题,是上下文没给准

有用户反馈“review 总说我的 logger 用法不对”,实际是工具把log.info("user: {}", user)里的user当成了敏感数据。根源在于:LLM 不懂 SLF4J 的占位符语法,而工具没给足够上下文。解决方案分三层:

① 提升 AST 解析精度
ocr默认用 tree-sitter,但对某些框架(如 Lombok)的 AST 识别不全。此时可启用--ast-provider javaparser,它用 JavaParser 库做更严格的语法树构建,代价是启动慢 1.2s。

② 自定义规则白名单
在~/.ocr/rules.yaml里加:

- pattern: "log\\..*\\(\".*\\{\\}.*\",.*\\)" severity: ignore reason: "SLF4J placeholder syntax, safe"

工具会在 review 前先匹配 diff 行,命中则跳过该行。

③ 模型微调提示词
对特定框架,可覆盖全局模板。比如 Spring 项目,在项目根目录建.ocr/template.jinja:

{% extends "review.jinja" %} {% block system_prompt %} You are reviewing Spring Boot code. Treat @Autowired, @Value, and logging placeholders as safe. {% endblock %}

ocr会优先使用项目级模板。

5.4 性能瓶颈排查:CPU 占用高、响应慢的 5 个定位点

ocr review卡住时,不要盲目重启,按此顺序诊断:

指标检查命令正常值异常含义
模型加载ocr model info phi3-miniloaded: true,size: 1.8GBloaded: false表示 GGUF 文件损坏
Git diff 体积git diff --cached | wc -l< 500 行> 2000 行需分块 review
网络延迟curl -o /dev/null -s -w "%{time_total}s" https://api.openrouter.ai/v1/models< 1.5s> 3s 说明网络或 API 限流
本地 CPUhtop查看llama-server进程单核 100%正常,Phi-3-mini 是 CPU 模型
内存占用free -h剩余 > 2GB< 500MB 可能 OOM,需--n-gpu-layers 0

独家技巧:我们内置了ocr benchmark命令,它会用标准测试集(10 个典型 Java diff)跑三次,输出平均耗时、token/s、内存峰值。某次客户报告“慢”,我们跑 benchmark 发现是他们服务器启用了 transparent huge pages(THP),关闭后性能提升 40%。这个细节现在写进了docs/performance-tuning.md。

6. 进阶扩展与定制化路径

6.1 从 CLI 到 CI:GitHub Actions 无缝集成

open-code-review不是孤岛,它设计之初就考虑 CI 场景。在.github/workflows/code-review.yml里:

name: Code Review on: [pull_request] jobs: review: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 # 必须获取完整历史 - name: Setup open-code-review run: curl -fsSL https://get.open-code-review.dev | sh - name: Run review run: ocr review --pr-base ${{ github.event.pull_request.base.sha }} --pr-head ${{ github.event.pull_request.head.sha }} - name: Post comments if: always() uses: actions/github-script@v7 with: script: | const reviews = require('./ocr-output.json'); for (const r of reviews) { github.rest.pulls.createReviewComment({ owner: context.repo.owner, repo: context.repo.repo, pull_number: context.payload.pull_request.number, body: `❌ ${r.severity}: ${r.message}\n\`\`\`diff\n${r.suggestion}\n\`\`\``, path: r.file, line: r.line_number, }); }

关键点:--pr-base和--pr-head参数让工具直接比较 PR 的 base/head,不用 checkout 切换分支。输出 JSON 由ocr review --output-format json > ocr-output.json生成,供后续步骤消费。

6.2 自定义审查规则:用 Rust 写插件,不是改配置

热搜词里“agent 和 llm 和 ai模型 有什么区别”其实指向一个本质:LLM 是引擎,Agent 是司机,而open-code-review是整车。它的插件系统允许你用 Rust 写审查逻辑,例如:

// src/plugins/no_todo.rs use ocr_core::{ReviewResult, DiffHunk}; pub fn check_no_todo(hunk: &DiffHunk) -> Vec<ReviewResult> { let mut results = vec![]; for (i, line) in hunk.lines.iter().enumerate() { if line.contains("TODO") || line.contains("FIXME") { results.push(ReviewResult { line_number: hunk.start_line + i as u32, severity: Severity::Warning, message: "TODO comment found".to_string(), suggestion: line.replace("TODO", "FIXME").replace("FIXME", "IMPL"), }); } } results }

编译成libno_todo.so,放在~/.ocr/plugins/,ocr启动时自动加载。这比 YAML 规则更强大——你能访问 AST、调用外部 API、做复杂模式匹配。

6.3 与飞书/钉钉打通:不只是“接入飞书”,而是消息闭环

热搜词“codex cli 接入飞书”背后是通知链路需求。open-code-review的--notify参数支持:

  • --notify feishu https://hook.feishu.cn/xxx:PR review 发现 critical 问题时,发飞书卡片,含一键跳转到 diff 行的链接。
  • --notify dingtalk https://oapi.dingtalk.com/robot/send?access_token=xxx:同理。
  • --notify email admin@company.com:用本地 sendmail 发送。

但关键是:消息里带git blame作者信息。工具会自动git blame -L <line>,<line> --date=short <file>,找出该行代码的最后修改者,并在飞书消息里 @ta。这不是简单 webhook,而是把 review、责任归属、通知形成闭环。

最后分享一个小技巧:我在实际使用中发现,把ocr review --max-hunk-lines 40加进~/.zshrc的 aliasalias gc='git commit -m'里,变成alias gc='ocr review --max-hunk-lines 40 && git commit -m',这样每次 commit 前自动 review,养成习惯后,团队代码质量肉眼可见地稳了。

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

YOLO26改进:C3k2融合EIEM边缘增强模块,专治小缺陷漏检

在工业视觉质检这个方向待久了&#xff0c;你会发现小缺陷漏检才是最磨人的问题。我之前在一个表面缺陷检测项目里&#xff0c;模型对大划痕、大污渍的召回已经做到九成五以上&#xff0c;但那种只有十几个像素的麻点、夹杂物&#xff0c;怎么调都差一口气。这一篇是 YOLO26 改…

作者头像 李华
网站建设 2026/10/19 17:01:16

从内置到自定义:LangChain复杂任务编排的Custom Chain与Agent实战

把LangChain从“会用”推向“能真正处理复杂任务”&#xff0c;核心就在于自己动手写Custom Chain和Custom Agent。内置的链解决线性流程还行&#xff0c;一旦任务要求循环判断、多渠道取数、多工具协同、中途修改参数&#xff0c;搭积木式的内置方案就完全不够用了。这篇文章我…

作者头像 李华
网站建设 2026/10/19 16:58:18

开源代码审查CLI:Git集成+本地LLM+可审计提示工程

1. 项目概述&#xff1a;一个真正能落地的开源代码审查 CLI 工具到底长什么样&#xff1f;“open-code-review”这个名字乍看平平无奇&#xff0c;但拆开来看——open不是泛指“开源”&#xff0c;而是强调开放可审计、开放可定制、开放可集成&#xff1b;code review也不是简单…

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

STM32 HTTP远程升级实战:告别串口烧录,实现OTA固件更新

简介&#xff1a;这份资源面向嵌入式开发者与STM32学习者&#xff0c;聚焦通过HTTP协议实现设备固件的远程升级&#xff0c;解决传统现场烧录维护效率低的问题。压缩包共202个文件&#xff0c;约5.23MB&#xff0c;以C源码与头文件为核心&#xff0c;包含36个.c、38个.h&#x…

作者头像 李华
网站建设 2026/10/19 16:52:16

Linux进程控制实战:从优先级、信号到僵尸进程

上一篇我们把进程从“是什么”讲到了“怎么看”&#xff0c;ps、top、进程状态这些基本操作应该都摸过一遍了。但一旦你真去维护一台服务器&#xff0c;或者写脚本拉起一堆任务&#xff0c;就会发现进程真正麻烦的地方其实在于“控制”&#xff1a;为什么关掉终端&#xff0c;程…

作者头像 李华