内容
# PR-Distiller
> 从团队的 PR 代码评审历史中提取可重用的编码规则,并实时为 AI 编码助手提供服务。
PR-Distiller 爬取 GitHub 仓库中的合并拉取请求评审评论,使用大型语言模型(LLM)对通用编码规则进行分类和提取(包括安全性、架构、性能、正确性、代码风格和测试等),通过 ChromaDB 矢量相似性进行语义重复数据删除,并通过模型上下文协议(MCP)服务器提供这些规则。Cursor 和 Claude Code 等 IDE 代理在每次代码更改时查询 MCP 服务器,接收基于团队实际评审历史的项目特定约束。
## 工作原理
```mermaid
flowchart LR
GH[GitHub 拉取请求]
CR[深度爬取器]
SR[安全信息脱敏器]
LLM[LLM 提取器]
SF[语义融合器]
DB[(ChromaDB 数据库)]
MCP[MCP 服务器]
IDE[IDE 代理\nCursor / Claude Code]
GH -->|评审评论| CR
CR -->|原始评论| SR
SR -->|脱敏文本| LLM
LLM -->|提取规则 JSON| SF
SF -->|重复数据删除规则| DB
DB -->|矢量查询| MCP
MCP -->|排名约束| IDE
```
1. **深度爬取器** — 通过 REST API 从 GitHub 爬取拉取请求评审评论,根据关键词启发式和机器人排除列表进行过滤。支持通过每个仓库的游标检查点进行增量爬取。
2. **安全信息脱敏器** — 在文本到达 LLM 之前,运行 Microsoft Presidio PII 检测和自定义正则表达式模式(AWS 密钥、令牌)。
3. **LLM 提取器** — 将每个评论分类为 `EXTRACT` 或 `SKIP`,然后提取结构化 JSON:标题、描述、强制提示、类别、置信度分数和文件路径作用域模式。
4. **语义融合器** — 查询 ChromaDB 以获取矢量相似的现有规则(余弦距离阈值 0.32)。重复命中由 LLM 合并,而不是存储为冗余条目。合并规则的出现次数累积。
5. **ChromaDB 数据库** — 持久存储规则及其完整元数据。规则最初处于 `needs_review` 状态;当置信度 >= 0.80 或在仪表板中获得人工批准时,它们会自动晋升为 `active` 状态。
6. **MCP 服务器** — 一个 TypeScript `@modelcontextprotocol/sdk` 服务器,暴露 `query_architectural_constraints` 接口。IDE 发送活动代码差异;服务器返回根据出现密度排名的 top-k 个语义相关规则。
## 功能
- 自动 PR 评论爬取,带有增量游标检查点(无需重新处理)
- 两阶段 LLM 管道:快速分类通道,然后是结构化提取
- 在调用 LLM 之前,通过 Microsoft Presidio 进行 PII 和机密信息脱敏
- 使用 ChromaDB 余弦距离和 LLM 辅助规则合并进行语义重复数据删除
- 规则审查工作流:`needs_review` → `active`(自动或手动),`blocked`
- 按规则跟踪效果:已提供、已应用、已驳回、接受率
- 自动提升具有 >= 5 次提供和 > 70% 接受率的规则
- 文件路径作用域:规则仅匹配文件路径满足配置的 glob 模式
- GitHub webhook 集成:触发每个合并的拉取请求的增量提取
- 导出到多种格式:系统提示、Claude 技能 Markdown、OpenAI 函数规范、AGENTS.md
- 通过 tree-sitter 支持多语言 AST(Python、TypeScript、JavaScript、Go、Rust)
- Next.js 仪表板,用于规则浏览、手动批准和管道配置
- 通过 LiteLLM 实现 LLM 无关性:Ollama(默认)、vLLM、OpenAI、Anthropic、Google、OpenRouter
## 快速开始
选择适合您机器的路径。后台 + 网页界面始终在 Docker 中运行;仅 LLM 放置位置不同。
### 常见步骤(所有平台)
```bash
git clone https://github.com/rendermani/PR-Distiller.git
cd PR-Distiller
cp .env.example .env # 至少设置 GITHUB_TOKEN
make preflight # 检测操作系统 + 可用的加速器
```
### macOS(Apple Silicon)
Docker on Mac 无法访问 GPU,因此 LLM 在主机上运行。macOS 上的 Ollama 使用 Metal 和统一内存自动实现 — 完整的 GPU 加速,无需配置。
```bash
brew install ollama # 或从 https://ollama.com 下载
ollama serve & # 或启动 Ollama.app
make run-model # 拉取 qwen3:8b (~5.2GB)
make up # 在 Docker 中启动后台 + 网页界面
```
### Windows — 主机 Ollama(WSL2 或原生)
```powershell
# 从 https://ollama.com/download 安装 Ollama(原生 Windows 安装程序)
ollama serve # 在后台自动运行
make run-model
make up # 将 Docker 指向主机 Ollama
```
> 在 WSL2 或 Git Bash 中运行 `make`。Docker Desktop 必须正在运行。
### Linux + NVIDIA GPU — 全部在 Docker 中
```bash
# 需要 NVIDIA Container Toolkit:https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/
make up-linux-gpu # 后台 + 网页界面 + Ollama(GPU)全部在 Docker 中
make run-model
```
### Linux / 任意操作系统 — 仅 CPU 备用
```bash
make up-cpu # 后台 + 网页界面 + Ollama(CPU)全部在 Docker 中
make run-model
```
### 完成
在 [http://localhost:4096](http://localhost:4096) 打开仪表板。输入 `owner/repo` 格式的仓库,点击 **Start** 以触发爬取。
要停止所有操作:`make down`。
## 架构
```mermaid
flowchart TB
subgraph Docker Compose
OL[Ollama\nlocalhost:11434]
BE[后台\nFastAPI + ChromaDB\nlocalhost:8923]
UI[网页界面\nNext.js 仪表板\nlocalhost:4096]
MCP[MCP 服务器\nstdio 传输]
end
IDE[IDE 代理] -->|stdio MCP| MCP
MCP -->|HTTP /api/mcp/query| BE
UI -->|HTTP /api/*| BE
BE -->|HTTP OpenAI-compat| OL
```
所有服务都容器化。MCP 服务器使用 stdio 传输,按需启动(`docker compose run --rm mcp-server`),而不是作为持久服务。
## 配置
所有配置均通过环境变量进行。复制 `.env.example` 到 `.env` 以供首次运行使用。运行时设置(重复数据删除阈值、自动批准置信度、爬取深度)也可以通过仪表板的设置面板进行调整,并持久存储到 `data/config.json`。
| 变量 | 默认值 | 描述 |
|---|---|---|
| `GITHUB_TOKEN` | — | GitHub 个人访问令牌,具有 `repo` 读取权限。爬取所需。 |
| `LLM_MODEL` | `ollama/qwen3:8b` | LiteLLM 模型字符串。必须包括提供者前缀(`ollama/`、`openai/`、`anthropic/` 等)。 |
| `LLM_API_BASE` | `http://host.docker.internal:11434/v1` | LLM 的 OpenAI 兼容基 URL。当使用 Ollama 容器叠加层时,自动覆盖为 `http://ollama:11434/v1`。 |
| `LLM_API_KEY` | — | 外部提供商(OpenAI、Anthropic 等)的 API 密钥。 |
| `EMBEDDING_MODEL` | `BAAI/bge-base-en-v1.5` | 用于 ChromaDB 嵌入的句子转换器模型。 |
| `FERNET_KEY` | — | 用于加密存储令牌的 32 字节 base64 Fernet 密钥。 |
| `API_AUTH_TOKEN` | auto | 在变异端点上强制执行的 Bearer 令牌(`/api/config`、`/api/jobs/*`、`/api/rules*`、`/api/admin/*`)。在首次启动时自动生成,并持久存储到 `backend/data/.api_token`(chmod 600)。网页界面以只读方式挂载相同的卷,因此其服务器端代理透明地附加令牌 — 令牌从未到达浏览器。设置此环境变量以固定特定值。 |
| `BACKEND_INTERNAL_URL` | `http://backend:8923` | Next.js `/api/proxy/*` 路由处理程序的服务器端目标 URL。当在 Docker 外运行 Next.js 服务器时,请覆盖此设置。 |
| `GITHUB_WEBHOOK_SECRET` | — | 用于验证 GitHub webhook 有效载荷的 HMAC 密钥。 |
| `HUGGINGFACE_HUB_TOKEN` | — | 可选。需要此令牌才能访问受限模型;建议使用此令牌以避免速率限制。在 Vault 页面上镜像此令牌。 |
| `WEBHOOK_PUBLIC_URL` | — | 后台的可公开访问的 URL。Vault 页面使用此 URL 渲染 GitHub webhook URL。 |
| `OPENAI_API_KEY`、`ANTHROPIC_API_KEY`、`GOOGLE_API_KEY`、`OPENROUTER_API_KEY` | — | 提供商密钥的可选环境变量覆盖;Vault 页面是替代方案。 |
| `DEDUP_DISTANCE_THRESHOLD` | `0.32` | 低于此余弦距离阈值时,认为两个规则是重复的。 |
| `AUTO_APPROVE_CONFIDENCE` | `0.80` | 规则的 LLM 置信度得分高于此阈值时自动批准。 |
| `WEBHOOK_MIN_INTERVAL` | `60` | 每个仓库的 webhook 触发作业之间的最小秒数。 |
| `API_PORT` | `8923` | FastAPI 后台的主机端口。 |
| `WEB_PORT` | `4096` | Next.js 仪表板的主机端口。 |
| `OLLAMA_PORT` | `11434` | Ollama 服务的主机端口。 |
### 加密保险库
用户提供的凭证存储在 **加密保险库** 页面,网址为 [http://localhost:4096/secrets](http://localhost:4096/secrets):
- GitHub 个人访问令牌
- HuggingFace 令牌(可选)
- LLM 提供商 API 密钥(OpenAI、Anthropic、Google、OpenRouter)
- GitHub webhook URL + 密钥(显示和复制)
值在 `backend/data/config.json` 中以 Fernet 加密方式存储。设置任何列出的环境变量会使相应的输入变为只读,并标记为 `from environment` — 环境变量的值优先。这允许您与 HashiCorp Vault、AWS Secrets Manager 或其他秘密注入设置集成。
## MCP 服务器集成
将 MCP 服务器添加到您的 IDE 配置中。服务器通过 stdio 进行通信。
**Cursor** (`~/.cursor/mcp.json`):
```json
{
"mcpServers": {
"pr-distiller": {
"command": "docker",
"args": ["compose", "-f", "/path/to/PR-Distiller/docker-compose.yml",
"run", "--rm", "mcp-server"],
"env": { "PR_DISTILLER_API_URL": "http://localhost:8923" }
}
}
}
```
**Claude Code** (项目中的 `.claude/mcp.json`):
```json
{
"mcpServers": {
"pr-distiller": {
"command": "docker",
"args": ["compose", "-f", "/path/to/PR-Distiller/docker-compose.yml",
"run", "--rm", "mcp-server"]
}
}
}
```
服务器公开一个工具:`query_architectural_constraints`。传递活动代码差异;可选传递 `file_path` 以限制结果为路径作用域规则。
## 技术栈
- **后台**: Python 3.11、FastAPI、ChromaDB、LiteLLM、Presidio、tree-sitter
- **前端**: Next.js 14、React、Tailwind CSS
- **MCP 服务器**: TypeScript、`@modelcontextprotocol/sdk`、Zod
- **LLM(默认)**: Ollama with `qwen3:8b` (~5.2GB); 支持更大的 Qwen3/Qwen3-Coder/Gemma 4/Llama 4 和 vLLM、OpenAI、Anthropic、Google Gemini、OpenRouter via LiteLLM
- **嵌入**: `BAAI/bge-base-en-v1.5` (sentence-transformers,在后台容器中本地运行)
- **AST 解析**: Python、TypeScript、JavaScript、Go、Rust 的 tree-sitter 语法
- **容器化**: Docker Compose,具有可选的 NVIDIA GPU 覆盖
## 许可证
商业源代码许可证 1.1。完整条款见 [LICENSE](LICENSE)。
免费用于非商业用途。转换为 Apache License 2.0 于 2030-04-13 生效。