# 课题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 Guard(L2 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 JSON(verdict + 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-4:Guardrail 检查结果也入 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-7:comments 表和 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 Comment(comments 表,type=handoff) → 写 output(outputs 表) → 通知 Daemon(inbox JSONL) ↓ Daemon 触发 Guardrail 自动检查 → 结果写入 reviews 表(reviewer='system', review_type='guardrail') → 通过 → 进入产出审查 → 不通过 → 打回 ↓ Daemon spawn 挑战者 → 挑战者读黑板:L1 含 Agent A 的 Handoff Comment + output summary → 挑战者做审查 → 写 review(reviews 表,verdict + summary + detail_path) → 写 comment(comments 表,协商讨论) → 通过 → status: done → 不通过 → status: working + Agent A 被 spawn 重做 ``` 下一个 Agent(如果需要)的 L1 消息中包含: 1. Agent A 的 Handoff Comment(最近3条评论之一) 2. 挑战者的 review summary(reviews 表最新一条) 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 打 confidence(HIGH/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-10:OpenClaw 集成——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 pool,scheduler 按 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 ` | 避免主 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 方案) > **触发条件**:仅在用户明确在任务意图中包含"辩论"等字样时启用。大多数任务走标准挑战机制(单审 + 反驳权)足够。 **调研来源**:TradingAgents(Bull vs Bear → Manager 裁决)、学术界 MAD(critic/defender/judge 三角色、稳定性检测早停)、claude-goal(none/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 评审详情文件 Schema(T3-6 方案) > **待司马懿评审确认。** **调研来源**:SARIF(Static Analysis Results Interchange Format)result 结构、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 怎么管理协商过程。 **调研来源**:TradingAgents(Bull/Bear → Manager 裁决)、claude-goal(double 审计)、superpowers(verify→fix loop)。 **触发条件**(不是所有 review 都触发): - review verdict=needs_revision,且 issues 中有 critical/major severity → 触发反驳 - review verdict=rejected → 触发反驳 - review verdict=approved → 不触发,直接 done - review verdict=needs_revision,但只有 minor → 不触发,执行者直接改 **流程**: ``` 审查者提交 review(verdict=needs_revision/rejected) ↓ Daemon tick 检测到 review → 检查 issues severity → 判定需要反驳 ↓ Daemon spawn 原执行者,注入: "你收到了一份审查意见。对每个 issue,你必须表态: ACCEPT / REJECT(说明理由) / PARTIAL(说明接受哪些) 不允许全部接受不加思考。" ↓ 执行者写入 comments(comment_type="rebuttal") ↓ Daemon 检查 rebuttal 结果: │ ├── 全部 ACCEPT │ → 执行者修改 → 重新提交 → 审查者 re-review │ └── 有 REJECT/PARTIAL → Daemon spawn 审查者看 rebuttal ↓ 审查者写入 comments(comment_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 检查用 Schema,YAML 声明规则 | | §4.2 Tick+Inbox(课题2) | 评审触发也走 inbox 通知 | ✅ 挑战者 review 写完后通知 Daemon | | §5.1 Handoff Comment(课题2) | §4 评审与 Handoff 关系 | ✅ Handoff 是执行者写的,review 是挑战者写的 | | §3.2 SQLite Schema | reviews 表新增 | ✅ 独立新表,不修改现有表 |