auto-sync: 2026-05-16 22:26:08

This commit is contained in:
cfdaily
2026-05-16 22:26:08 +08:00
parent ce3fd584ad
commit 8abf45c748
+222 -10
View File
@@ -656,16 +656,228 @@ def spawn_subagent(task_id, task_description, context=None):
| # | 待解决事项 | 归属 | 说明 |
|---|----------|------|------|
| T3-1 | reviews 表的 CLI 命令blackboard.py review | Phase 2 | 写入/查询评审结果 |
| T3-2 | Guardrail YAML 解析 + 执行引擎 | Phase 2 | 读取 guardrails.yaml 并按 layer 执行 |
| T3-3 | 对抗辩论模式的具体黑板协议 | Phase 3 | 正方/反方如何在黑板上交互 |
| T3-4 | 挑战者池的选择策略 | Phase 2 | 按任务类型自动选择挑战者 |
| T3-5 | confidence 低于阈值自动升级 | Phase 2 | 如 confidence < 0.7 升级庞统 |
| T3-6 | 评审详情文件的 Schema 定义 | Phase 2 | detail_path 指向的 JSON 结构 |
| T3-7 | low 风险任务 Guardrail 自动通过的流控 | Phase 2 | 自动跳过 review 状态 |
| T3-8 | Review Protocol 模板文件编写 | Phase 2 | 4个 YAML 协议文件 + Daemon 加载逻辑 |
| T3-9 | 反驳权(Rebuttal Phase)的 Daemon 流控 | Phase 2 | review 提交后自动 spawn 原执行者反驳 |
| T3-10 | Full Agent vs Subagent 的 Daemon 调度逻辑 | Phase 2 | 根据任务类型自动选择 spawn 方式 |
| ~~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",
"severity": "critical|major|minor|info",
"category": "correctness|security|performance|style|scope_deviation",
"location": {
"file": "src/strategy.py",
"line_start": 42,
"line_end": 55
},
"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,超时不能等同于"放弃反驳"。轮次上限已经是自然的终止条件。
**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):
# 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
return spawn_subagent(task_description=action_type)
```
**简化规则**:黑板上有名字的角色(庞统/司马懿/张飞/关羽/赵云/姜维)走 Full Agent。没有名字的一次性检查走 Subagent。纯机械检查 Daemon 自己做。
## 6. 和现有设计的对齐检查