Ken-u/review-agent

A code review agent

★ 0Forks 0RustGitHub ↗Compare

README

review-agent

非交互式自动代码审查 Agent —— 使用 LLM 驱动对 git diff / patch 文件进行深度代码审查,输出结构化 JSON 与 Markdown 报告。

核心特性

  • LLM 驱动的自动审查:兼容 OpenAI Chat Completions 协议,支持任意兼容端点
  • Agent 自主探索:Agent 自行决定读取哪些文件、搜索哪些符号、追踪哪些调用链
  • 规则文件解耦:审查规则通过 --rules 传入(可多个),通用规则、Android 规则、Linux 规则各自独立
  • 结构化输出:稳定的 JSON Schema + 可读的 Markdown 报告,可直接供 CI/Jenkins 消费
  • Verifier 过滤:只报告由本次 diff 明确引入的问题,附带触发条件、影响、证据
  • 工具沙箱:受控的文件读取、git、ripgrep 访问;命令执行需显式启用且匹配 allowlist
  • CI 友好:确定性退出码,无交互输入,单二进制部署

安装

从源码编译

cargo build --release
# 生成的二进制在 target/release/review-agent

一键安装(推荐)

安装脚本会按当前系统自动选择 linux/darwin/windows + x86_64/aarch64 包,并把安装来源写入 ~/.codereview-agent/install_source 与 config。之后 cv / cvm 等命令的自动更新会固定走同一来源。

GitHub(公开):

curl -fsSL https://raw.githubusercontent.com/Ken-u/review-agent/main/install.sh | bash -s -- --source github

# 非交互
curl -fsSL https://raw.githubusercontent.com/Ken-u/review-agent/main/install.sh | bash -s -- --source github -y

内网 GitBucket:

curl -fsSL http://10.10.10.205:8091/bjc/codereview-agent/raw/HEAD/install.sh | bash

# 非交互 / 指定平台模板
curl -fsSL http://10.10.10.205:8091/bjc/codereview-agent/raw/HEAD/install.sh | bash -s -- -y
curl -fsSL http://10.10.10.205:8091/bjc/codereview-agent/raw/HEAD/install.sh | bash -s -- --platform android
curl -fsSL http://10.10.10.205:8091/bjc/codereview-agent/raw/HEAD/install.sh | bash -s -- --source gitbucket --platform linux

安装后请编辑 ~/.codereview-agent/config,填入 REVIEW_AGENT_API_KEY 等配置。

本地打包

./package_release.sh
# 生成 codereview-agent-vX.Y.Z-<os>-<arch>.tar.gz

./package_release.sh --binary ./target/release/review-agent --platform linux-x86_64

发布说明

  • 修改 Cargo.toml 中的 version 并推送到 main 后,GitHub Actions 会自动编译 Linux / macOS / Windows 多架构二进制并创建 Release(tag = v<version>)。
  • 同一版本号只会发布一次;重复推送不会覆盖已有 tag。

仓库布局

  • src/:Rust 主程序与审查流程
  • resources/:内置审查规则与提交信息规则
  • experiments/:评测辅助脚本与文档
  • eval_compare.sh:评测集批量入口脚本
  • review-agent.toml:示例配置文件

快速开始

基本用法(通用规则)

export OPENAI_API_KEY="sk-..."

review-agent review \
  --repo . \
  --base origin/main \
  --head HEAD \
  --rules resources/REVIEW_RULES.md \
  --output-json review.json \
  --output-md review.md

Android/AOSP 项目

review-agent review \
  --repo . \
  --base origin/main \
  --head HEAD \
  --rules resources/REVIEW_RULES.md \
  --rules resources/RULES_ANDROID.md \
  --output-json review.json

Linux SDK / Buildroot 项目

review-agent review \
  --repo . \
  --base origin/main \
  --head HEAD \
  --rules resources/REVIEW_RULES.md \
  --rules resources/RULES_LINUX.md \
  --output-json review.json

审查 patch 文件

review-agent review \
  --patch change.patch \
  --rules resources/REVIEW_RULES.md \
  --output-json review.json

提交信息审查

review-agent review \
  --repo . \
  --base HEAD~1 \
  --rules resources/REVIEW_RULES.md \
  --commit-rules resources/COMMIT_RULES_ANDROID.md

通过 CLI 传入 API Key

review-agent review \
  --repo . \
  --base HEAD~1 \
  --api-key sk-xxxxxxxxxxxxxxxx \
  --rules resources/REVIEW_RULES.md

审查规则文件

审查规则通过 --rules 参数传入,可多次指定以组合多套规则。所有规则文件内容会被拼接后注入到 Agent 的 system prompt 中。

提供的规则文件

文件 说明 适用场景
resources/REVIEW_RULES.md 通用审查规则(错误处理、安全、性能、并发、资源管理) 所有项目
resources/RULES_ANDROID.md Android/AOSP 专项(Binder、多用户、ANR、AIDL、JNI、SELinux、system_server) Android 系统/应用开发
resources/RULES_LINUX.md Linux SDK/Buildroot 专项(Kconfig、设备树、内核模块、rootfs、交叉编译、U-Boot) 嵌入式 Linux / Buildroot / Yocto

组合示例

# 只用通用规则
--rules resources/REVIEW_RULES.md

# 通用 + Android
--rules resources/REVIEW_RULES.md --rules resources/RULES_ANDROID.md

# 通用 + Linux
--rules resources/REVIEW_RULES.md --rules resources/RULES_LINUX.md

# 通用 + Android + 项目自定义
--rules resources/REVIEW_RULES.md --rules resources/RULES_ANDROID.md --rules my_project_rules.md

# 不传 --rules 也能运行(Agent 只使用内置的基础审查逻辑)

自定义规则

你可以创建自己的规则文件,Markdown 格式,内容随意。Agent 会将其作为审查指南。建议包含:

  • 项目特有的编码规范
  • 已知的高风险模块说明
  • 历史上常见的 bug 模式
  • 特定 API 的使用约束

CLI 参数说明

review-agent review [OPTIONS]
参数 类型 默认值 说明
--repo <PATH> 路径 . 仓库根目录路径
--base <REF> 字符串 — Diff 基准 ref(例如 origin/main, HEAD~1, commit SHA)
--head <REF> 字符串 HEAD Diff 目标 ref
--patch <PATH> 路径 — Patch 文件路径(与 --base/--head 二选一)
--rules <PATH> 路径 — 审查规则文件,可多次指定:--rules a.md --rules b.md
--commit-rules <PATH> 路径 — 提交信息审查规则文件,可多次指定
--config <PATH> 路径 review-agent.toml TOML 配置文件路径
--api-key <KEY> 字符串 — LLM API Key(优先级最高)
--output-json <PATH> 路径 — JSON 报告输出路径
--output-md <PATH> 路径 — Markdown 报告输出路径
--gen-debug-view <PATH> 路径 — 生成单文件 HTML 调试视图
--post-hook <PATH> 路径 — 审查结束后执行 hook 脚本

配置文件

配置文件使用 TOML 格式,默认查找 review-agent.toml。

[provider] — LLM 提供方

字段 类型 默认值 说明
endpoint 字符串 https://api.openai.com/v1 API 端点(兼容 OpenAI Chat Completions 协议)
api_key 字符串 — 直接配置 API Key(不推荐明文存储)
api_key_env 字符串 OPENAI_API_KEY 从此环境变量读取 API Key
model 字符串 gpt-4o 模型名称
timeout_secs 整数 120 单次请求超时(秒)
max_tokens 整数 4096 单次响应最大 token 数
max_retries 整数 4 LLM 请求失败后最大重试次数。普通瞬时错误指数退避 1s→2s→…(上限 30s);429 最少等待 60s(覆盖后台 1 分钟窗口),之后 120s→180s,并行调用共享限流门闩;其他 4xx 不重试
max_rounds 整数 15 Agent 最大探索轮次(每轮 = 一次 LLM 调用 + 工具执行)
context_limit_tokens 整数 32000 上下文 token 软上限(按 API 返回的 prompt_tokens),超限后调用 LLM 摘要压缩

API Key 优先级:--api-key CLI 参数 > [provider].api_key 配置 > $OPENAI_API_KEY 环境变量

[policy] — 审查策略

字段 类型 默认值 说明
severity_threshold 字符串 low 最低报告级别:low / medium / high / critical
max_findings 整数 50 最多输出 finding 条数
confidence_threshold 浮点数 0.6 最低置信度阈值(0.0–1.0)

[tools] — 工具权限

字段 类型 默认值 说明
enable_commands 布尔 false 是否允许 Agent 执行 shell 命令
command_allowlist 字符串数组 [] 允许执行的命令模板(支持 * 通配符)
command_timeout_secs 整数 30 命令执行超时(秒)
output_limit_bytes 整数 65536 工具输出截断阈值(字节)

[reporter] — 输出配置

字段 类型 默认值 说明
json_output 字符串 — 默认 JSON 输出路径(CLI --output-json 会覆盖)
md_output 字符串 — 默认 Markdown 输出路径(CLI --output-md 会覆盖)

调试视图与 Hook

生成完整调用链调试页:

review-agent review \
  --repo . \
  --base HEAD~1 \
  --rules resources/REVIEW_RULES.md \
  --gen-debug-view debug.html

执行审查结束 hook:

review-agent review \
  --repo . \
  --base HEAD~1 \
  --rules resources/REVIEW_RULES.md \
  --post-hook ./gerrit_hook.sh

--post-hook 会注入 REVIEW_* 环境变量,例如 REVIEW_VERDICT、REVIEW_FINDINGS_COUNT、REVIEW_JSON_PATH、REVIEW_GERRIT_JSON_PATH。


Agent 内置工具

工具 说明 权限
read_file 读取仓库内文件内容,可指定起止行号 只读,限仓库内
list_files 按 glob 模式列举文件(例如 src/**/*.rs) 只读
git_diff 执行 git diff 对比两个 ref 只读
git_show 查看指定 ref 下的文件内容 只读
rg 使用 ripgrep 搜索代码模式,返回匹配行 只读
get_changed_files 获取本次 diff 涉及的文件列表及状态 只读
get_changed_lines 获取指定文件中变更的行号与内容 只读
run_command 执行受控 shell 命令 需显式启用 + allowlist 匹配

容错与上下文管理

请求重试

LLM API 请求失败时,Agent 会按错误类型选择是否重试:

  • 429(rate limit):最少等待 60s(覆盖后台 1 分钟窗口);有 Retry-After/正文提示时取更大值,之后按 60s → 120s → 180s 增长。并行 Agent 共享限流门闩,避免互相踩配额
  • 5xx / 408 / 网络错误:指数退避 1s → 2s → 4s…(上限 30s)
  • 其他 4xx(如 400/401/403):立即失败,不重试
  • 默认最多重试 4 次,可通过 max_retries 配置调整

实验评测

主线自带一个批量对比评测脚本:

OPENAI_API_KEY=sk-... ./eval_compare.sh \
  --baseline-worktree /path/to/baseline-worktree \
  --candidate-worktree /path/to/candidate-worktree \
  --config ./review-agent.toml \
  --dataset-csv ./dataset/datasets.csv.mini \
  --output-dir /tmp/review-eval \
  --default-base HEAD~1 \
  --default-rules "$(pwd)/resources/REVIEW_RULES.md,$(pwd)/resources/RULES_ANDROID.md"

推荐先用 git worktree 准备 baseline 和 candidate,而不是来回切分支。这样两个工作目录可以共用同一个 git 对象库,测试集路径和大部分仓库文件也不需要重复拷贝。

评测脚本按严格串行方式执行:先编译两边,再逐个 case 依次跑 baseline 和 candidate。不要把多个 case 并发跑,也不要同时起多个 eval_compare.sh 进程,否则模型侧并发会污染耗时和结果稳定性。

# 在仓库旁边准备两个工作树
git worktree add ../codereview-agent-baseline main
git worktree add ../codereview-agent-candidate HEAD

# 脚本会自动编译两边,再跑同一套评测集
OPENAI_API_KEY=sk-... ./eval_compare.sh \
  --baseline-worktree ../codereview-agent-baseline \
  --candidate-worktree ../codereview-agent-candidate \
  --config ./review-agent.toml \
  --dataset-csv ./dataset/datasets.csv.mini \
  --output-dir /tmp/review-eval \
  --default-base HEAD~1 \
  --default-rules "$(pwd)/resources/REVIEW_RULES.md,$(pwd)/resources/RULES_ANDROID.md"

它会:

  • 先在 baseline 和 candidate worktree 中执行 cargo build --release
  • 严格串行地逐个执行所有 case,不做并发调度
  • 按 --dataset-csv 的 name 列从 ./dataset 或你传入的 --suite-dir 中筛选测试集
  • 分别运行 baseline 和 candidate
  • 输出:
    • summary.md
    • summary.json
    • summary.html
    • 每个 case 的 baseline_only / candidate_only 差异文件
    • 每个 case 的 JSON / Markdown 原始报告

说明:

  • --dataset-csv ./dataset/datasets.csv.mini 是推荐入口,适合固定一小组 case 做快速回归
  • 如果不传 --suite-dir,--dataset-csv 默认从仓库内 ./dataset 查找对应 repo
  • 汇总结果不再输出单一总分,而是输出一组独立指标
  • 主指标包括稳定性、效率分、Finding 密度、Severe Finding 密度
  • 其中稳定性等于完成项目数量 / 总项目数量的百分比
  • 效率项会先按复合补丁复杂度归一化 total_tokens 和 tool call 数量,再按统一标尺给 baseline / candidate 分别打分
  • 效率项里 total_tokens 是主指标,权重 80%;tool call 数量权重 20%
  • severe/overall overlap 和 verdict agreement 只作为 baseline 对照观察项展示
  • wall_ms 只作为辅助观测项展示,不参与最终得分
  • 如果 cases.normalized.tsv 同级目录或 suite 根目录下存在 labels/,汇总脚本会自动加载人工标签,额外输出 verdict 正确率、finding 精确率和自动结论

可选的人工标签目录结构:

labels/
  case_labels.csv
  finding_labels.jsonl

也可以手工运行汇总脚本,并显式传入标签目录:

./experiments/summarize_results.py \
  /tmp/review-eval/cases.normalized.tsv \
  /tmp/review-eval \
  ./experiments/labels

相关文档:

上下文压缩(LLM Summarizer)

上下文大小基于 API 实际返回的 prompt_tokens 追踪(而非字符估算)。当 prompt_tokens 超过 context_limit_tokens 时:

  1. LLM 摘要压缩(主策略):

    • 将较早的 tool call 记录和 assistant 推理消息提取成摘要素材
    • 调用 LLM summarizer(独立的一次轻量 chat 请求)生成 ≤500 词的压缩摘要
    • 用一条摘要消息替换原来的多条中间消息,保留 system prompt、初始 user prompt 和最近 4 条消息不动
  2. 硬截断兜底(summarizer 失败时):

    • 若 summarizer 本身调用失败(如网络问题),退化为硬截断
    • 老旧 tool 结果只保留前 3 行 + 字符数元信息
    • 老旧 assistant 中间推理截断为 200 字符

优雅降级

  • 连续 2 次 LLM 调用失败时,Agent 不再中断而是尝试从已有对话中提取部分结果
  • 接近轮次上限(倒数第 2 轮)时,自动注入提示要求 Agent 尽快输出结果
  • 即使中途失败,已收集的 findings 也会尽量保留到最终报告中

提示词优化

Agent 的 system prompt 明确要求使用行号范围读取文件(而非整个文件),以避免上下文爆炸:

  • read_file 应始终指定 start_line / end_line,不允许读取整个大文件
  • 推荐先用 get_changed_lines 定位变更位置,再有针对性地读取
  • 探索深度限制为 2 层调用链,不重复读取同一文件段

调试方法

日志级别控制

# 默认 info 级别
review-agent review --repo . --base HEAD~1

# debug 级别:显示每个 agent round、tool call 参数和结果
RUST_LOG=review_agent=debug review-agent review --repo . --base HEAD~1

# trace 级别:显示完整的 LLM 请求/响应
RUST_LOG=review_agent=trace review-agent review --repo . --base HEAD~1

查看工具调用记录

cat review.json | jq '.tool_calls[] | {tool_name, status, duration_ms}'

Verifier 过滤日志(debug 级别)

DEBUG rejected: not introduced by diff (title="...")
DEBUG rejected: line not in or near changed lines (file="...", line=42)
DEBUG rejected: empty trigger_condition (title="...")

不同 LLM 端点

# 使用本地 Ollama
# 在 review-agent.toml 中:
# [provider]
# endpoint = "http://localhost:11434/v1"
# model = "llama3"
# api_key = "ollama"

退出码

退出码 含义
0 审查完成,无 finding
1 审查完成,有 finding
2 输入/配置错误
3 LLM provider 错误
4 工具权限或执行错误
5 内部异常

架构概览

CLI (clap) → Config (TOML) → Orchestrator
                                ├── Diff Profiler    解析 unified diff,风险评估
                                ├── Tool Router      调度 read_file / git / rg 等工具
                                ├── Review Agent     LLM tool-use 循环,自主探索
                                │     └── rules 文件内容注入 system prompt
                                ├── Verifier         硬规则过滤 + 排序
                                └── Reporter         JSON + Markdown 输出

许可

内部使用。

Contributors

Ken-u

Issues