auto-sync: 2026-05-29 20:08:58

This commit is contained in:
cfdaily
2026-05-29 20:08:58 +08:00
parent 32723716f2
commit 28fdad4bce
+102 -4
View File
@@ -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:
# 信号 1Agent 已自行更新状态(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 自己标了终态
# 信号 2outputs 表有产出
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
→ 三无 → 留 workingticker 重查,最多 3 次 → failed
庞统 review
→ 第二层(文件存在性:content_path 验证)
→ 第三层(AI 验证:产出是否覆盖 must_haves
→ 通过 → GOAL_ACHIEVED 或创建新 sub task
→ 不通过 → 打回重做
```
---