Files
sanguo_moziplus_v2/docs/design/archive-2.0/topic3-challenge-review-proposal.md
T
2026-05-28 08:45:47 +08:00

907 lines
37 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 课题3 设计方案:挑战/评审体系 + 质量门控结构化
**作者**: 庞统士元
**日期**: 2026-05-15
**状态**: 方案待确认
**前置**: 课题1(AI决策者参与)、课题2(事件驱动+上下文传递)已结题
---
## 1. 设计目标
课题1已定义了"谁来判断"(双轨制:Daemon系统保护 + Coordinator AI决策)和"判断什么"must_haves三件套、幻觉门控、Scope Guard)。课题2定义了"怎么触发判断"Tick+Inbox事件驱动、Handoff Comment无缝接手)。
**课题3要解决的问题是:判断的结果怎么记录、怎么协商、怎么流转。**
具体来说:
1. 评审结果怎么结构化存储(不是散落在 comments 里的自然语言)
2. 挑战/评审的协商流程怎么设计(几轮、升级条件、对抗模式)
3. 评审体系和现有状态机(pending→working→review→done)怎么对齐
## 2. v1.0 三层体系的问题
| 问题 | v1.0 做法 | 根因 |
|------|----------|------|
| PAV自律形同虚设 | Plan→Act→Verify 靠 Skill 文本约束 | Skill 是"菜单"不是"触发器"Agent 可忽略 |
| 每个节点都审过重 | 司马懿审所有节点 | 没有分级,简单任务和复杂任务同一个审查标准 |
| 方案阶段没审查 | 只审产出不审方案 | 编码前的设计方案没有独立审查 |
| 评审结果不结构化 | 司马懿写自然语言评论 | 无法机器判断"通过还是没通过",只能人读 |
| 司马懿角色重叠 | 节点审一次 + 终审一次 | 重复劳动 |
## 3. 设计决策
### D3-1:评审体系由三层改为"分级 + 流水线"
> **参考实践**
> - **superpowers**:串行双审(spec reviewer → code quality reviewer),先审方案再审代码
> - **TradingAgents**:多空对抗辩论(Bull vs Bear → Research Manager 裁决)
> - **OpenAI Agent SDK**Guardrail 是 tripwire(检测到违规立即中断,不是建议)
> - **Hermes v0.13**Comment 的 metadata JSON 承载结构化数据(changed_files / tests_run / diff_path
> - **v1.0 PRD**review_result JSON 结构(verdict + issues + round + max_rounds
> - **GitHub PR Review**APPROVE / REQUEST_CHANGES / COMMENT 三种明确 verdict
**核心思路**:不搞三层并行,而是每个任务按风险等级走不同的审查流水线。
| 任务风险等级 | 流水线 | 方案审查 | 产出审查 | 审查模式 | 最大轮次 |
|------------|--------|---------|---------|---------|---------|
| **high**(部署/策略/资金) | 三阶段 | ✅ 独立审查 | ✅ 独立审查 + Guardrail | 对抗辩论 | 5 |
| **standard**(编码/设计) | 二阶段 | ✅ 方案过挑战 | ✅ 产出过挑战 | 单审 | 3 |
| **low**(文档/格式化/搬运) | 一阶段 | ❌ 跳过 | ⚡ Guardrail 自动检查 | 自动 | 0 |
| **research**(调研/分析) | 一阶段 | ❌ 跳过 | ✅ 庞统确认方向 | 单审 | 2 |
**和课题1的分级审查矩阵对齐**:课题1的 §9.5 已定义了四级风险等级和审查深度,课题3 补充的是每个等级内部的具体流程。
### D3-2:评审三阶段流水线(high/standard 任务)
> **参考实践**
> - **superpowers**implementer → spec reviewer(必须通过) → code quality reviewer
> - **TradingAgents**:多空辩论 + Manager 裁决,用 `add_conditional_edges` 实现
> - **OpenAI Agent SDK**OutputGuardrail 是并行运行的轻量 AI Agent,不是 if-else 规则
**阶段 1:方案审查(Plan Review**——只对 high/standard 任务
```
执行者提交方案(scope_declaration)到黑板 decisions 表
挑战者审查方案
├── high:对抗辩论(正方 vs 反方 → 庞统裁决)
└── standard:单审(指定挑战者,默认司马懿)
通过 → 进入执行阶段
未通过 → 协商修改(最多 max_rounds 轮)
└── 超轮次 → 升级用户
```
方案审查和课题1的 Scope Guard 关系:
- Scope GuardL2 sub 异步检查)是吹哨人——发现偏离写 observation
- 方案审查(L3 Agent 正式审查)是正式评审——通过/打回有 verdict
- 两者互补:Scope Guard 是过程中的软检查,方案审查是阶段门
**阶段 2:执行 + Guardrail 自动检查**——所有任务
```
执行者按方案执行
每次写 output 时,Daemon 自动触发 Guardrail
├── L1 机械检查(文件存在、JSON 格式、字段非空)→ 不通过直接打回
├── L2 轻量 AI 检查(Schema 校验、artifacts 路径验证)→ 不通过写 observation
└── L3 安全红线(tripwire:如直接操作生产环境)→ 立即中断
Guardrail 通过 → 进入产出审查
Guardrail 不通过 → 自动打回(tripwire 直接 block
```
**阶段 3:产出审查(Output Review**——high/standard 任务
```
执行者提交产出到黑板 outputs 表
挑战者审查产出(质量/完整性/与方案一致性)
评审结果结构化记录到 reviews 表
通过 → status: review → done
未通过 → status: review → working(打回重做)
└── 协商在 comments 表讨论
└── 超轮次 → 升级用户
```
### D3-3:评审结果结构化存储(reviews 表)
> **参考实践**
> - **Hermes**Comment 的 metadata JSON 承载结构化数据
> - **SWE-agent**Trajectory 线性追加,不修改历史
> - **v1.0 PRD**review_result JSONverdict + issues + round
> - **GitHub PR Review**APPROVE / REQUEST_CHANGES / COMMENT 三种 verdict
> - **Control Center**artifacts 按 stage 组织,支持阶段回退
**设计原则**
1. **追加写入不修改历史**(SWE-agent 模式)——每轮评审是新记录
2. **黑板索引 + 文件详情**(课题2 原则)——黑板存摘要,文件存详情
3. **结构化 verdict**GitHub PR Review 模式)——枚举值,不是自然语言
4. **关联产出物**Control Center 模式)——review 关联到具体 output
```sql
-- ===== 评审结果表 =====
CREATE TABLE IF NOT EXISTS reviews (
id TEXT PRIMARY KEY, -- rev-001
task_id TEXT NOT NULL,
output_id TEXT, -- 关联产出物(outputs 表)
reviewer TEXT NOT NULL, -- 审查者 agent id 或 'system'
review_type TEXT NOT NULL,
CHECK (review_type IN ('plan_review', 'output_review', 'guardrail', 'final_review')),
-- 评审结论(必须是枚举)
verdict TEXT NOT NULL,
CHECK (verdict IN ('approved', 'rejected', 'needs_revision')),
-- 信心度(可选)
confidence REAL, -- 0.0-1.0
-- 协商轮次
round INTEGER NOT NULL DEFAULT 1,
max_rounds INTEGER NOT NULL DEFAULT 3,
consensus_reached BOOLEAN DEFAULT FALSE,
-- 摘要(黑板索引)
summary TEXT NOT NULL, -- 一句话结论(人可读)
-- 详情路径
detail_path TEXT, -- 完整评审报告文件
created_at TEXT NOT NULL DEFAULT (datetime('now')),
FOREIGN KEY (task_id) REFERENCES tasks(id),
FOREIGN KEY (output_id) REFERENCES outputs(id)
);
CREATE INDEX IF NOT EXISTS idx_reviews_task ON reviews(task_id);
CREATE INDEX IF NOT EXISTS idx_reviews_output ON reviews(output_id);
```
**评审详情文件**detail_path 指向):
```json
{
"review_id": "rev-001",
"task_id": "task-001",
"output_id": "out-001",
"reviewer": "simayi-challenger",
"review_type": "output_review",
"verdict": "needs_revision",
"confidence": 0.65,
"round": 1,
"max_rounds": 3,
"summary": "代码逻辑正确但缺少错误处理和单元测试",
"issues": [
{
"id": "iss-001",
"severity": "critical",
"category": "correctness",
"location": "src/trading.py:42",
"description": "未处理网络超时异常",
"suggestion": "添加 try-except 包装,设置 30s 超时"
}
],
"positives": ["代码结构清晰,职责分离做得好"],
"metadata": {
"files_reviewed": ["src/trading.py", "src/utils.py"],
"total_lines_reviewed": 150
}
}
```
### D3-4Guardrail 检查结果也入 reviews 表
> **参考实践**
> - **OpenAI Agent SDK**Guardrail 的 tripwire_triggered 是结构化输出
> - **Hermes 幻觉门控**:系统验证产出是否真实存在
Guardrail 自动检查结果存入 reviews 表(`reviewer='system'`, `review_type='guardrail'`):
```json
{
"review_id": "rev-auto-001",
"reviewer": "system",
"review_type": "guardrail",
"verdict": "rejected",
"summary": "Guardrail 检查失败:产出文件不存在",
"issues": [
{
"severity": "blocking",
"description": "产出文件不存在: output.md"
}
]
}
```
**和课题1的 Guardrail 吹哨人机制对齐**
- L1 机械检查失败 → 直接入 reviews 表(verdict=rejected+ 打回
- L2 轻量 AI 检查发现问题 → 写 observation(课题1设计)+ 入 reviews 表(verdict=needs_revision
- L3 tripwire → 直接入 reviews 表(verdict=rejected+ block 任务
### D3-5:对抗辩论模式(high 风险任务)
> **参考实践**
> - **TradingAgents**Bull Researcher vs Bear Researcher → Research Manager 裁决
> - **MetaGPT**Engineer Agent 隐式 supervisor,按 SOP 产出
> - **oh-my-claudecode Critic**Critic 被禁止 Write/Edit 工具,只能读和评论
**high 风险任务的方案审查和产出审查都走对抗模式**
```
方案审查(对抗模式):
正方(执行者):写 scope_declaration,论证方案可行性
反方(挑战者池中的一人):找方案漏洞、风险、遗漏
庞统裁决:综合双方观点,做最终判断
├── 认可正方 → 方案通过
├── 认可反方 → 方案打回
└── 综合意见 → 要求修改后重新辩论
```
**挑战者池**:不是固定司马懿一个人,而是按任务类型选择:
- 编码任务 → 司马懿
- 风控任务 → 关羽
- 数据任务 → 赵云(数据质量视角)
- 部署任务 → 姜维
庞统在黑板上创建任务时指定 reviewer(`assigned_by` 字段已有)。
### D3-6:协商流程与状态机对齐
> **参考实践**
> - **superpowers**implementer 报告四种状态(task_completed / task_completed_with_notes / task_blocked / task_failed
> - **Hermes**block with reason 前缀约定(review-required: / blocked-by:
> - **v1.0 PRD**:三轮协商上限,超轮次升级用户
**现有状态机**`pending → claimed → working → review → done`
**和评审流水线的对齐**
```
pending → claimed → working
[方案审查]high/standard
├── approved → 继续 working
└── needs_revision → 继续 working(修改方案)
└── 超轮次 → 升级用户
[执行 + Guardrail]
├── guardrail rejected → back to working(自动打回)
└── guardrail passed → 继续
写 output → status: review
[产出审查]high/standard
├── approved → status: done
├── needs_revision → status: working(协商在 comments
└── rejected → status: working(打回重做)
└── 超轮次 → 升级用户
low 风险任务:working → [Guardrail 自动检查] → done(跳过 review 状态)
research 任务:working → [庞统确认] → review → done
```
**新状态机扩展**(在现有 8 状态基础上,不增加新状态):
| 状态转换 | 触发条件 | 对应阶段 |
|---------|---------|---------|
| working → working | 方案审查 needs_revision | 阶段 1 |
| working → review | 写 output + Guardrail 通过 | 阶段 2→3 |
| working → working | Guardrail rejected(自动打回) | 阶段 2 |
| review → done | 产出审查 approved | 阶段 3 |
| review → working | 产出审查 needs_revision | 阶段 3 |
| review → blocked | 超轮次升级 | 阶段 3 |
### D3-7comments 表和 reviews 表的职责分离
| 表 | 职责 | 内容类型 | verdict |
|---|------|---------|---------|
| **comments** | 讨论、@mention、协商过程 | 自然语言 | ❌ 无 |
| **reviews** | 正式评审结论 | 结构化 JSON | ✅ 必须有 |
评审协商过程("这里有个问题,建议这样改")写在 comments。
评审结论("通过" / "不通过,原因见 issues")写在 reviews。
两者关联:reviews.detail_path 指向的完整报告可以引用 comments 中的讨论。
### D3-8:声明式 Guardrail 配置(YAML
> **参考实践**
> - **OpenAI Agent SDK**`@output_guardrail` 装饰器声明检查函数
> - **v1.0 M4 Guard**entry/exit guard + skill 化检查逻辑
> - **SonarQube / CodeClimate**rule_id 关联可查规则文档
```yaml
# guardrails.yaml
#
# L1 check 用 assert 字段(Python 表达式,Daemon eval 执行)
# L2 check 用 prompt 字段(传给 subagent 的检查指令)
task_types:
coding:
output_guardrails:
- name: file_exists
assert: "len(output.get('files', [])) > 0"
severity: blocking
layer: L1
- name: json_valid
assert: "output.get('json_schema_valid', False) == True"
severity: blocking
layer: L1
- name: artifacts_exist
assert: "all(os.path.exists(p) for p in output.get('artifacts_paths', []))"
severity: blocking
layer: L1
- name: scope_alignment
prompt: "Compare the agent's scope_declaration against task truths. Check: is every truth covered? Are there deviations not declared?"
severity: warning
layer: L2
output_review:
required: true
mode: single_reviewer
max_rounds: 3
deploy:
plan_review:
required: true
mode: debate
max_rounds: 5
output_guardrails:
- name: no_direct_production
assert: "output.get('target_env') != 'production'"
severity: tripwire
layer: L1
- name: rollback_plan_exists
assert: "output.get('rollback_plan') is not None"
severity: blocking
layer: L1
output_review:
required: true
mode: debate
max_rounds: 5
data:
output_guardrails:
- name: format_check
assert: "output.get('format') in ['csv', 'parquet', 'json']"
severity: blocking
layer: L1
output_review:
required: false
research:
output_review:
required: true
reviewer: "pangtong-fujunshi" # 庞统确认方向
mode: single_reviewer
max_rounds: 2
```
## 4. 评审记录与 Handoff Comment 的关系
> **对齐课题2设计**
Handoff Comment(课题2)是 Agent 结束时写的交接信息。评审记录(课题3)是挑战者写的审查结论。
两者在黑板上的关系:
```
Agent A 完成产出
→ 写 Handoff Commentcomments 表,type=handoff
→ 写 outputoutputs 表)
→ 通知 Daemoninbox JSONL
Daemon 触发 Guardrail 自动检查
→ 结果写入 reviews 表(reviewer='system', review_type='guardrail'
→ 通过 → 进入产出审查
→ 不通过 → 打回
Daemon spawn 挑战者
→ 挑战者读黑板:L1 含 Agent A 的 Handoff Comment + output summary
→ 挑战者做审查
→ 写 reviewreviews 表,verdict + summary + detail_path
→ 写 commentcomments 表,协商讨论)
→ 通过 → status: done
→ 不通过 → status: working + Agent A 被 spawn 重做
```
下一个 Agent(如果需要)的 L1 消息中包含:
1. Agent A 的 Handoff Comment(最近3条评论之一)
2. 挑战者的 review summaryreviews 表最新一条)
3. 协商过程的 comments(L2 按需读取)
### D3-9:审查协议注册表(Review Protocol Registry
> **参考实践**
> - **superpowers**:三个独立 prompt 文件——`implementer-prompt.md`、`spec-reviewer-prompt.md`、`code-quality-reviewer-prompt.md`,每个角色有专属模板,不是笼统的"请审查"
> - **oh-my-claudecode Critic**Investigation Protocol 分 Phase 执行(预判→验证→多视角→缺口分析→自审),不同 artifact type 自动切换视角(代码→安全/新人/运维,方案→执行者/利益相关者/怀疑论者)
> - **superpowers spec-reviewer**prompt 注入对抗性指令——"DO NOT trust the report. Read the actual code.""Compare to requirements line by line."
**问题**:审查者不知道自己该审什么,容易陷入局部审查(编码规范、编译通过),漏掉本质问题(需求一致性、语义正确性)。或者被挑战后一律照改,不加思考。
**根因**:审查指令是笼统的"请审查",审查者靠"自觉"决定审什么。Skill 是软引导,可看可不看。
**方案**:审查协议是代码注入的,不是靠 Agent 自己去找的。Daemon spawn 审查者时,根据任务类型 + 审查类型动态加载协议模板,注入到 bootstrap 消息中。
```
review_protocols/
├── plan_review.yaml # 方案审查协议
├── output_review.yaml # 产出审查协议
├── guardrail_l2.yaml # L2 轻量AI检查协议
└── analysis_review.yaml # 分析/调研审查协议
```
每个协议文件定义四个维度:
**维度1:审查维度(审什么)**
```yaml
# review_protocols/output_review.yaml(示例片段)
dimensions:
- id: requirement_traceability
description: "每个 must_have truth 是否被覆盖"
weight: critical
method: "逐条比对 truths → 产出代码/文件"
- id: scope_alignment
description: "产出是否与 scope_declaration 一致"
weight: critical
method: "对比 decisions.scope_declaration vs 实际产出"
- id: correctness
description: "逻辑是否正确"
weight: major
method: "追踪执行路径,验证关键逻辑"
- id: completeness
description: "是否有遗漏"
weight: major
method: "缺口分析:什么缺失了?什么假设未被验证?"
- id: constraint_compliance
description: "是否遵守约束"
weight: major
method: "逐条检查 tasks.constraints"
```
**维度2:审查方法(怎么审)**——参考 oh-my-claudecode Critic 的 Investigation Protocol
```yaml
investigation_protocol:
phases:
- name: pre_commitment
instruction: >
先不读产出,凭领域经验预测3-5个最可能出问题的点。
写下预测。然后逐个验证。这迫使主动搜索而非被动阅读。
- name: verification
instruction: >
读实际产出(不是报告),逐条验证每个 truth。
提取所有文件引用、函数名、API 调用,逐一对照源码验证。
模拟执行每个步骤,不只读文字描述。
- name: multi_perspective
instruction: >
从不同角色看这份产出:
- 安全视角:什么信任边界被跨越?什么输入没校验?
- 新人视角:不熟悉代码的人能理解吗?什么上下文被假设但没说明?
- 运维视角:规模化后怎样?依赖失败时怎样?爆炸半径多大?
- name: gap_analysis
instruction: >
不只看"什么有问题",还看"什么缺失了"。
问:什么会破坏这个?什么边界情况没处理?什么假设可能是错的?
- name: self_audit
instruction: >
给自己的每个 finding 打 confidenceHIGH/MEDIUM/LOW)。
LOW confidence → 降级为 Open Question。
"作者能立刻反驳吗?"如果能 → 降级。
"这是真正的缺陷还是风格偏好?"如果是偏好 → 降级。
```
不同审查类型用不同的 multi_perspective 视角集(参考 Critic 的代码视角 vs 方案视角分离):
| 审查类型 | 多视角集合 |
|---------|----------|
| `output_review`(代码产出) | 安全 / 新人 / 运维 |
| `plan_review`(方案) | 执行者 / 利益相关者 / 怀疑论者 |
| `analysis_review`(调研分析) | 领域专家 / 实践者 / 反方辩手 |
| `guardrail_l2`(轻量检查) | 无多视角(单一维度快速检查) |
**维度3:对抗性指令(防止走过场)**——参考 superpowers spec-reviewer 的"DO NOT trust"指令
```yaml
adversarial_instructions:
- "DO NOT trust the implementer's report. Read the actual code/files."
- "If something looks correct on the surface, verify it works in context."
- "Not just what's wrong — also check what's MISSING."
- "Accept findings only with evidence (file:line or specific quote). No evidence = opinion."
- "If you find 1 CRITICAL or 3+ MAJOR issues, escalate to adversarial mode: actively hunt for more problems, challenge every design decision, expand scope to adjacent code."
- "Also check for EXTRA/UNNEEDED work that wasn't requested."
```
**维度4:输出格式**
```yaml
output_schema: "schemas/review-output.schema.json"
verdict_options: ["approved", "rejected", "needs_revision"]
required_fields:
- verdict
- summary
- issues[] (each with severity, description, evidence)
- confidence (0.0-1.0)
```
**Daemon 拼接逻辑**
```python
def build_reviewer_bootstrap(task, review_type):
# 1. 加载协议模板
protocol = load_protocol(f"review_protocols/{review_type}.yaml")
# 2. 注入任务上下文( truths, constraints, scope_declaration
protocol.inject_context(task)
# 3. 拼接成 L1 bootstrap 消息
# 审查者收到的消息 = 角色定义 + 审查协议 + 任务上下文 + 必读材料
return format_reviewer_bootstrap(protocol, task)
```
**防止"一律照改"——反驳权(Rebuttal Phase**
审查不是单向的。但不是每次都触发反驳——有跳过条件:
**跳过条件**(不需 spawn 反驳):
- 审查者 verdict=approved → 直接 done,跳过 rebuttal
- 审查者 verdict=needs_revision,但 issues 全是 minor severity → 执行者自然在 comments 接受并修改,不 spawn 反驳
**触发条件**spawn 反驳):
- 审查者 verdict=needs_revision,且 issues 中有 critical 或 major severity
- 审查者 verdict=rejected
```
审查者提交 review
verdict=approved → 直接 done(跳过 rebuttal
verdict=needs_revision 且只有 minor → 执行者直接修改(跳过 rebuttal)
verdict=needs_revision 且有 critical/major → spawn 反驳
Daemon spawn 原执行者,注入反驳指令:
"你收到了一份审查意见。对每个 issue,你必须明确表态:
ACCEPT(接受并修改)/ REJECT(拒绝,说明为什么)/ PARTIAL(部分接受)
不允许全部接受不加思考。"
执行者 response 写入 comments 表
如果是 REJECT → Daemon spawn 审查者看 response → 继续协商
如果全部 ACCEPT → 修改后重新提交 → 审查者 re-review
```
### D3-10OpenClaw 集成——Full Agent vs Subagent vs Daemon 直接执行
> **参考实践**
> - **superpowers**Implementer / Spec Reviewer / Code Quality Reviewer 都是 Task tool dispatch 的 subagent,但各自有独立的 prompt 模板和模型选择
> - **oh-my-claudecode**Critic 被禁止 Write/Edit 工具(disallowedTools),是角色隔离而非进程隔离
> - **open-multi-agent**TaskQueue 维护 agent poolscheduler 按 capability-match 分配任务
**问题**:什么任务需要完整的 Agent 身份(SOUL/IDENTITY/MEMORY),什么任务只需要无身份的 AI Worker?
**判据:五个问题**
| 问题 | 走 Full Agent | 走 Subagent | Daemon 直接执行 |
|------|-------------|-----------|--------------|
| 需要独立身份/人格吗? | ✅ 司马懿的"质量守门人" | ❌ | ❌ |
| 需要 Agent 专属工具吗? | ✅ 关羽的风控工具 | ❌ 通用 exec/read 就够 | 不需要 AI |
| 任务复杂度 | 编码、审查、调研、决策 | 单一检查、快速评估 | 格式校验、文件存在检查 |
| 需要写黑板吗? | ✅ 写 review/output/decision | ❌ 只返回 pass/fail | 只改状态 |
| 需要多轮交互吗? | ✅ 协商、反驳、辩论 | ❌ 一次性的 | 一次性的 |
**对应到我们的场景**
| 场景 | 走什么 | OpenClaw API | 理由 |
|------|--------|-------------|------|
| 张飞编码 | Full Agent | `openclaw agent --agent zhangfei-dev` | 需要身份、编码工具 |
| 司马懿产出审查 | Full Agent | `openclaw agent --agent simayi-challenger` | 需要质量守门人角色、多轮协商 |
| 执行者反驳审查 | Full Agent(原 Agent | `openclaw agent --agent <原执行者>` | 需要原执行者的身份和上下文 |
| 庞统任务规划 | Full Agent | `openclaw agent --agent pangtong-fujunshi` | 需要副军师角色、决策能力 |
| 庞统冲突裁决 | Full Agent(隔离 session | `openclaw agent --agent pangtong-fujunshi --session-id <new>` | 避免主 session 上下文膨胀 |
| 赵云数据下载 | Full Agent | `openclaw agent --agent zhaoyun-data` | 需要数据工具、NAS 操作 |
| 姜维部署 | Full Agent | `openclaw agent --agent jiangwei-infra` | 需要 Docker/PM2 工具 |
| L2 Guardrail AI 检查 | Subagent | `sessions_spawn(task=...)` | 单一检查、不需要身份 |
| Scope Guard 异步检查 | Subagent | `sessions_spawn(task=...)` | 轻量、一次性 |
| L1 机械校验(文件存在/JSON格式) | **不走 AI** | Daemon 直接执行 | 纯机械操作,不需要 AI |
**简化规则**:黑板上有名字的角色(庞统/司马懿/张飞/关羽/赵云/姜维)走 Full Agent。没有名字的一次性检查走 Subagent。纯机械检查 Daemon 自己做。
**OpenClaw spawn 具体实现**
```python
def spawn_agent(agent_id, task_id, mandate):
"""Spawn Full Agent(有身份、有专属工具)"""
session_id = f"moziplus-{task_id}-{agent_id}-{uuid4().hex[:8]}"
bootstrap_msg = format_mandate_message(mandate)
subprocess.run([
"openclaw", "agent",
"--agent", agent_id,
"--session-id", session_id,
"--message", bootstrap_msg
], capture_output=True, text=True)
# 记录到黑板 events 表
blackboard.execute(
"INSERT INTO events (task_id, event_type, data) VALUES (?, 'agent_spawned', ?)",
task_id, json.dumps({"session_id": session_id, "agent_id": agent_id})
)
def spawn_subagent(task_id, task_description, context=None):
"""Spawn Subagent(无身份、通用工具、一次性)"""
# 通过 OpenClaw API spawn 轻量 worker
# 返回结果直接处理,不写入黑板 reviews 表
# 适用于 L2 Guardrail、Scope Guard 等轻量检查
pass
```
**庞统主 session 的隔离策略**
庞统主 session 做轻量调度(L1 构建、状态检查、黑板 tick 处理)。复杂的任务拆解和裁决 spawn 一个 pangtong-fujunshi 的隔离 session,避免主 session 上下文膨胀(课题2 D2-6:不需要 Auto-compact,但庞统是唯一可能有累积的 session)。
---
## 5. 遗留 TODO
| # | 待解决事项 | 归属 | 说明 |
|---|----------|------|------|
| ~~T3-1~~ | ~~reviews 表的 CLI 命令~~ | ~~Phase 2~~ | ✅ 方案已定,开发实现 |
| ~~T3-2~~ | ~~Guardrail YAML 解析 + 执行引擎~~ | ~~Phase 2~~ | ✅ 方案已定,开发实现 |
| ~~T3-3~~ | ~~对抗辩论模式的具体黑板协议~~ | ~~Phase 3~~ | ✅ 方案已定(见 §5.1),仅在用户明确要求时启用 |
| ~~T3-4~~ | ~~挑战者池的选择策略~~ | ~~Phase 2~~ | ✅ 方案已定,开发实现 |
| ~~T3-5~~ | ~~confidence 低于阈值自动升级~~ | ~~Phase 2~~ | ✅ 方案已定,开发实现 |
| ~~T3-6~~ | ~~评审详情文件的 Schema 定义~~ | ~~Phase 2~~ | ✅ 方案已定(见 §5.2),待司马懿评审确认 |
| ~~T3-7~~ | ~~low 风险任务 Guardrail 自动通过~~ | ~~Phase 2~~ | ✅ 方案已定,开发实现 |
| ~~T3-8~~ | ~~Review Protocol 模板文件编写~~ | ~~Phase 2~~ | ✅ 方案已定,开发实现 |
| ~~T3-9~~ | ~~反驳权 Daemon 流控~~ | ~~Phase 2~~ | ✅ 方案已定(见 §5.3),轮次上限兜底不设超时 |
| ~~T3-10~~ | ~~Agent 调度判据~~ | ~~Phase 2~~ | ✅ 方案已定(见 §5.4),配置表驱动非 AI 判断 |
### 5.1 对抗辩论黑板协议(T3-3 方案)
> **触发条件**:仅在用户明确在任务意图中包含"辩论"等字样时启用。大多数任务走标准挑战机制(单审 + 反驳权)足够。
**调研来源**TradingAgentsBull vs Bear → Manager 裁决)、学术界 MADcritic/defender/judge 三角色、稳定性检测早停)、claude-goalnone/adversarial/double 三级)。
**三角色 × 最多 5 轮 × 2 种结束条件**
- **正方(Proponent**= 执行者
- **反方(Opponent)**= 挑战者池按任务类型选择
- **裁决者(Judge**= 庞统(隔离 session
**黑板交互格式**
每个参与者用 comments 表写入,按类型区分:
- `comment_type = "debate_argument"` → 正方/反方论点
- `comment_type = "debate_rebuttal"` → 反驳
- `comment_type = "debate_judgment"` → 庞统裁决
每条 comment 的结构:
```json
{
"role": "proponent | opponent | judge",
"round": 1-5,
"claims": [
{"point": "...", "evidence": "文件路径/行号/数据", "severity": "critical|major|minor"}
],
"concession": ["我接受的观点..."],
"stance": "hold | yield | partial"
}
```
**流程**
```
Round 1: 正方写 scope_declaration + arguments → 反方读后写反驳
Round 2+: 正方回应反驳 → 反方回应
每轮结束后 Daemon 检查结束条件
```
**结束条件**(任一满足即停):
1. **达成共识**:一方 stance=yield 或双方 stance=partial
2. **轮次耗尽**:达到 max_rounds(默认 5
3. **稳定性检测**:连续 2 轮无新论点(claims 无变化)→ 提前终止
达成共识 → 按共识结论执行。轮次耗尽/稳定性 → 庞统裁决。
庞统裁决输出:写入 reviews 表(verdict + summary + detail_path),verdict = approved | rejected | needs_revision。
**reviews 表变更**:新增 `debate_context` JSON 字段(存辩论参与者和轮次数)。
### 5.2 评审详情文件 SchemaT3-6 方案)
> **待司马懿评审确认。**
**调研来源**SARIFStatic Analysis Results Interchange Formatresult 结构、GitHub PR Review、Hermes comment metadata JSON。
**Schema**`{task_id}/reviews/{review_id}.json`):
```json
{
"$schema": "review-detail-v1",
"review_id": "rev-001",
"task_id": "task-001",
"reviewer": "simayi-challenger",
"review_type": "output_review",
"verdict": "approved",
"confidence": 0.85,
"round": 1,
"summary": "一句话结论",
"issues": [
{
"id": "iss-1",
"status": "open|accepted|rejected|deferred",
"severity": "critical|major|minor|info",
"category": "correctness|security|performance|style|scope_deviation|architecture|robustness",
"location": {
"file": "src/strategy.py",
"line_start": 42,
"line_end": 55,
"context": "def calculate_signal(df):\n ..."
},
"title": "简短描述",
"description": "详细说明",
"evidence": "代码片段或引用",
"suggestion": "修复建议",
"remediation_effort": "low|medium|high"
}
],
"evidence": [
{
"type": "file_content",
"path": "src/strategy.py",
"relevant_lines": [42, 43, 44]
},
{
"type": "command_output",
"command": "pytest tests/ -x",
"exit_code": 1,
"output": "失败信息..."
}
],
"positives": ["做得好的地方"],
"meta": {
"review_protocol": "output_review",
"files_reviewed": 3,
"model_used": "zhipu/glm-5.1"
}
}
```
**SARIF 借鉴**issues 数组结构(severity + location + message)是 SARIF result 核心字段,但我们简化了——不需要 SARIF 的完整 taxonomy 和 rule metadata,我们的场景是 Agent 审查而非静态分析工具。
### 5.3 反驳权 Daemon 流控(T3-9 方案)
**本质问题**:审查者和执行者意见不一致时,Daemon 怎么管理协商过程。
**调研来源**TradingAgentsBull/Bear → Manager 裁决)、claude-goaldouble 审计)、superpowersverify→fix loop)。
**触发条件**(不是所有 review 都触发):
- review verdict=needs_revision,且 issues 中有 critical/major severity → 触发反驳
- review verdict=rejected → 触发反驳
- review verdict=approved → 不触发,直接 done
- review verdict=needs_revision,但只有 minor → 不触发,执行者直接改
**流程**
```
审查者提交 reviewverdict=needs_revision/rejected
Daemon tick 检测到 review → 检查 issues severity → 判定需要反驳
Daemon spawn 原执行者,注入:
"你收到了一份审查意见。对每个 issue,你必须表态:
ACCEPT / REJECT(说明理由) / PARTIAL(说明接受哪些)
不允许全部接受不加思考。"
执行者写入 commentscomment_type="rebuttal"
Daemon 检查 rebuttal 结果:
├── 全部 ACCEPT
│ → 执行者修改 → 重新提交 → 审查者 re-review
└── 有 REJECT/PARTIAL
→ Daemon spawn 审查者看 rebuttal
审查者写入 commentscomment_type="rebuttal_response"
Daemon 检查:
├── 双方达成一致 → 执行者按协商结果修改 → re-review
├── 审查者认可执行者反驳 → 执行者修改 → re-review
└── 仍有分歧
→ round++
→ round < max_rounds → 回到执行者继续协商
→ round >= max_rounds → 升级庞统裁决
```
**唯一的兜底机制**:协商轮次达到 max_rounds 仍未一致 → 升级庞统裁决。庞统裁决也达不成结论 → 升级用户。
**不设超时**——Agent 可能被长任务 block,超时不能等同于"放弃反驳"。轮次上限已经是自然的终止条件。
**进度检测**(催促通知,非阻塞):如果同一轮次超过 `task_timeout`(10 分钟)没有任何新 comment 写入 → Daemon 通过 Inbox 发一个催促通知给当前应回应的 Agent。不是强制终止,只是提醒。
**reviews 表新增字段**
- `rebuttal_status`: "pending" | "completed" | "escalated"
- `debate_round`: INTEGER(当前协商轮次,默认 1)
**和 T3-3 对抗辩论的区别**:反驳权是审查后的协商机制(大多数任务),对抗辩论是正式辩论(仅用户明确要求时)。
### 5.4 Agent 调度判据(T3-10 方案)
**调研来源**Phil Schmid 四种子 Agent 模式、Addy Osmani Code Agent Orchestra、oh-my-opencode 三层调度。
**现有设计已完整**(D3-10 五问题判据 + 场景映射 + 简化规则),补充的是 **Daemon 自动调度逻辑**
**三级决策树(配置表驱动,非 AI 判断)**
```python
DISPATCH_RULES = {
"L1_guardrail": "daemon", # Daemon eval guardrails.yaml assert
"L2_ai_check": "subagent", # sessions_spawn 单一检查
"scope_guard": "subagent", # 轻量异步检查
"execute": "full_agent", # 走 registered agent
"review": "full_agent", # 走 registered agent
"rebuttal": "full_agent", # 走原执行者
"debate_proponent": "full_agent", # 走原执行者
"debate_opponent": "full_agent", # 走挑战者
"debate_judge": "full_agent", # 庞统隔离 session
"plan_decomposition": "full_agent", # 庞统
}
def dispatch(task, action_type, project_config):
# 从项目配置动态读取可用 Agent 列表,不硬编码
registered_agents = project_config.get("agents", [])
# Level 1: 纯机械检查 → Daemon 直接执行
if action_type in ("L1_guardrail", "format_check", "file_exists_check"):
return execute_locally(task)
# Level 2: 有名字的角色 → Full Agent
if task.assignee in registered_agents:
if action_type == "adjudication":
return spawn_full_agent(task.assignee, new_session=True)
return spawn_full_agent(task.assignee)
# Level 3: 无名字的一次性任务 → Subagent
if DISPATCH_RULES.get(action_type) == "subagent":
return spawn_subagent(task_description=action_type)
# Level 4: 未知 action_type → 庞统裁决
return spawn_full_agent("pangtong-fujunshi", new_session=True)
```
**简化规则**:黑板上有名字的角色(庞统/司马懿/张飞/关羽/赵云/姜维)走 Full Agent。没有名字的一次性检查走 Subagent。纯机械检查 Daemon 自己做。未知类型交给庞统裁决。
**spawn 方式**(和课题11异步计数器模型一致):
- **Full Agent**`subprocess.Popen`(非阻塞)启动 `openclaw agent` CLI,不等返回,下次 tick 检查产出
- **Subagent**`sessions_spawn`Gateway 内部 API),等返回
## 6. 和现有设计的对齐检查
| 已有设计 | 课题3 补充 | 一致性 |
|---------|-----------|--------|
| §9.5 分级审查矩阵(课题1) | D3-1 分级流水线(补充每级内部流程) | ✅ 四级风险对应四级流水线 |
| §4.7 Guardrail 吹哨人(课题1 | D3-4 Guardrail 结果入 reviews 表 | ✅ 吹哨后写 observation + 入 reviews |
| §3.7 Schema 校验(课题2 | D3-8 Guardrail YAML 和 Schema 对齐 | ✅ L1 检查用 SchemaYAML 声明规则 |
| §4.2 Tick+Inbox(课题2 | 评审触发也走 inbox 通知 | ✅ 挑战者 review 写完后通知 Daemon |
| §5.1 Handoff Comment(课题2 | §4 评审与 Handoff 关系 | ✅ Handoff 是执行者写的,review 是挑战者写的 |
| §3.2 SQLite Schema | reviews 表新增 | ✅ 独立新表,不修改现有表 |