purvanshh/PRGuard-AI
GitHub: purvanshh/PRGuard-AI
PRGuard-AI 是一个多智能体、生产级的 GitHub PR 自动代码审查系统,通过并行运行的 Style、Logic、Security 智能体结合规则匹配与 LLM 推理,对提交的代码进行全面审查并直接在 PR 中发布结构化评论。
Stars: 0 | Forks: 0
# PRGuard AI
**一个生产级、多智能体的 Pull Request 审查系统。**
[](https://python.org)
[](https://fastapi.tiangolo.com)
[](https://docs.celeryq.dev)
[](https://postgresql.org)
[](https://docker.com)
[](LICENSE)
[](https://github.com/purvanshh/PRGuard-AI/actions)
PRGuard AI 通过 webhook 与 GitHub 集成,并为每个传入的 pull request 编排一个多智能体分析 pipeline。三个独立的智能体 —— **Style**、**Logic** 和 **Security** —— 作为 Celery 任务并行运行。它们的初始发现被持久化到由 Redis 支持的共享上下文存储中。然后,这些智能体将经历由 **Coordinator Agent** 协调的迭代细化循环(最多三轮),在达成共识之前相互交叉审查彼此的发现。**Confidence Arbitrator** 会汇总最终输出,计算加权置信度分数,检测智能体之间的分歧,并将带有可选行内注释的结构化审查评论直接发布到 pull request 中。
该系统专为生产环境而构建:具有重试逻辑的异步任务队列、PostgreSQL 审计日志、LLM 调用上的熔断器、基于 Redis 的 token 预算管理、HMAC webhook 验证、重放攻击保护、速率限制、带有 LRU 淘汰机制的沙盒化仓库克隆,以及带有 OpenTelemetry trace 传播的结构化 JSON 日志记录。
## 目录
- [架构](#architecture)
- [示例输出](#example-output)
- [智能体分解](#agent-breakdown)
- [置信度评分](#confidence-scoring)
- [生产级特性](#production-features)
- [安装说明](#setup)
- [GitHub Webhook 配置](#github-webhook-configuration)
- [环境变量](#environment-variables)
- [API 端点](#api-endpoints)
- [仓库结构](#repository-structure)
- [安全性](#security)
- [评估](#evaluation)
- [路线图](#roadmap)
- [贡献](#contributing)
- [许可证](#license)
## 架构
```
flowchart TD
GH["GitHub (PR opened / updated)"]
GH -->|"POST /webhook"| FW
subgraph FW["FastAPI Server"]
direction LR
HMAC["HMAC Sig\nVerification"] --> REPLAY["Replay\nProtection"]
REPLAY --> TS["Timestamp\nValidation"]
TS --> RL["Rate Limiter\n(repo + inst.)"]
RL --> CLONE["Repo Cache\n& Sandbox"]
CLONE --> IDX["ChromaDB\nIndexing"]
end
FW -->|"enqueue review_pr"| CQ
subgraph CQ["Celery + Redis Task Queue"]
direction TB
ORCH["Orchestrator Task"] -->|"round 0 parallel run"| INIT["Style / Logic / Security Agents"]
INIT -->|"store context"| REDIS[("Redis Context Store")]
REDIS -->|"refinement loop (rounds 1-3)"| REF["Refinement & Dialogue Pass"]
REF -->|"stopping conditions check"| COORD["Coordinator Agent"]
COORD -->|"if converged"| ARB["Confidence Arbitrator"]
end
ARB --> C1["PR Comment"]
ARB --> C2["Inline Comments"]
ARB --> C3["Audit Log (PostgreSQL)"]
```
## 示例输出
以下是 PRGuard AI 在包含故意植入漏洞的测试 pull request 上发布的真实审查:
中高严重性的发现还会作为行内评论发布在特定的 diff 行上(每次审查最多 10 条)。
## 智能体分解
每个智能体都作为一个独立的 Celery 任务在专用队列上运行,具有自动重试(`autoretry_for=(Exception,)`、`retry_backoff=True`、`max_retries=1`)和 5 分钟的硬性任务超时限制。
### Style Agent
使用两阶段方法检查与仓库现有规范的一致性:
| 阶段 | 方法 | 捕获内容 |
|------|--------|-----------------|
| 基于规则 | 确定性字符串匹配 | 缩进使用 Tab、行宽超过 120 个字符 |
| LLM 引导 | Prompt + ChromaDB 代码示例 | 命名规范、docstring 一致性、文件结构 |
该智能体从仓库的 ChromaDB 索引中检索语义相似的代码,以使 LLM 分析基于项目特定的规范。
### Logic Agent
使用 AST 分析、模式匹配和上下文 LLM 推理检测逻辑缺陷:
| 阶段 | 方法 | 捕获内容 |
|------|--------|-----------------|
| 基于规则 | 对新增行进行模式匹配 | 裸 `except:` 子句、未解决的 `TODO` 标记 |
| AST 驱动 | tree-sitter 解析树摘要 | Python、Go、TypeScript 和 Rust 中的函数结构、变量使用、控制流 |
| LLM 引导 | Prompt + AST 摘要 + 上下文代码行 | 差一错误(Off-by-one)、空指针解引用、边界条件、未处理的异常 |
该智能体通过 `analysis/ast_parser.py` 为每个文件构建 AST 摘要,并将其与周围的 diff 上下文一起作为结构化输入提供给 LLM。
### Security Agent
使用模式匹配和专注于安全性的 LLM prompting 检测漏洞:
| 阶段 | 方法 | 捕获内容 |
|------|--------|-----------------|
| 基于规则 | 正则表达式和字符串检测 | `eval()`/`exec()` 的使用、SQL 注入模式、硬编码的密钥和 API key |
| LLM 引导 | 特定于安全的 prompt | 命令注入、不安全的反序列化、权限提升、SSRF、路径遍历 |
每个基于规则的检测函数(`detect_sql_injection`、`detect_eval_usage`、`detect_hardcoded_secrets`)都是独立导出且可测试的。
## 置信度评分
每个发现都带有一个映射到数字权重的 `confidence_source` 标签:
| 来源 | 权重 | 含义 |
|--------|--------|---------|
| `rule_based` | **0.9** | 确定性模式匹配 —— 高确定性 |
| `llm_reasoning` | **0.6** | LLM 生成的发现 —— 中等确定性 |
| `inferred` | **0.3** | 启发式或间接信号 —— 低确定性 |
**每个智能体的分数:** `refined = (base_confidence + avg_issue_weight) / 2`,限制在 `[0.0, 1.0]` 之间。
**汇总分数:** 对智能体分数取平均值,当任何智能体中存在任何高严重性的问题时,应用 +0.1 的提升(上限为 1.0)。
**分歧检测:** 仲裁器会比较各个智能体之间的严重性分布,当某个智能体报告了其他智能体未报告的高严重性发现时,会对该审查进行标记。
## 生产级特性
PRGuard AI 经历了十五个生产阶段的系统化强化:
| 阶段 | 特性 | 描述 |
|-------|---------|-------------|
| 1 | 异步 Webhook 处理 | Webhook 处理程序立即返回 `202 Accepted`;完整的 pipeline 通过 Celery `group` + `chain` 异步运行 |
| 2 | LLM 熔断器 | 所有 LLM 调用上的线程安全熔断器;当熔断器开启时,智能体回退到仅基于规则的模式 |
| 3 | PostgreSQL 审计日志 | SQLAlchemy 异步 ORM 替换 SQLite;Alembic 管理 schema 迁移 |
| 4 | 全面的健康检查 | `/health`、`/health/ready` 和 `/health/live` 端点涵盖 Redis、PostgreSQL、LLM、GitHub、Celery、ChromaDB、磁盘空间、日志记录和仓库缓存 |
| 5 | 集中化配置 | 所有环境变量和常量被整合到带有快速失败验证的 Pydantic `Settings` 模型中 |
| 6 | Redis Token 预算管理 | 通过带有 1 小时 TTL 的 Redis `WATCH` pipeline 进行原子的、基于每个 PR 的 token 统计;在 Redis 故障时提供内存回退 |
| 7 | 仲裁器重试与降级 | 仲裁器使用指数退避重试最多 2 次;如果智能体部分失败,则发布降级的审查 |
| 8 | LLM 输出清理 | 对所有 LLM 输出进行 Pydantic 验证、HTML 转义、去除非打印字符,并限制每个智能体最多 20 个问题 |
| 9 | 生产环境 Redis 强制执行 | `REDIS_FALLBACK_TO_MEMORY` 默认为 `false`;在生产环境中连接失败时快速失败 |
| 10 | 测试覆盖率强制执行 | 在 CI 中强制执行 `pytest-cov` 并设置 70% 的最低阈值 |
| 11 | 结构化 JSON 日志记录 | 所有 API 和 Celery worker 日志均使用 `JsonLogFormatter`;注入 OpenTelemetry trace/span ID;异常堆栈跟踪序列化 |
| 12 | 仓库缓存 | 带有 LRU 淘汰机制(10 GB 上限)的持久化浅克隆缓存;硬链接拷贝到分析沙盒中,实现近乎即时的工作区设置 |
| 13 | Prometheus 指标强化 | 每个智能体的延迟直方图、熔断器状态仪表、token 预算仪表、智能体错误计数器;全部连接到 `/metrics` 端点 |
| 14 | 评估框架 | 将 F1 分数添加到所有评估指标中;提供 `evaluate_dataset_file` 和 `run_evaluation_suite` 辅助函数;通过 `python -m prguard_ai.evaluation.evaluator --dataset` 提供完整的 CLI 入口点 |
| 15 | 覆盖率提升至 76% | 针对结构化日志记录、所有 Pydantic schema、任务注册表、Redis 客户端和所有 Celery 任务函数的新测试文件 —— 总计 203 个测试 |
## 安装说明
### 前置条件
- Python 3.11+
- Docker 和 Docker Compose
- 带有需要监控的仓库的 GitHub 账号
- NVIDIA NIM API key 或 OpenAI API key
### Docker(推荐)
```
git clone https://github.com/purvanshh/PRGuard-AI.git
cd PRGuard-AI
cp .env.example .env
# 使用你的凭证编辑 .env
docker compose up --build
```
这将启动四个容器:
| 容器 | 角色 | 端口 |
|-----------|------|------|
| `prguard-api` | FastAPI webhook 服务器 | 8000 |
| `prguard-worker` | Celery agent worker | — |
| `prguard-redis` | Redis broker 和结果后端 | 6379 |
| `prguard-db` | PostgreSQL 审计数据库 | 5432 |
### 本地开发
```
git clone https://github.com/purvanshh/PRGuard-AI.git
cd PRGuard-AI
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
pip install -e .
cp .env.example .env
# 使用你的凭证编辑 .env
# 启动 Redis 和 PostgreSQL
docker run -d -p 6379:6379 redis:7
docker run -d -p 5432:5432 \
-e POSTGRES_USER=postgres \
-e POSTGRES_PASSWORD=postgres \
-e POSTGRES_DB=prguard \
postgres:15-alpine
# 启动 Celery worker
celery -A prguard_ai.task_queue.celery_app.celery_app worker \
--loglevel=INFO --concurrency=1 \
-Q style,logic,security,arbitrator,celery
# 在单独的终端中,启动 API 服务器
python -m prguard_ai.main
```
服务器运行在 `http://localhost:8000`。
### 运行测试
```
pytest
```
测试套件强制要求 70% 的最低覆盖率阈值。203 个测试涵盖了 diff 解析、智能体分析、置信度评分、熔断器行为、token 预算、健康检查、数据清理、仓库缓存、任务注册表、Celery 任务执行、Pydantic schema、结构化日志记录以及端到端 pipeline。目前的覆盖率为 76%。
## GitHub Webhook 配置
1. 导航到您的仓库 **Settings** > **Webhooks** > **Add webhook**。
2. 配置 webhook:
| 字段 | 值 |
|-------|-------|
| Payload URL | `https://your-server.com/webhook` |
| Content type | `application/json` |
| Secret | 您 `.env` 中的 `GITHUB_WEBHOOK_SECRET` 的值 |
| Events | 仅限 Pull requests |
| Active | Enabled |
3. PRGuard AI 会处理这些 PR 操作:`opened`、`synchronize`、`ready_for_review`。
4. 对于本地开发,使用隧道暴露您的服务器:
ngrok http 8000
使用生成的 HTTPS URL 作为 Payload URL。
### GitHub App 身份验证(可选)
PRGuard AI 支持 GitHub App 身份验证,以实现细粒度的、基于安装范围的权限控制:
```
GITHUB_APP_ID=your_app_id
GITHUB_APP_INSTALLATION_ID=your_installation_id
GITHUB_APP_PRIVATE_KEY=/path/to/private-key.pem
```
如果未提供 App 凭证,客户端将回退到 `GITHUB_TOKEN`。
## 环境变量
| 变量 | 必需 | 默认值 | 描述 |
|----------|----------|---------|-------------|
| `NVIDIA_API_KEY` | 是 | — | 用于 LLM 分析的 NVIDIA NIM API key |
| `OPENAI_API_KEY` | 否 | — | OpenAI API key(如果未设置 `NVIDIA_API_KEY` 时的回退选项) |
| `GITHUB_TOKEN` | 是* | — | GitHub 个人访问 token(如果未配置 App 身份验证时的回退选项) |
| `GITHUB_WEBHOOK_SECRET` | 是 | — | 用于 HMAC-SHA256 签名验证的共享密钥 |
| `REDIS_URL` | 否 | `redis://redis:6379/0` | Redis 连接 URL |
| `DATABASE_URL` | 否 | `postgresql+asyncpg://postgres:postgres@localhost:5432/prguard` | PostgreSQL 连接 URL |
| `CHROMA_PERSIST_DIR` | 否 | `.chroma` | ChromaDB 向量索引持久化目录 |
| `REDIS_FALLBACK_TO_MEMORY` | 否 | `false` | 允许内存 Redis 回退(仅用于本地开发) |
| `REPO_CACHE_DIR` | 否 | `.repo_cache` | 用于持久化浅层仓库克隆的目录 |
| `REPO_CACHE_MAX_SIZE_GB` | 否 | `10.0` | LRU 淘汰前的最大仓库缓存大小 |
| `MAX_FILES_PER_PR` | 否 | `50` | 每个 pull request 分析的最大文件数 |
| `DAILY_LIMIT_USD` | 否 | `5.0` | 以美元为单位的每日 LLM 支出限额| `MAX_TOKENS_PER_PR` | 否 | `8000` | 每个 pull request 消耗的最大 token 数 |
| `LLM_CIRCUIT_FAIL_MAX` | 否 | `5` | LLM 熔断器开启前的失败阈值 |
| `LLM_CIRCUIT_RESET_TIMEOUT` | 否 | `60` | 熔断器尝试恢复前的秒数 |
| `PRGUARD_OFFLINE_MODE` | 否 | `false` | 禁用用于离线测试的外部调用 |
| `GITHUB_APP_ID` | 否 | — | GitHub App ID |
| `GITHUB_APP_INSTALLATION_ID` | 否 | — | GitHub App installation ID |
| `GITHUB_APP_PRIVATE_KEY` | 否 | — | PEM 私钥字符串或文件路径 |
| `ADMIN_TOKEN` | 否 | `admin-secret-token` | 用于 `/config` 管理端点的 Bearer token |
| `OTEL_EXPORTER_OTLP_ENDPOINT` | 否 | `http://localhost:4317` | OpenTelemetry OTLP 收集器端点 |
*除非配置了 GitHub App 身份验证,否则为必需。*
参考:[`.env.example`](.env.example)
## API 端点
| 方法 | 端点 | 描述 |
|--------|----------|-------------|
| `POST` | `/webhook` | GitHub webhook 接收器 —— 经过 HMAC 验证,受重放保护 |
| `GET` | `/review/{pr_id}` | 检索给定 PR 的智能体输出和分析 trace |
| `GET` | `/health` | 聚合依赖项健康检查 |
| `GET` | `/health/ready` | Kubernetes 就绪探针 |
| `GET` | `/health/live` | Kubernetes 存活探针 |
| `GET` | `/metrics` | Prometheus 指标端点 |
| `GET` | `/config` | 仅限管理员的配置视图(需要 bearer token) |
| `WS` | `/stream/{pr_id}` | 用于实时智能体进度事件的 WebSocket 流 |
## 仓库结构
```
prguard-ai/
├── src/
│ └── prguard_ai/
│ ├── agents/ # Style, Logic, Security, Arbitrator, Coordinator agents
│ ├── analysis/ # Diff parsing, AST analysis, repo cache, sandbox, ChromaDB indexing
│ ├── confidence/ # Weighted confidence scoring engine
│ ├── config/ # Pydantic Settings with environment-driven configuration
│ ├── cost/ # LLM budget manager and token tracking
│ ├── dashboard/ # Optional web dashboard
│ ├── db/ # SQLAlchemy models, async session, Redis client
│ ├── gh_client/ # Webhook server, GitHub API client, App authentication
│ ├── llm/ # LLM client with circuit breaker and token budgeting
│ ├── observability/ # Structured JSON logging, OpenTelemetry tracing, Prometheus metrics, event streaming
│ ├── reliability/ # Circuit breaker implementation
│ ├── schemas/ # Pydantic models (AgentOutput, Issue, PullRequestReport, ReviewContext)
│ ├── security/ # Per-repo and per-installation rate limiting
│ └── task_queue/ # Celery app, orchestrator, task definitions, task registry, Redis client
├── alembic/ # Database migration environment and revisions
├── deploy/ # Production Docker Compose and Prometheus configuration
├── docs/ # Architecture documentation, example reviews, runbook
├── fixtures/ # Test fixtures and sample diff data
├── prompts/ # Agent prompt templates
├── scripts/ # Utility and maintenance scripts
├── tests/ # Unit and integration test suite (203 tests, 76% coverage)
├── .github/workflows/ # GitHub Actions CI pipeline
├── Dockerfile # Python 3.11-slim container image
├── docker-compose.yml # Multi-service orchestration (API, worker, Redis, PostgreSQL)
├── pyproject.toml # Project metadata and packaging configuration
├── requirements.txt # Python runtime dependencies
└── .env.example # Environment variable reference template
```
## 安全性
- 对每个传入的 webhook payload 进行 **HMAC-SHA256 验证**
- 通过由 Redis 支持、具有 5 分钟 TTL 的 `X-GitHub-Delivery` 去重机制进行 **重放保护**
- **时间戳验证**,拒绝超过 2 分钟的 payload
- 在 HTTP 层强制执行 5 MB 的 **Payload 大小限制**
- 应用于每个仓库和每个 GitHub App 安装的 **速率限制**
- 防止 worker 队列饱和的 **全局并发控制**
- **沙盒化的仓库克隆**,完成时保证清理
- **LLM 输出清理** —— HTML 转义、去除非打印字符,并设置每个智能体的问题上限
- **绝不记录密钥** —— 结构化日志记录会屏蔽所有敏感的配置值
## 评估
PRGuard AI 包含一个评估框架,用于根据带标签的数据集对智能体准确性进行基准测试:
1. **数据集**:`evaluation/dataset/` 中五个手工标注的 PR diff,其中预期发现的问题被映射到特定的行。
2. **Pipeline**:每个 diff 都会通过所有三个智能体和仲裁器进行处理,以生成检测到的问题集。
3. **指标**:标准的信息检索指标:
| 指标 | 公式 |
|--------|---------|
| 精确率 (Precision) | `TP / (TP + FP)` |
| 召回率 (Recall) | `TP / (TP + FN)` |
| F1 | `2 * P * R / (P + R)` |
| 置信度 (Confidence) | 仲裁器汇总的置信度分数 |
针对单个数据集文件运行评估:
```
python -m prguard_ai.evaluation.evaluator --dataset src/prguard_ai/evaluation/dataset/example_1.json
```
针对完整数据集目录运行评估并将结果写入文件:
```
python -m prguard_ai.evaluation.evaluator \
--dataset src/prguard_ai/evaluation/dataset/ \
--output evaluation_results.json
```
或者直接从 Python 调用 API:
```
from prguard_ai.evaluation.evaluator import evaluate_pr, run_evaluation_suite
from pathlib import Path
# 单个 diff
result = evaluate_pr(diff_text, expected_issues=[{"line": 30, "message": "injection"}])
print(result) # {"precision": 0.8, "recall": 1.0, "f1": 0.89, ...}
# 完整数据集套件
results = run_evaluation_suite(Path("src/prguard_ai/evaluation/dataset/"))
```
## 路线图
- [x] 多语言支持 —— 通过 tree-sitter 支持 Python、Go、TypeScript 和 Rust
- [x] 使用 Celery group/chain 工作流的异步 webhook 处理
- [x] 带有仅限规则回退模式的 LLM 熔断器
- [x] 带有 Alembic 迁移的 PostgreSQL 审计日志
- [x] 带有就绪和存活探针的全面健康检查
- [x] 带有快速失败验证的集中式 Pydantic 设置
- [x] 基于每个 PR 的原子统计的、由 Redis 支持的 token 预算管理
- [x] 仲裁器重试逻辑及在部分智能体失败时的优雅降级
- [x] LLM 输出验证和 HTML 清理
- [x] 带有 OpenTelemetry trace 传播的结构化 JSON 日志记录
- [x] 带有 LRU 淘汰机制的持久化仓库缓存
- [x] Prometheus 指标强化 —— 每个智能体的延迟、熔断器状态、token 预算、错误计数器
- [x] 带有 F1 分数、批量数据集运行器和 CLI 入口点的评估框架
- [x] 203 个测试的测试覆盖率达到 76%(阈值强制要求为 70%)
- [ ] 基于每个仓库的 `.prguard.yml` 配置,用于自定义阈值
- [ ] GitHub App Marketplace 列表,用于一键安装
- [ ] 针对可自动修复发现的 PR 建议 API 集成
- [ ] 增量审查 —— 仅在 `synchronize` 事件上重新分析更改的文件
- [ ] 在带标签的 PR 审查数据集上进行领域特定的 fine-tuning
- [ ] Slack 和 Microsoft Teams 通知集成
- [ ] 通过 Ollama 或 vLLM 后端支持自托管 LLM
- [ ] Dashboard v2 —— 实时审查进度、历史分析、成本跟踪
## 许可证
[MIT](LICENSE)
由 [Purvansh Sahu](https://github.com/purvanshh) 构建 | Scaler School of Technology 与 BITS Pilani 计算机科学三年级 | IIT Madras ML 研究实习生
LLM 后端由 NVIDIA NIM 提供支持
标签:DLL 劫持, Python, 代码审查, 多智能体, 大语言模型, 异步任务, 搜索引擎查询, 无后门, 测试用例, 用户代理, 自动化CI/CD, 自定义请求头, 请求拦截, 逆向工具, 错误基检测, 静态代码分析