Ashishkosana/review-lens
GitHub: Ashishkosana/review-lens
一款多维度 LLM 代码审查代理,通过对初步发现进行对抗性自我验证来显著降低误报,输出高信号且经过验证的审查意见。
Stars: 0 | Forks: 0
# review-lens
**你可以真正将其放在 PR 之后的 LLM 代码审查 —— 因为它在发表评论之前会先与自己进行辩论。**
[](https://github.com/AshishKosana/review-lens/actions/workflows/ci.yml)


`review-lens` 通过 LLM 从**四个专注的维度**审查 git diff —— 正确性、安全性、性能和测试覆盖率 —— 然后运行**对抗性自我验证阶段**,在你看到结果之前尝试*反驳*每一个发现。你将得到一份简短、高信号且经过验证的评论列表,而不是单一“审查此 PR”提示词产生的那一大堆自信却错误的噪音。
它只负责提供建议。**由你来做决定。** 任何内容都不会被自动应用。
## 30 秒试用(无需 API key)
```
git clone https://github.com/Ashishkosana/review-lens && cd review-lens
pip install -e .
review-lens --demo
```
```
review-lens: 4 findings across 1 file (1 blocker, 2 high, 1 medium)
BLOCKER app/users.py:5 [security · 98% ✓verified]
SQL injection: username interpolated into the query string
get_user() builds SQL with an f-string, so `' OR '1'='1` runs as SQL (OWASP A03).
→ Use a parameterized query: db.execute("... WHERE username = ?", (username,)).
HIGH app/users.py:7 [correctness · 95% ✓verified]
Unhandled missing row raises TypeError
fetchone() returns None for an unknown user; row[0] then raises instead of 404-ing.
→ Guard the None case before indexing.
HIGH app/users.py:12 [security · 90% ✓verified]
Privilege escalation: admin derived from email domain
→ Check an explicit role flag set by a trusted process, not user-supplied email.
MEDIUM app/users.py:10 [tests · 80% ✓verified]
No test covers the not-found or admin paths
→ Add tests for the missing-user and is_admin true/false branches.
```
## 实际使用
```
export ANTHROPIC_API_KEY=sk-ant-...
git diff main | review-lens - # review a branch against main
review-lens HEAD~1 # review the last commit
review-lens # review your working tree vs HEAD
review-lens changes.diff # review a saved diff
review-lens HEAD~1 --format markdown # PR-ready markdown
review-lens HEAD~1 --lenses security,correctness --fail-on high
```
参数:`--format {terminal,markdown,github}` · `--lenses` · `--min-severity` · `--min-confidence` · `--no-verify` · `--fail-on ` (CI gate) · `--model`。
## 工作原理
```
┌─ correctness ─┐
git diff ──┼─ security ─────┤ (LLM, run in parallel)
├─ performance ──┤
└─ tests ────────┘
│ candidate findings
▼
adversarial verify ← a skeptic pass refutes each finding
│ against the actual diff; only survivors remain
▼
ranked, de-duped, verified findings → terminal / markdown / GitHub review
```
验证阶段是整个设计的核心:它以牺牲少量的召回率来换取极高的**精确率**,这正是人们愿意保留的审查者与被静音的审查者之间的区别。这一说法并非凭空感觉 —— 有一个[评估测试套件](#evaluation)可以对其进行测量。如果模型捏造的行号引用与 diff 实际更改的行不匹配,也会被作废。
## 作为 GitHub Action 使用
```
# .github/workflows/review.yml
name: review-lens
on: pull_request
permissions:
contents: read
pull-requests: write
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with: { fetch-depth: 0 }
- uses: Ashishkosana/review-lens@main
with:
anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}
fail-on: blocker
```
它将审查结果作为 PR 评论发布,并(可选地)在发现严重问题时使检查失败。
## 设计
- **端口与适配器。** 一切都依赖于一个微小的 `LLMClient` 协议,因此整个 pipeline 是针对内存中的 mock 进行单元测试的 —— CI 中无需密钥,也无需网络。Anthropic 适配器是唯一接触 API 的地方。
- **结构化输出。** 模型被强制要求使用一个必需的 tool call,其输出会被宽容地强制转换(错误的 severity → LOW,confidence 被限制范围,垃圾数据被丢弃)—— 它绝不会导致运行崩溃。
- **纯核心。** Diff 解析、排序、过滤和渲染都是带有各自测试的纯函数。
```
src/review_lens/
models.py # typed domain models (pure)
diff.py # unified-diff → per-file added-line maps (pure)
lenses.py # the four focused reviewer prompts
llm.py # LLMClient protocol + Anthropic adapter
coerce.py # tolerant LLM-output → Finding coercion
reviewer.py # orchestration: fan out → verify → filter
verify.py # adversarial self-verification
render.py # terminal / markdown / GitHub renderers (pure)
config.py # env-driven settings
cli.py # entry point
eval/ # labeled dataset + precision/recall/F1 harness (python -m review_lens.eval)
```
## 评估
核心主张 —— *验证阶段以召回率换取精确率* —— 是经过测量的,
而非断言。在 `src/review_lens/eval/cases/` 下有一个小型的**标注数据集**:
每个用例都是一个 unified diff 以及一个列出它*应该*呈现的发现的 ground-truth 标签文件
(`file`、`line`、`lens`、`severity`)。
- **注入 bug 的 diff** —— 一个 SQL injection、一个 off-by-one slice、一个 N+1 查询,
以及一个没有测试就发布的分支密集型函数 —— 每个维度一个。
- **干净的 diff** —— 一个纯粹的重命名/重输入以及一个正确的 parameterize-and-guard 修复 ——
不携带*任何*标签,因此对它们的任何发现都是 false positive。这就是测试套件测量精确率,而不仅仅是测量召回率的方式。
**指标**(`review_lens.eval.metrics`,纯函数且经过单元测试)使用 **precision / recall / F1** 将预测的
发现与标签进行评分。当预测通过 `file` + `lens` 匹配标签,并落在标记行的几行范围内时,该预测即为 true positive;匹配是一对一的,因此对同一缺陷的重复评论将计为
false positive,而不会虚增 recall。语料库指标汇总了所有
diff 的混淆矩阵计数(因此干净的 diff 确实会拉低 precision)。
运行它:
```
# 无 key:打印 dataset 及其评分方式(exit 0)。
python -m review_lens.eval
# 有 key:对每个 diff 运行两次 review() —— 分别为不带和带 verify
# pass —— 并打印显示 precision 提升的 precision/recall/F1 表格。
export ANTHROPIC_API_KEY=sk-ant-...
python -m review_lens.eval
```
两次运行使用相同的 severity/confidence 门槛,因此验证阶段是它们之间唯一的
变量。**每个数字都是通过模型在数据集上实时计算出来的 —— 没有任何硬编码。** 预计 *with-verify* 一行将显示出更高的
精确率(在干净的 diff 上 false positive 更少),但会牺牲一些召回率。
## 路线图
- 内联 GitHub review 评论(不仅仅是总结评论)
- 用于配置基于仓库的 lens 权重和忽略规则的配置文件
- 本地/OSS 模型适配器
## 许可证
MIT © Ashish Kosana
标签:DLL 劫持, LNA, Python, 人工智能, 代码审查, 大语言模型, 无后门, 用户模式Hook绕过, 逆向工具