Project-Navi/grippy-code-review
GitHub: Project-Navi/grippy-code-review
一款自带确定性安全规则引擎的开源 AI 代码审查工具,支持自托管模型和跨 PR 上下文记忆,将安全审计无缝融入 CI/CD 流程。
Stars: 1 | Forks: 0
# Grippy 代码审查
[](https://github.com/Project-Navi/grippy-code-review/actions/workflows/tests.yml)
[](https://codecov.io/gh/Project-Navi/grippy-code-review)
[](https://github.com/Project-Navi/grippy-code-review/actions/workflows/codeql.yml)
[](https://scorecard.dev/viewer/?uri=github.com/Project-Navi/grippy-code-review)
[](https://slsa.dev)
[](https://pypi.org/project/grippy-code-review/)
[](LICENSE)
[](https://www.python.org/downloads/)
[](https://github.com/astral-sh/ruff)
Grippy 使用任何 OpenAI 兼容模型审查 pull request —— GPT、Claude,或在本地硬件上运行的本地 LLM。它将你的代码库索引到向量存储中以实现上下文感知分析,然后发布带有分数、判定和升级路径的结构化发现。它恰好还是一位脾气暴躁的安全审计员,私底下尊重优秀的代码。
## 为什么选择 Grippy?
- **你的模型,你的基础设施。** 自带模型。无 SaaS 依赖,无按席位收费。通过 OpenAI 运行 GPT-5,通过兼容代理运行 Claude,或通过 Ollama 或 LM Studio 运行本地模型。
- **感知代码库,而非只看 diff。** Grippy 将你的仓库嵌入到 LanceDB 向量索引中,并在审查期间搜索它。它理解 diff 周围的代码,而不仅仅是 diff 本身。大多数开源替代方案将此功能锁定在托管层级的付费墙后。
- **跨 PR 记忆,而非健忘。** Grippy 构建你代码库的知识图谱 —— 跟踪每个 PR 的文件、审查、发现和导入依赖关系。它知道哪些模块是爆炸半径风险,哪些文件有重复发现,哪些作者有值得关注的模式。像 CodeRabbit、Greptile 和 Qodo 这样的工具对类似的跨 PR 上下文每个席位每月收费 20–38 美元。在这里,它是免费且开源的。
- **结构化输出,不仅仅是评论。** 每次审查都会产生带有严重性、置信度和类别的类型化发现。满分 100 的分数。判定(PASS / FAIL / PROVISIONAL)。针对需要人工关注的发现的升级目标。
- **安全优先,而非附加安全。** Grippy 是一位同时也审查代码的安全审计员,而不是反过来。专用的审计模式比通用 linter 更深入。
- **确定性规则,不仅仅是 LLM 猜测。** 内置规则引擎在 LLM 看到每个 diff 之前对其运行 6 条安全规则。发现是保证的 —— 而非幻觉产生的 —— 并且配置文件门控可以在关键严重性命中时使 CI 失败,独立于模型输出。
- **它有主见。** Grippy 是一个脾气暴躁的安全审计员角色,而不是一个冷冰冰的机器人。好的代码得到勉强的尊重。坏的代码得到失望。这种个性使审查具有可读性和诚实性。
## 它的样子
PR diff 上的内联发现:
作为 PR 评论发布的审查摘要:
## 快速开始
### GitHub Actions (OpenAI)
将 `.github/workflows/grippy-review.yml` 添加到你的仓库:
```
name: Grippy Review
on:
pull_request:
types: [opened, synchronize, reopened]
permissions:
contents: read
pull-requests: write
jobs:
review:
name: Grippy Code Review
runs-on: ubuntu-latest
steps:
- uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0
with:
egress-policy: audit
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
with:
python-version: '3.12'
- name: Install Grippy
run: pip install "grippy-code-review[persistence]"
- name: Run review
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_EVENT_PATH: ${{ github.event_path }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
GRIPPY_TRANSPORT: openai
GRIPPY_MODEL_ID: gpt-5.2
GRIPPY_EMBEDDING_MODEL: text-embedding-3-large
GRIPPY_DATA_DIR: ./grippy-data
GRIPPY_TIMEOUT: 300
run: python -m grippy
```
### GitHub Actions (自托管 LLM)
Grippy 适用于任何 OpenAI 兼容的 API 端点,包括 Ollama、LM Studio 和 vLLM。我们推荐 **Q4 量化或更高的 Devstral-Small 24B** —— 在开发过程中经过结构化输出合规性和审查质量的测试。有关完整的设置说明,请参阅 wiki 上的 [自托管 LLM 指南](https://github.com/Project-Navi/grippy-code-review/wiki/Self-Hosted-LLM-Guide)。
### 本地开发
```
# 使用 uv(推荐)
uv add "grippy-code-review[persistence]"
# 或使用 pip
pip install "grippy-code-review[persistence]"
```
## 配置
Grippy 完全通过环境变量进行配置。
| Variable | Purpose | Default |
|---|---|---|
| `GRIPPY_TRANSPORT` | API 传输方式:`openai` 或 `local` | 从 `OPENAI_API_KEY` 推断 |
| `GRIPPY_MODEL_ID` | 模型标识符 | `devstral-small-2-24b-instruct-2512` |
| `GRIPPY_BASE_URL` | 本地传输的 API 端点 | `http://localhost:1234/v1` |
| `GRIPPY_EMBEDDING_MODEL` | Embedding 模型名称 | `text-embedding-qwen3-embedding-4b` |
| `GRIPPY_API_KEY` | 非 OpenAI 端点的 API key | `lm-studio` |
| `GRIPPY_DATA_DIR` | 持久化目录 | `./grippy-data` |
| `GRIPPY_TIMEOUT` | 审查超时时间(秒)(0 = 无限制) | `300` |
| `GRIPPY_PROFILE` | 安全配置文件:`general`、`security`、`strict-security` | `general` |
| `GRIPPY_MODE` | 审查模式覆盖 | `pr_review` |
| `OPENAI_API_KEY` | OpenAI API key(将传输方式设置为 `openai`) | — |
| `GITHUB_TOKEN` | GitHub API token(由 Actions 自动设置) | — |
### 跨供应商模型选择
如果你的代码库是与 AI 编程助手共同开发的,**我们强烈建议在与编写代码的供应商不同的模型上运行 Grippy**。不同的模型系列有不同的训练数据、不同的偏差和不同的盲点。与作者共享相同先验的审查者更有可能错过相同类别的 bug。使用跨供应商模型 —— 例如,用 Claude 审查 GPT 编写的代码,或用 GPT 审查 Claude 编写的代码 —— 可为你提供真正独立的审计,而不是回声室。
## 安全配置文件
Grippy 的确定性规则引擎由配置文件控制。通过 `GRIPPY_PROFILE` 环境变量或 `--profile` CLI 标志设置(CLI 优先级更高)。
| Profile | Rule engine | Gate threshold | Use case |
|---|---|---|---|
| `general` | Off | — | 标准 LLM-only 审查 |
| `security` | On | Fail on ERROR+ | 安全聚焦的 CI 门控 |
| `strict-security` | On | Fail on WARN+ | 高保障环境 |
当非 `general` 配置文件处于活动状态时,Grippy 在 LLM 之前运行 6 条确定性规则:
| Rule ID | Detects | Severity |
|---|---|---|
| `workflow-permissions-expanded` | write/admin 权限,未固定的 actions | ERROR / WARN |
| `secrets-in-diff` | API keys,私钥,`.env` 添加 | CRITICAL / WARN |
| `dangerous-execution-sinks` | 不安全的代码执行模式 | ERROR |
| `path-traversal-risk` | 污染的路径变量,`../` 模式 | WARN |
| `llm-output-unsanitized` | 模型输出在无 sanitizer 的情况下通过管道传输到 sinks | ERROR |
| `ci-script-execution-risk` | 有风险的 CI 脚本模式,CI 中的 sudo | CRITICAL / WARN |
规则发现作为确认的事实注入到 LLM 上下文中以进行解释。
## 审查模式
| Mode | Trigger | Focus |
|---|---|---|
| `pr_review` | PR 事件时默认 | 完整代码审查:正确性、安全性、风格、可维护性 |
| `security_audit` | 手动、计划或 `profile != general` 时自动 | 深度安全分析:注入、认证、密码学、数据暴露 |
| `governance_check` | 手动或计划 | 合规性与策略:许可、访问控制、审计追踪 |
| `surprise_audit` | PR 标题/正文包含 "production ready" | 具有扩展治理检查的全面审计 |
| `cli` | 本地调用 | 用于本地开发和测试的交互式审查 |
| `github_app` | GitHub App webhook | 通过安装的 GitHub App 进行事件驱动审查 |
## GitHub Actions 输出
作为 GitHub Action 运行时,Grippy 为下游工作流逻辑设置这些步骤输出:
| Output | Type | Description |
|---|---|---|
| `score` | int | 审查分数 0–100 |
| `verdict` | string | `PASS` / `FAIL` / `PROVISIONAL` |
| `findings-count` | int | LLM 发现总数 |
| `merge-blocking` | bool | 判定是否阻止合并 |
| `rule-findings-count` | int | 确定性规则命中数 |
| `rule-gate-failed` | bool | 规则门控是否导致 CI 失败 |
| `profile` | string | 活动安全配置文件名称 |
## 安全
Grippy 在对抗性环境中运行 —— PR diff 是由任何贡献者控制的不可信输入。深度防御清理应用于管道的每个阶段,并由覆盖 9 个攻击领域的 44 个测试的对抗性测试套件验证。
**输入清理。** 所有不可信文本(PR 元数据、diff、工具输出)都通过 [navi-sanitize](https://pypi.org/project/navi-sanitize/) 进行 Unicode 规范化 —— 剥离不可见字符(ZWSP、bidi 覆盖、变体选择器)、规范化同形异义字符(Cyrillic/Greek → ASCII)并删除空字节。这在任何其他处理之前运行。
**Prompt 注入防御。** 三层保护 LLM 上下文:
1. **XML 转义** — 所有上下文部分(``、``、`` 等)都经过 XML 转义,防止 ` ...` 突围攻击。
2. **自然语言注入模式中和** — 七个编译好的正则表达式模式检测并替换自然语言注入尝试(评分指令、置信度操纵、系统覆盖短语)为 `[BLOCKED]` 标记。
3. **数据围栏边界** — LLM prompt 中的前言明确将所有后续内容标记为“仅限 USER-PROVIDED DATA”,并指示忽略嵌入的指令。
**输出清理。** LLM 生成的文本在发布到 GitHub 之前通过五阶段管道:
1. **[navi-sanitize](https://pypi.org/project/navi-sanitize/)** — Unicode 规范化(与输入阶段相同)。
2. **nh3** — 基于 Rust 的 HTML sanitizer 从自由文本字段中剥离所有 HTML 标签。
3. **Markdown 图片剥离** — 删除 `` 语法以防止审查评论中的跟踪像素。
4. **Markdown 链接重写** — 将 `[text](https://url)` 转换为纯文本以防止钓鱼链接。
5. **URL scheme 过滤** — 从剩余的链接语法中删除 `javascript:`、`data:` 和 `vbscript:` scheme。
**工具输出清理。** 代码库工具响应(`read_file`、`grep_code`、`list_files`)在到达 LLM 之前经过 navi-sanitize 清理和 XML 转义,防止通过精心制作的文件内容进行间接 prompt 注入。
**对抗性测试套件。** `tests/test_hostile_environment.py` 涵盖 44 个攻击场景,包括 Unicode 攻击、prompt 注入、工具利用、输出清理漏洞、信息泄露、schema 验证攻击、会话历史中毒等。所有 44 个都通过。
有关代码库工具保护、CI 加固和完整的威胁模型,请参阅 [安全模型](https://github.com/Project-Navi/grippy-code-review/wiki/Security-Model) wiki 页面。
## 文档
- [入门指南](https://github.com/Project-Navi/grippy-code-review/wiki/Getting-Started) — OpenAI、本地 LLM 和开发的设置
- [配置](https://github.com/Project-Navi/grippy-code-review/wiki/Configuration) — 环境变量和模型选项
- [架构](https://github.com/Project-Navi/grippy-code-review/wiki/Architecture) — 模块映射、prompt 系统、数据流
- [审查模式](https://github.com/Project-Navi/grippy-code-review/wiki/Review-Modes) — 6 种审查模式及其工作原理
- [评分标准](https://github.com/Project-Navi/grippy-code-review/wiki/Scoring-Rubric) — Grippy 如何对 PR 进行评分
- [安全模型](https://github.com/Project-Navi/grippy-code-review/wiki/Security-Model) — 代码库工具保护、加固的 CI
- [自托管 LLM 指南](https://github.com/Project-Navi/grippy-code-review/wiki/Self-Hosted-LLM-Guide) — Ollama/LM Studio + Cloudflare Tunnel
- [贡献](https://github.com/Project-Navi/grippy-code-review/wiki/Contributing) — 开发设置、测试、约定
## 许可证
[MIT](LICENSE)
标签:AI风险缓解, Claude, CVE检测, DevSecOps, DLL 劫持, LanceDB, LLM评估, Ollama, OpenAI, Petitpotam, Pull Request, Python, RAG, 上游代理, 云安全监控, 人工智能, 代码安全, 代码审查, 内存规避, 向量数据库, 大语言模型, 威胁情报, 开发者工具, 开源, 无后门, 本地部署, 漏洞枚举, 用户模式Hook绕过, 网络调试, 自动化, 逆向工具, 静态分析