Ashishkosana/review-lens

GitHub: Ashishkosana/review-lens

一款多维度 LLM 代码审查代理,通过对初步发现进行对抗性自我验证来显著降低误报,输出高信号且经过验证的审查意见。

Stars: 0 | Forks: 0

# review-lens **你可以真正将其放在 PR 之后的 LLM 代码审查 —— 因为它在发表评论之前会先与自己进行辩论。** [![CI](https://static.pigsec.cn/wp-content/uploads/repos/cas/ad/ad5834178f7599af9fdda11629d49cae07f2997beec49821b2920eff5bfd50e7.svg)](https://github.com/AshishKosana/review-lens/actions/workflows/ci.yml) ![Python](https://img.shields.io/badge/python-3.11+-blue) ![License](https://img.shields.io/badge/license-MIT-green) `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绕过, 逆向工具