Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions openspec/changes/multi-agent-parallel-review/.openspec.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-05-19
71 changes: 71 additions & 0 deletions openspec/changes/multi-agent-parallel-review/design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
## Context

opencode-review 当前使用单个 `review` agent 串行审查所有维度。每个维度(code-quality、security、performance、testing、documentation)的 prompt 混合在同一个 prompt 中,由一个 agent 完成全部审查。

OpenCode SDK 原生支持 sub-agent 调度(通过 `task` 工具),可以在一个 agent 中并行 spawn 多个 sub-agent 并收集结果。当前项目已有一个 sub-agent 模式:`review:fixer`。

代码结构:
- `src/agent.ts` — 两个函数 `buildAgentPrompt` 和 `buildFixerPrompt`
- `src/config.ts` — `ReviewConfig` 接口
- `src/index.ts` — 插件入口,注册 agent、tool、event handler
- `src/tools/review-changes.ts` — git diff 采集工具

## Goals / Non-Goals

**Goals:**
- 将 5 个审查维度拆分为独立 sub-agent 并行执行
- 保持输出格式与当前版本一致(critical / suggestion / highlight)
- 自动去重和合并不同维度 agent 的重叠发现
- 支持 `parallel` 配置开关,允许回退到单 agent 模式
- 保持 auto-fix 链功能(critical issue → fixer)

**Non-Goals:**
- 不做 agent 间辩论/争论机制(如 spencermarx 的 discourse phase)——复杂度高,收益不确定
- 不做共识评分(如 calimero 的 severity × agreement)——单 agent per 维度无需共识
- 不做收敛检测/增量审查——属于独立功能,不在本次范围
- 不做 Web dashboard
- 不做 GitHub PR 发帖集成

## Decisions

### Decision 1: 维度 sub-agent 拆分策略

**选择**: 每个审查维度一个独立 sub-agent(`review:dim-code-quality`、`review:dim-security` 等 5 个)

**替代方案**:
- A) 按文件类型拆分(前端/后端/配置)——不利于维度专业化
- B) 按严重性拆分(critical scanner / suggestion scanner)——不同维度的 critical 标准不同
- C) 动态拆分(根据 diff 内容决定 spawn 哪些 agent)——增加复杂度,且用户已通过 `dimensions` 配置表达了偏好

**理由**: 维度拆分与现有配置模型(`dimensions` 数组)天然对齐,用户可以选择启用哪些维度,每个维度 agent 只关注一个领域,prompt 更精准。

### Decision 2: 调度模式

**选择**: 主 review agent 作为调度器,通过 `task` 工具并行 spawn 维度 sub-agent,收集结果后生成统一报告

**理由**: OpenCode 的 `task` 工具支持并行 sub-agent 调度。主 agent 负责调度和聚合,不参与实际审查。这与现有的 `review:fixer` 模式一致。

### Decision 3: 结果聚合策略

**选择**: 主 agent 按顺序收集各维度 sub-agent 的输出,按 severity 分组(critical → suggestion → highlight),去重后输出

**理由**: 简单有效。不同维度 agent 可能对同一代码行有不同视角(如 security 和 performance 都关注某个查询),主 agent 负责合并这些重叠发现。

### Decision 4: prompt 文件组织

**选择**: 新增 `src/dimensions/` 目录,每个维度一个文件(`code-quality.ts`、`security.ts` 等),导出 prompt 构建函数

**理由**: 当前 `agent.ts` 已有 200+ 行,拆分后每个维度文件 30-50 行,可维护性更好。也方便未来独立迭代某个维度的 prompt。

### Decision 5: 向后兼容

**选择**: `config.parallel` 默认 `true`。设为 `false` 时使用当前的单 agent 逻辑

**理由**: 多 agent 应该是更好的默认体验,但需要一个回退选项以应对 sub-agent 调度的问题。

## Risks / Trade-offs

- **[Token 消耗增加]** → 5 个 agent 各自独立运行,token 消耗约为当前的 3-5 倍。缓解:每个维度 agent 的 prompt 更短更精准(不需要包含其他维度的指令),部分抵消增长。用户可通过 `parallel: false` 回退。
- **[延迟增加]** → sub-agent 调度有额外开销。缓解:并行执行,总时间应接近单 agent 中最慢的维度。
- **[结果质量不一致]** → 不同维度 agent 可能对同一段代码给出矛盾建议。缓解:主 agent 在聚合时负责识别和解决矛盾。
- **[sub-agent 数量限制]** → OpenCode 可能对同时运行的 sub-agent 数量有限制。缓解:如果有限制,改为串行 spawn + 流式收集。
28 changes: 28 additions & 0 deletions openspec/changes/multi-agent-parallel-review/proposal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
## Why

当前 opencode-review 使用单一 agent 审查所有维度(code-quality、security、performance、testing、documentation)。竞品分析(见 #2)表明,多 agent 并行审查是行业趋势——spencermarx/open-code-review(179 Stars)使用多 agent 辩论机制,calimero/ai-code-reviewer 使用 5 个专业 agent 共识评分。单 agent 在复杂 diff 中容易遗漏维度、输出笼统,且无法利用 OpenCode 的 subagent 并行能力。现在 OpenCode SDK 已原生支持 sub-agent 调度(`task` 工具),实现多 agent 并行审查的时机已成熟。

## What Changes

- 新增**维度 agent 调度器**:将 5 个审查维度(code-quality、security、performance、testing、documentation)拆分为独立的 sub-agent,并行执行审查
- 新增**结果聚合器**:收集各维度 agent 的审查结果,去重、合并、按严重性排序,输出统一报告
- 修改 `buildAgentPrompt`:review agent 从"执行所有维度审查"变为"调度维度 sub-agent + 聚合结果"
- 新增 5 个维度 sub-agent prompt(`review:code-quality`、`review:security`、`review:performance`、`review:testing`、`review:documentation`)
- 修改 `ReviewConfig`:新增 `parallel` 开关(默认 true),允许回退到单 agent 模式
- 保持向后兼容:`parallel: false` 时行为与当前版本一致

## Capabilities

### New Capabilities
- `parallel-review`: 多维度 sub-agent 并行审查、结果聚合、统一报告生成

### Modified Capabilities
(无现有 specs)

## Impact

- **代码变更**:`src/agent.ts`(拆分为调度 prompt + 5 个维度 prompt)、`src/config.ts`(新增 `parallel` 字段)、`src/index.ts`(注册 5 个 sub-agent)
- **新增文件**:`src/dimensions/` 目录,每个维度一个 prompt 文件
- **Token 消耗**:并行模式 token 消耗会增加(5 个 agent 各自独立运行),但总审查时间缩短(并行 vs 串行)
- **配置**:`.opencode/review.json` 新增可选字段 `"parallel": true`
- **无 breaking change**:默认行为从单 agent 切换为多 agent,但输出格式不变;用户可通过 `parallel: false` 回退
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
## ADDED Requirements

### Requirement: Parallel dimension agents
The system SHALL spawn one sub-agent per enabled review dimension. Each sub-agent SHALL be named `review:dim-<dimension>` (e.g., `review:dim-security`). Sub-agents SHALL be spawned in parallel using the `task` tool.

#### Scenario: All 5 dimensions enabled
- **WHEN** config.dimensions contains all 5 dimensions and config.parallel is true
- **THEN** the system spawns 5 sub-agents (`review:dim-code-quality`, `review:dim-security`, `review:dim-performance`, `review:dim-testing`, `review:dim-documentation`) in parallel

#### Scenario: Subset of dimensions enabled
- **WHEN** config.dimensions contains only ["security", "performance"] and config.parallel is true
- **THEN** the system spawns only 2 sub-agents (`review:dim-security`, `review:dim-performance`)

#### Scenario: Parallel mode disabled
- **WHEN** config.parallel is false
- **THEN** the system uses the current single-agent behavior, reviewing all enabled dimensions in one agent

### Requirement: Dimension agent prompts
Each dimension sub-agent SHALL receive a focused prompt that covers only its assigned dimension. The prompt SHALL instruct the agent to use the `review_changes` tool, analyze the diff from its specific perspective, and output findings in the standard format (critical / suggestion / highlight).

#### Scenario: Security dimension agent prompt
- **WHEN** the `review:dim-security` sub-agent is spawned
- **THEN** its prompt focuses exclusively on security concerns (input validation, injection prevention, auth, sensitive data) and outputs findings with file_path:line_number references

#### Scenario: Performance dimension agent prompt
- **WHEN** the `review:dim-performance` sub-agent is spawned
- **THEN** its prompt focuses exclusively on performance concerns (algorithm complexity, query optimization, memory usage, N+1 queries)

### Requirement: Result aggregation
The main review agent SHALL collect all dimension sub-agent results, merge them into a single report grouped by severity (critical → suggestion → highlight), and deduplicate overlapping findings about the same code location.

#### Scenario: Overlapping findings from different dimensions
- **WHEN** `review:dim-security` reports a critical SQL injection at `db.ts:42` and `review:dim-performance` reports a suggestion about the same query at `db.ts:42`
- **THEN** both findings appear in the merged report under their respective severity sections, with the code location referenced once

#### Scenario: No findings from any dimension
- **WHEN** all dimension sub-agents report no issues
- **THEN** the main agent outputs a clean report with highlights only

### Requirement: Auto-fix chain preservation
The auto-fix chain (critical issue → `review:fixer` sub-agent) SHALL continue to work in parallel mode. The main agent SHALL collect all critical issues from all dimension sub-agents and spawn a single fixer with the combined fix instructions.

#### Scenario: Critical issues from multiple dimensions
- **WHEN** `review:dim-security` finds a SQL injection and `review:dim-code-quality` finds a resource leak, both critical
- **THEN** the main agent spawns one `review:fixer` with fix instructions for both issues

#### Scenario: No critical issues in parallel mode
- **WHEN** all dimension sub-agents report zero critical issues
- **THEN** no fixer sub-agent is spawned

### Requirement: Parallel config option
The `ReviewConfig` interface SHALL include an optional `parallel` boolean field (default: `true`). When `false`, the plugin reverts to single-agent mode.

#### Scenario: Config with parallel true
- **WHEN** `.opencode/review.json` contains `"parallel": true` or omits the field
- **THEN** multi-agent parallel review is used

#### Scenario: Config with parallel false
- **WHEN** `.opencode/review.json` contains `"parallel": false`
- **THEN** single-agent review is used (current behavior)

#### Scenario: Config without parallel field
- **WHEN** `.opencode/review.json` does not contain a `parallel` field
- **THEN** multi-agent parallel review is used (default is true)

### Requirement: Dimension prompt files
Each dimension SHALL have its own prompt module file under `src/dimensions/`, exporting a function that returns the dimension-specific prompt string. Files SHALL follow the naming convention `<dimension>.ts` (e.g., `security.ts`, `code-quality.ts`).

#### Scenario: Prompt function returns correct content
- **WHEN** `buildDimensionPrompt("security", config)` is called
- **THEN** it returns a prompt string focused on security review, using the configured language (zh/en)

### Requirement: Output format consistency
The final merged report output format SHALL be identical to the current single-agent format (Overall Assessment → Critical Issues → Suggestions → Highlights), regardless of parallel mode.

#### Scenario: Output format in parallel mode
- **WHEN** parallel review completes with findings
- **THEN** the output uses the same section headers and emoji markers (🔴 🟡 ✅) as single-agent mode

#### Scenario: Language consistency in parallel mode
- **WHEN** config.language is "zh"
- **THEN** the aggregated report and all dimension sub-agent outputs are in Chinese
37 changes: 37 additions & 0 deletions openspec/changes/multi-agent-parallel-review/tasks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
## 1. Config 扩展

- [x] 1.1 在 `ReviewConfig` 接口中添加 `parallel?: boolean` 字段,默认 `true`
- [x] 1.2 在 `DEFAULT_CONFIG` 中添加 `parallel: true`
- [x] 1.3 验证 `loadConfig` 正确合并 `parallel` 字段(全局 + 项目配置)

## 2. 维度 Prompt 文件

- [x] 2.1 创建 `src/dimensions/` 目录
- [x] 2.2 创建 `src/dimensions/code-quality.ts` — 代码质量维度 prompt 构建函数
- [x] 2.3 创建 `src/dimensions/security.ts` — 安全性维度 prompt 构建函数
- [x] 2.4 创建 `src/dimensions/performance.ts` — 性能维度 prompt 构建函数
- [x] 2.5 创建 `src/dimensions/testing.ts` — 测试维度 prompt 构建函数
- [x] 2.6 创建 `src/dimensions/documentation.ts` — 文档维度 prompt 构建函数
- [x] 2.7 创建 `src/dimensions/index.ts` — 导出统一的 `getDimensionPrompts(config)` 函数,返回 `{ name, agentName, prompt }[]`
- [x] 2.8 验证每个维度 prompt 包含:使用 review_changes 工具的指令、维度专注的审查要点、标准输出格式(critical / suggestion / highlight)、中英双语支持

## 3. 主 Agent Prompt 重构

- [x] 3.1 修改 `buildAgentPrompt` 添加并行模式分支:当 `parallel: true` 时生成调度器 prompt(spawn sub-agents + 聚合结果),当 `parallel: false` 时保持当前逻辑
- [x] 3.2 调度器 prompt 需包含:对每个启用维度调用 `task` 工具 spawn `review:dim-<dimension>` sub-agent、收集所有结果、按 severity 分组合并、去重同位置发现、输出统一报告格式
- [x] 3.3 调度器 prompt 需包含 auto-fix 指令:收集所有 critical issues 后 spawn 单个 `review:fixer`

## 4. 插件入口更新

- [x] 4.1 在 `src/index.ts` 中注册 5 个维度 sub-agent(`review:dim-code-quality` 等),每个设置 `mode: "subagent"`、只读权限、对应维度 prompt
- [x] 4.2 维度 sub-agent 的注册需根据 config.dimensions 动态生成(只注册启用的维度)
- [x] 4.3 验证 `review` agent 和 `review:fixer` 的注册不受影响

## 5. 集成验证

- [ ] 5.1 验证并行模式:配置 `parallel: true`,运行 `/review`,确认 5 个维度 sub-agent 并行执行,结果正确聚合(需在 OpenCode 中手动验证)
- [ ] 5.2 验证回退模式:配置 `parallel: false`,运行 `/review`,确认行为与当前版本一致(需在 OpenCode 中手动验证)
- [ ] 5.3 验证 auto-fix 链:并行模式下触发 critical issue,确认 fixer 正确接收合并后的修复指令(需在 OpenCode 中手动验证)
- [ ] 5.4 验证部分维度:配置只启用 `["security", "performance"]`,确认只 spawn 2 个 sub-agent(需在 OpenCode 中手动验证)
- [ ] 5.5 验证中英双语:切换 `language: "en"` 后确认所有维度 prompt 输出英文(需在 OpenCode 中手动验证)
- [ ] 5.6 验证 idle 自动审查:并行模式下 session idle 自动触发审查(需在 OpenCode 中手动验证)
108 changes: 108 additions & 0 deletions src/agent.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { ReviewConfig } from "./config.ts"
import { getDimensionPrompts } from "./dimensions/index.ts"

const DIMENSION_LABELS: Record<string, { zh: string; en: string }> = {
"code-quality": {
Expand Down Expand Up @@ -38,7 +39,114 @@ function buildCustomRules(rules: string[]): string {
return `\n### Custom Rules\n${rules.map((r) => `- ${r}`).join("\n")}`
}

const REPORT_FORMAT: Record<string, string> = {
zh: `## 输出格式

\`\`\`
## 审查结果

### 总体评价
[简要描述代码质量]

### 关键问题 :red_circle:
[必须修复的问题,引用 file_path:line_number]

### 建议改进 :yellow_circle:
[可选的优化建议,引用 file_path:line_number]

### 亮点 :white_check_mark:
[代码中做得好的地方]
\`\`\``,
en: `## Output Format

\`\`\`
## Review Results

### Overall Assessment
[Brief description of code quality]

### Critical Issues :red_circle:
[Must-fix issues, reference file_path:line_number]

### Suggestions :yellow_circle:
[Optional improvements, reference file_path:line_number]

### Highlights :white_check_mark:
[Good practices found in the code]
\`\`\``,
}

const AUTO_FIX_INSTRUCTION: Record<string, string> = {
zh: `## 自动修复

如果任何维度代理发现了关键问题(🔴),你必须:
1. 汇总所有关键问题
2. 使用 \`task\` 工具 spawn \`review:fixer\` 子代理,传入所有关键问题的修复指令
3. 等待 fixer 完成修复`,
en: `## Auto-Fix

If any dimension agent finds critical issues (🔴), you MUST:
1. Collect all critical issues across dimensions
2. Use the \`task\` tool to spawn a \`review:fixer\` sub-agent with combined fix instructions
3. Wait for the fixer to complete`,
}

export function buildAgentPrompt(config: ReviewConfig): string {
if (config.parallel) {
return buildParallelPrompt(config)
}
return buildSinglePrompt(config)
}

function buildParallelPrompt(config: ReviewConfig): string {
const lang = config.language === "zh" ? "zh" : "en"
const dimensions = getDimensionPrompts(config)
const dimensionList = dimensions.map((d) => `- ${d.agentName}: ${d.name}`).join("\n")

if (lang === "zh") {
return `你是一个代码审查调度器。你的任务是并行调度多个维度审查子代理,收集结果,并生成统一报告。

## 可用维度代理
${dimensionList}

## 工作流程
1. 使用 \`review_changes\` 工具获取 diff(默认 scope 为 staged)
2. 对每个启用的维度,使用 \`task\` 工具 spawn 对应的子代理:
- agent: \`<维度代理名>\`
- message: "请审查以下代码变更" + diff 摘要
3. 收集所有维度代理的结果
4. 按严重性分类合并结果:
- 关键问题(🔴)→ 建议改进(🟡)→ 亮点(✅)
5. 对同一代码位置的重复发现进行合并
6. 输出统一报告

${REPORT_FORMAT.zh}

${AUTO_FIX_INSTRUCTION.zh}`
}

return `You are a code review orchestrator. Your task is to dispatch multiple dimension review sub-agents in parallel, collect results, and produce a unified report.

## Available Dimension Agents
${dimensionList}

## Workflow
1. Use the \`review_changes\` tool to get the diff (default scope is "staged")
2. For each enabled dimension, use the \`task\` tool to spawn the corresponding sub-agent:
- agent: \`<dimension agent name>\`
- message: "Review the following code changes" + diff summary
3. Collect all dimension agent results
4. Merge results by severity:
- Critical (🔴) → Suggestions (🟡) → Highlights (✅)
5. Deduplicate overlapping findings at the same code location
6. Output a unified report

${REPORT_FORMAT.en}

${AUTO_FIX_INSTRUCTION.en}`
}

function buildSinglePrompt(config: ReviewConfig): string {
const isZh = config.language === "zh"

if (isZh) {
Expand Down
2 changes: 2 additions & 0 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export interface ReviewConfig {
cooldown_seconds: number
}
custom_rules: string[]
parallel: boolean
}

const DEFAULT_CONFIG: ReviewConfig = {
Expand All @@ -28,6 +29,7 @@ const DEFAULT_CONFIG: ReviewConfig = {
cooldown_seconds: 120,
},
custom_rules: [],
parallel: true,
}

const CONFIG_FILENAME = "review.json"
Expand Down
Loading