diff --git a/docs/design/02-main-session-delegation.md b/docs/design/02-main-session-delegation.md index a341645..fa6a6c0 100644 --- a/docs/design/02-main-session-delegation.md +++ b/docs/design/02-main-session-delegation.md @@ -377,11 +377,109 @@ def _task_auto_complete(self, task_id, agent_id, db_path): ### 待确认 -| # | 问题 | 说明 | +| # | 问题 | 状态 | |---|------|------| -| 1 | **投递消息的 prompt 模板** | 需要和 v2.8 方向的 Prompt 进化对齐(身份+能力+约束 vs 固定步骤) | -| 2 | **E2E 测试适配** | 现有 E2E 测试依赖 spawner 的 `--session-id UUID` 机制,需要适配 | -| 3 | **幻觉门控策略** | 普通 Task 用 outputs 表 + status 字段检查,还是其他方式? | +| 1 | **投递消息的 prompt 模板** | ✅ 告诉 Agent "优先使用 subagent-delegation skill",让 Agent 自己决定 | +| 2 | **E2E 测试适配** | ✅ 测试验证黑板状态变化,不依赖具体 session 机制 | +| 3 | **幻觉门控策略** | ✅ 三层门控(见下文),已确认 | + +--- + +## 九、幻觉门控方案(三层) + +### 第一层:Daemon 确定性检查(on_complete 触发) + +`on_complete` 回调触发时机:`openclaw agent` 子进程退出时(Agent 在 main session 执行完 turn)。 +Agent 没执行完进程不会退出,不存在长任务误判。 + +```python +def _task_verify_completion(self, task_id, db_path): + """普通 Task 完成验证(泛化 Mail 幻觉门控) + + 三信号检查:status / outputs / comments 是否有变化。 + 任一信号存在即视为有效完成。 + """ + conn = get_connection(db_path) + try: + # 信号 1:Agent 已自行更新状态(review/done/failed) + row = conn.execute( + "SELECT status FROM tasks WHERE id=?", (task_id,) + ).fetchone() + if not row or row["status"] != "working": + return True # Agent 自己标了终态 + + # 信号 2:outputs 表有产出 + output_count = conn.execute( + "SELECT COUNT(*) FROM outputs WHERE task_id=?", (task_id,) + ).fetchone()[0] + if output_count > 0: + return True + + # 信号 3:有评论/handoff(Agent 至少写了交接文档) + comment_count = conn.execute( + "SELECT COUNT(*) FROM comments WHERE task_id=? AND author != 'system'", + (task_id,) + ).fetchone()[0] + if comment_count > 0: + return True + + # 三无 → 可能是幻觉 + return False + finally: + conn.close() +``` + +**行为**: +- 通过 → 标 review(等待庞统 review) +- 不通过 → 留 working,ticker 重查(最多 3 次,然后标 failed) + +**不会误判长任务**:`on_complete` 只在 `openclaw agent` 子进程退出时触发。Agent 在 main session 里执行时进程还活着,不会触发。 + +### 第二层:Daemon 产出物文件验证(review 触发) + +对 `outputs` 表中有 `content_path` 的产出,验证文件是否真实存在。放在 Daemon(确定性代码,不依赖 AI): + +```python +def _verify_output_files(self, task_id, db_path): + """验证产出物文件是否真实存在(Daemon 确定性检查)""" + conn = get_connection(db_path) + outputs = conn.execute( + "SELECT content_path FROM outputs WHERE task_id=? AND content_path IS NOT NULL", + (task_id,) + ).fetchall() + missing = [] + for o in outputs: + if not Path(o["content_path"]).exists(): + missing.append(o["content_path"]) + return missing +``` + +**触发时机**:review 阶段(庞统 review 前),Daemon 先跑一次文件验证。 +**行为**:missing 非空 → 在黑板 comment 中标注缺失文件,供庞统 review 时参考。 + +### 第三层:AI 验证(review prompt 中要求) + +庞统/司马懿 review 时,在 prompt 中要求: +1. 检查产出是否覆盖 must_haves 中的验收标准 +2. 如果产出不可验证,在评论中标注 + +这一层由 AI 做,成本高但准确度高,只 review 时触发。 + +### 三层关系 + +``` +openclaw agent 子进程退出 + → on_complete 回调 + → 第一层(三信号:status / outputs / comments) + → 有信号 → 标 review + → 三无 → 留 working(ticker 重查,最多 3 次 → failed) + +庞统 review + → 第二层(文件存在性:content_path 验证) + → 第三层(AI 验证:产出是否覆盖 must_haves) + → 通过 → GOAL_ACHIEVED 或创建新 sub task + → 不通过 → 打回重做 +``` ---