用 OpenCode + Oh My OpenCode 搭建 PR 审核机器人
1. 方案概述
本方案使用以下组件搭建 AI 驱动的 PR 审核机器人:
- OpenCode:开源 AI 编码代理,提供 CLI 和 API 能力
- Oh My OpenCode:多模型编排框架,支持自定义命令和智能体
- Gitea MCP Server:官方 MCP 服务器,实现智能 PR 评论
- Gitea Actions:CI/CD 触发机制
1.1 核心特性
| 特性 | 说明 |
|---|---|
自定义 /review 命令 | 一键触发多领域专家审查 |
| 多模型路由 | 安全用 Claude,性能用 GPT-4,各取所长 |
| MCP 智能评论 | 支持多条、内联、上下文感知的 PR 评论 |
| 并行审查 | 多个智能体同时工作,缩短审查时间 |
1.2 架构图
text
┌─────────────────────────────────────────────────────────────┐
│ Gitea PR 触发 │
└─────────────────────────┬───────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ OpenCode + Oh My OpenCode │
│ │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ 自定义 /review 命令 │ │
│ │ (.opencode/command/review.md) │ │
│ │ │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │安全审查 │ │性能审查 │ │架构审查 │ │ │
│ │ │(Claude) │ │(GPT-4) │ │(Gemini) │ │ │
│ │ └─────────┘ └─────────┘ └─────────┘ │ │
│ └───────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ Gitea MCP Server │ │
│ │ - create_issue_comment: 多条评论回复 │ │
│ │ - get_file_content: 获取文件上下文 │ │
│ │ - get_pull_request_by_index: 获取 PR 详情 │ │
│ └───────────────────────────────────────────────────────┘ │
└─────────────────────────┬───────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 智能 PR 评论(多条、内联、上下文感知) │
└─────────────────────────────────────────────────────────────┘2. 前置准备
- 一个 Gitea 仓库(自托管或 Gitea Cloud)
- Anthropic API Key(到 https://console.anthropic.com 注册)
- OpenAI API Key(可选,用于多模型审查)
3. 配置 Secrets
在 Gitea 仓库中添加以下 Secrets:
| Secret 名称 | 说明 |
|---|---|
ANTHROPIC_API_KEY | Anthropic API 密钥 |
OPENAI_API_KEY | OpenAI API 密钥(可选) |
GITEA_TOKEN | Gitea Personal Access Token(需要 repo 权限) |
4. 创建自定义 /review 命令
创建 .opencode/command/review.md 文件,定义审查命令:
markdown
# /review
对代码变更进行全面审查,支持多领域专家并行分析。
## 审查维度
1. **安全性**:SQL注入、XSS、认证绕过、敏感数据泄露
2. **性能**:N+1查询、内存泄漏、不必要的重渲染
3. **架构**:SOLID原则、设计模式、模块耦合度
4. **可维护性**:代码重复、函数复杂度、命名规范
## 审查流程
1. 获取 PR diff 和上下文
2. 并行调用各领域专家智能体
3. 聚合结果,按文件分组
4. 通过 Gitea MCP 发布内联评论
## 输出格式
对于每个问题:
- 文件路径:行号
- 严重程度:🔴 高 / 🟡 中 / 🟢 低
- 问题描述
- 修复建议
## 使用方式
```
/review
/review --focus security
/review --focus performance
/review --files src/auth/,src/api/
```5. 配置 Oh My OpenCode
创建 opencode.json 配置文件:
json
{
"model": "anthropic/claude-sonnet-4-20250514",
"provider": {
"anthropic": { "disabled": false },
"openai": { "models": { "gpt-4o": { "disabled": false } } },
"google": { "models": { "gemini-3.1-pro": { "disabled": false } } }
},
"permission": {
"read": { "*": "allow" },
"edit": { "*": "deny" },
"bash": { "git *": "allow", "*": "deny" }
},
"agent": {
"security-reviewer": {
"name": "security-reviewer",
"description": "安全漏洞审查专家",
"mode": "primary",
"model": "anthropic/claude-sonnet-4-20250514",
"prompt": "你是安全审查专家。检查:SQL注入、XSS、认证绕过、敏感数据泄露、不安全的依赖。每个问题给出严重程度(🔴高/🟡中/🟢低)和修复建议。",
"tools": { "write": false, "edit": false, "bash": false }
},
"performance-reviewer": {
"name": "performance-reviewer",
"description": "性能分析专家",
"mode": "primary",
"model": "openai/gpt-4o",
"prompt": "你是性能分析专家。检查:N+1查询、内存泄漏、不必要的重渲染、低效算法、资源未释放。给出具体的优化建议。",
"tools": { "write": false, "edit": false, "bash": false }
},
"architecture-reviewer": {
"name": "architecture-reviewer",
"description": "架构设计审查专家",
"mode": "primary",
"model": "google/gemini-3.1-pro",
"prompt": "你是架构审查专家。评估:SOLID原则、设计模式、模块耦合度、代码可维护性。给出改进建议。",
"tools": { "write": false, "edit": false, "bash": false }
}
},
"mcp": {
"gitea": {
"type": "local",
"command": "docker",
"args": [
"run", "--rm", "-i",
"-e", "GITEA_HOST",
"-e", "GITEA_TOKEN",
"gitea/gitea-mcp-server:latest",
"-t", "stdio",
"--host", "${GITEA_HOST}",
"--token", "${GITEA_TOKEN}"
]
}
}
}5.1 配置说明
| 配置项 | 说明 |
|---|---|
model | 默认使用的模型 |
provider | 模型提供商配置 |
permission | 权限控制(审查场景设为只读) |
agent | 定义各领域审查智能体 |
mcp.gitea | Gitea MCP Server 配置 |
5.2 Gitea MCP Server 可用工具
| 工具 | 功能 |
|---|---|
create_issue_comment | 创建 PR/Issue 评论 |
get_pull_request_by_index | 获取 PR 详情 |
get_file_content | 获取文件内容 |
list_repo_commits | 查看提交历史 |
create_issue | 创建新 Issue |
list_repo_issues | 列出仓库 Issue |
6. 创建 Gitea Actions 工作流
创建 .gitea/workflows/pr-review.yml:
yaml
name: AI PR Review (/review + MCP)
on:
pull_request:
types: [opened, synchronize, reopened]
jobs:
ai-review:
runs-on: ubuntu-latest
if: gitea.event.pull_request.additions < 500
steps:
- name: Checkout
uses: https://gitea.com/actions/checkout@v6
with:
fetch-depth: 0
- name: Setup Node.js
uses: https://gitea.com/actions/setup-node@v4
with:
node-version: '22'
- name: Install OpenCode
run: npm install -g opencode-ai
- name: Configure authentication
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
GITEA_HOST: ${{ gitea.server_url }}
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
run: |
mkdir -p ~/.local/share/opencode
cat > ~/.local/share/opencode/auth.json << EOF
{
"anthropic": { "type": "api", "key": "$ANTHROPIC_API_KEY" },
"openai": { "type": "api", "key": "$OPENAI_API_KEY" }
}
EOF
- name: Create project files
env:
GITEA_HOST: ${{ gitea.server_url }}
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
run: |
# 创建 /review 命令
mkdir -p .opencode/command
cat > .opencode/command/review.md << 'REVIEW_EOF'
# /review
对代码变更进行全面审查。
## 流程
1. 使用 git diff 获取变更
2. 调用安全、性能、架构审查智能体
3. 通过 Gitea MCP 发布评论
## 输出
按文件分组的问题列表,包含严重程度和修复建议。
REVIEW_EOF
# 创建 opencode.json
cat > opencode.json << CONFIG_EOF
{
"model": "anthropic/claude-sonnet-4-20250514",
"permission": {
"read": { "*": "allow" },
"edit": { "*": "deny" },
"bash": { "git *": "allow", "*": "deny" }
},
"agent": {
"security-reviewer": {
"name": "security-reviewer",
"mode": "primary",
"model": "anthropic/claude-sonnet-4-20250514",
"prompt": "你是安全审查专家。检查安全漏洞,给出严重程度和修复建议。",
"tools": { "write": false, "edit": false, "bash": false }
},
"performance-reviewer": {
"name": "performance-reviewer",
"mode": "primary",
"model": "openai/gpt-4o",
"prompt": "你是性能分析专家。检查性能问题,给出优化建议。",
"tools": { "write": false, "edit": false, "bash": false }
},
"architecture-reviewer": {
"name": "architecture-reviewer",
"mode": "primary",
"model": "anthropic/claude-sonnet-4-20250514",
"prompt": "你是架构审查专家。评估架构设计,给出改进建议。",
"tools": { "write": false, "edit": false, "bash": false }
}
},
"mcp": {
"gitea": {
"type": "local",
"command": "docker",
"args": [
"run", "--rm", "-i",
"-e", "GITEA_HOST",
"-e", "GITEA_TOKEN",
"gitea/gitea-mcp-server:latest",
"-t", "stdio",
"--host", "$GITEA_HOST",
"--token", "$GITEA_TOKEN"
]
}
}
}
CONFIG_EOF
- name: Run /review command
env:
GITEA_HOST: ${{ gitea.server_url }}
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
run: |
# 获取 PR diff
BASE_REF="${{ gitea.event.pull_request.base.ref }}"
git fetch origin "$BASE_REF"
DIFF=$(git diff "origin/$BASE_REF"...HEAD 2>/dev/null || git diff "origin/$BASE_REF"..HEAD)
# 执行审查并使用 MCP 发布评论
opencode run "
执行 /review 命令:
1. 分析以下代码变更
2. 调用安全、性能、架构审查智能体
3. 使用 Gitea MCP 的 create_issue_comment 工具发布审查结果
PR #${{ gitea.event.pull_request.number }}
代码变更:
$DIFF
"7. 提交并测试
bash
git add .opencode/command/review.md opencode.json .gitea/workflows/pr-review.yml
git commit -m "Add AI PR review with /review command and Gitea MCP"
git push创建一个测试 PR,等待 Actions 运行完成,你会在 PR 评论区看到智能审查报告。
8. MCP vs 传统方式对比
| 维度 | 传统方式 | MCP 方式 |
|---|---|---|
| 评论数量 | 单条评论,内容冗长 | 多条评论,按文件分组 |
| 上下文 | 无上下文感知 | 可获取文件内容、提交历史 |
| 交互性 | 静态输出 | 动态交互,可追问 |
| 集成方式 | 手动拼接 API | 标准化 MCP 接口 |
| 内联评论 | 不支持 | 支持针对具体文件行 |
9. 成本控制
9.1 限制触发条件
yaml
on:
pull_request:
types: [opened, synchronize]
paths-ignore:
- '**.md'
- 'docs/**'9.2 限制变更行数
yaml
jobs:
ai-review:
if: gitea.event.pull_request.additions < 5009.3 使用轻量模型
在 opencode.json 中将简单任务分配给更便宜的模型:
json
{
"agent": {
"quick-reviewer": {
"model": "anthropic/claude-haiku-4-20250514",
"prompt": "快速检查明显的安全漏洞和语法错误"
}
}
}10. GitHub Actions 版本
如果使用 GitHub,工作流文件改为 .github/workflows/pr-review.yml:
yaml
name: AI PR Review
on:
pull_request:
types: [opened, synchronize, reopened]
jobs:
ai-review:
runs-on: ubuntu-latest
if: github.event.pull_request.additions < 500
permissions:
contents: read
pull-requests: write
steps:
- uses: actions/checkout@v4
with: { fetch-depth: 0 }
- uses: actions/setup-node@v4
with: { node-version: '22' }
- run: npm install -g opencode-ai
- name: Configure
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
mkdir -p ~/.local/share/opencode
echo "{\"anthropic\":{\"type\":\"api\",\"key\":\"$ANTHROPIC_API_KEY\"}}" > ~/.local/share/opencode/auth.json
- name: Review
run: |
DIFF=$(git diff origin/${{ github.base_ref }}...HEAD)
opencode run "Review this diff for security, performance, and quality issues.
$DIFF"