11 KiB
#09 Rebuttal 流程自动化 + 目标一致性 Gate
版本: v1.1 日期: 2026-06-03 作者: 庞统(副军师) 状态: 待评审(v1.1) 前置: #04 黑板协作(@mention)+ #08 Classify Outcome 关联: T4 审查体系完善 变更: v1.1 纳入司马懿评审反馈 — verdict 读 reviews 表 + rebuttal mention spawn 带 on_complete 回调
讨论决策记录
D1: 庞统持续 session
结论:不做 openclaw 层面的持续 session(受 openclaw 机制限制)。改为两个场景确保目标一致性:
- Round review(已实现 ✅)— 子任务完成后庞统审查
- 过程中 agent 沟通(本设计覆盖)— agent 遇到问题问庞统时,庞统保持和目标高度一致,防止需求降级
D2: 动态规划 / Replan
结论:不需要专门的 replan 模块。在当前架构中 replan 已通过自然组合实现:
- Task 失败 → crash_limit 标 failed → round review → 庞统看全局后决定调整
- Task 产出改变理解 → agent 自主读黑板(#05 上下文注入)→ agent 自己判断调整
- 发现新依赖 → 庞统在 round review 中发现 → 创建新子任务
- 依赖链自动推进 →
_advance_dependencies(blocked→pending) - Per-task timeout + crash limit →
_check_timeouts(deadline 优先,默认 30m,crash 3/30m 标 failed)
不做独立的 replan 代码模块。
D3: Rebuttal 触发方式
结论:靠 agent 自主 + @mention 现有机制,不做 daemon 层面的自动触发。原因:
- 减少系统复杂度
- Agent 有自主判断能力(#05 上下文注入)
- @mention 机制已成熟(#04)
D4: B8 BUG-7 planning 暂停
结论:planning 状态已从状态机中移除,BUG 不再存在。但前端 resume 映射为 executing(非法状态),应改为恢复到 resumed_from 记录的状态。记为后续前端修复项。
D5: 司马懿评审反馈(v1.0 → v1.1)
问题1:verdict 读取方式 → on_complete 回调中从 reviews 表查最新 verdict(SELECT verdict FROM reviews WHERE task_id=? ORDER BY created_at DESC LIMIT 1),和 ticker _recover_review_task 一致。
问题2:review 保持状态不会被重复 dispatch → 确认无问题,_dispatch_reviews 已有 if reviews: continue 保护。
问题3:rebuttal @mention 缺 on_complete → 选方案 1:mention spawn 带回调。触发条件:task status=review + comment_type=rebuttal → spawn 时带 _review_on_complete 回调。改动点在 _process_mentions,约 10 行。
问题4:assignee 而非 current_agent → 确认 @mention 对象用 assignee(执行者),不用 current_agent(审查者)。
MAX_ROUNDS 确认:RebuttalManager.MAX_ROUNDS = 2,rebuttal round 1(司马懿重审)+ rebuttal round 2(庞统仲裁)= 2 轮。对齐。
一、问题陈述
1.1 Rebuttal 缺失
当前审查流程:
Agent 完成 → review → 司马懿审查 → verdict(approved/rejected/needs_revision) → 结束
问题:审查结论是单方面的。Agent 对 rejected/needs_revision 没有反驳渠道。尤其是:
- 复杂设计方案,司马懿可能误判
- 需求降级场景,agent 认为自己做了正确的事但被 reviewer 要求改回去
- 没有 1-2 轮辩论,结论质量无法保证
已有基础:
RebuttalManager类已实现(2 轮反驳,round 1→司马懿重审,round 2→庞统仲裁)comment_type支持rebuttal、rebuttal_response、debate_argument等reviews表结构完整
缺什么:ticker/dispatcher 层面没有自动串联 rebuttal 流程。submit_rebuttal 存在但无人调用。
1.2 目标一致性 Gate
当前 agent 遇到需求不清晰时:
- executor prompt 说"不确定时停下来问(黑板 comment)"
- @mention 机制可以把庞统 spawn 起来
缺什么:
- executor/reviewer prompt 没有明确指引"需求不清晰时 @pangtong-fujunshi 提问"
- 庞统收到提问时,没有注入原始任务目标和验收标准来校准回答
- 庞统的回复可能无意中做了需求降级("这个太复杂了,简化一下吧")
二、设计方案
2.1 Rebuttal 自动化流程
流程图
Agent 完成任务 → review
→ 司马懿审查 → verdict
├─ approved → done(无争议)
├─ rejected/needs_revision → 通知被审 agent
│ → Agent 选择:
│ ├─ 接受 verdict → 按 verdict 修改 → 重新提交 review
│ └─ 反驳 → submit_rebuttal(黑板 comment_type=rebuttal)
│ → Ticker 检测到 rebuttal → spawn 司马懿重审(round 2)
│ ├─ 司马懿改判 → done/needs_revision
│ └─ 司马懿坚持 → 通知庞统仲裁(round 3,最终轮)
│ → 庞统裁决 → done/needs_revision/创建新任务
└─ (rebuttal 最多 2 轮,超限庞统最终裁决)
触发机制
关键设计决策:谁触发 rebuttal?
不是 daemon 自动触发,而是 agent 自主选择。流程:
- 司马懿审查完成 → verdict 写入 reviews 表 + comment_type=review
- Ticker 检测到新 review verdict → 通知被审 agent(@mention agent)
- Agent 看到 verdict + 自己的产出 → 决定接受或反驳
- 如果反驳 → agent 写 comment_type=rebuttal + @simayi-challenger
- Ticker 的 mention 处理循环 spawn 司马懿重审
- 司马懿重审后如果坚持 → @pangtong-fujunshi 请求仲裁
- 庞统仲裁 → 最终结论
这个流程几乎不需要新代码——主要靠 @mention 现有机制 + prompt 引导。
需要改的代码
| 文件 | 改动 | 说明 |
|---|---|---|
dispatcher.py _task_on_complete |
修改 | review completed → 读 verdict → approved 标 done / 非 approved @mention assignee |
ticker.py _process_mentions |
修改 | rebuttal mention spawn 时带 _review_on_complete 回调 |
prompt_templates/executor.md |
修改 | 加入“需求不清晰时 @pangtong-fujunshi 提问” |
prompt_templates/reviewer.md |
修改 | 加入 rebuttal 流程指引 |
prompt_templates/review_pangtong.md |
修改 | 加入仲裁指引 + 目标一致性检查 |
prompt_templates/review_simayi.md |
修改 | 加入 rebuttal 处理指引 |
_task_on_complete 改动细节(dispatcher.py)
当前逻辑(L244-250):review completed → 直接标 done。
改为:
if _is_review:
if outcome in ("completed", "session_revived"):
# 读 verdict
review = conn.execute(
"SELECT verdict FROM reviews WHERE task_id=? ORDER BY created_at DESC LIMIT 1",
(_task_id,)
).fetchone()
if review and review["verdict"] == "approved":
_dispatcher._mark_task_status(_task_db, _task_id, "done")
else:
# 非 approved → @mention 被审 agent(用 assignee,非 current_agent)
task = conn.execute("SELECT assignee FROM tasks WHERE id=?", (_task_id,)).fetchone()
if task and task["assignee"]:
bb.add_comment(_task_id, "daemon",
f"@{task['assignee']} 审查结论: {review['verdict'] if review else '未知'},请查看详情并决定接受或反驳",
comment_type="review")
# 不标 done,保持 review
else:
# crash/error → 保持 review 等 ticker 处理
pass
_process_mentions 改动细节(ticker.py)
当前 mention spawn 不带 on_complete。rebuttal 场景需要带,否则新 verdict 无人处理。
触发条件:task status=review + mention 的 comment_type 包含 rebuttal
# 在 mention spawn 时检查:如果是 rebuttal 场景
has_rebuttal = any(
item.get("comment_type") == "rebuttal"
for item in items
)
task_status = bb.get_task(items[0]["task_id"]).status if items else None
if has_rebuttal and task_status == "review":
# rebuttal 重审:带 on_complete 回调处理新 verdict
result = await self.spawner.spawn_full_agent(
agent_id=agent_id,
message=prompt,
task_id=tid,
use_main_session=True,
on_complete=_review_on_complete, # 处理新 verdict
)
else:
# 普通 mention:不带回调
result = await self.spawner.spawn_full_agent(
agent_id=agent_id,
message=prompt,
task_id=tid,
use_main_session=True,
)
其中 _review_on_complete 复用 dispatcher 中 review verdict 的处理逻辑(读 verdict → approved 标 done / 非 approved @mention)。
防止无限循环
- RebuttalManager.MAX_ROUNDS = 2(已有,rebuttal round 1 司马懿重审 + round 2 庞统仲裁)
- 超过 2 轮 → 庞统最终裁决
- 每个 review 记录在 reviews 表中,rebuttal_count 可追溯
_dispatch_reviews已有if reviews: continue保护,有 review 结论的任务不会被重复 dispatch
2.2 目标一致性 Gate
Agent 端
executor.md 改动:
在"工作方式"和"约束"之间新增一节:
## 需求不清晰时的处理
- 任务描述有歧义、验收标准不明确、多个理解方式 → @pangtong-fujunshi 提问
- 不要自行假设。宁可多问一句,也不要做错方向
- 提问时:列出你的理解、可能的选项、你倾向的方案,让庞统确认
- 庞统回复后,以回复为准继续执行
庞统端
review_pangtong.md 改动:
新增"代理提问处理"部分:
## 回答 Agent 提问时的原则
- 对照原始任务目标和验收标准回答,不做需求降级
- 如果 agent 觉得目标太难 → 讨论替代方案,但必须说清楚代价(缩小的范围、降低的质量)
- 如果原始目标确实不可行 → 升级用户,不要自己做主降级
- 回答要具体到可操作,不要给模糊方向
Bootstrap 注入
当庞统被 @mention spawn 回答问题时,bootstrap 已经会注入任务上下文(#05 L2 层)。不需要额外改动。
2.3 司马懿 Rebuttal 处理
reviewer.md / review_simayi.md 改动:
## Rebuttal 处理
- 被反驳时,重新审视自己的结论
- 如果 agent 的反驳有理有据 → 改判
- 如果坚持原判 → 给出更具体的理由,不要只说"我认为不行"
- Rebuttal 不是对抗,是共同追求正确答案
- 第 2 轮 rebuttal 如果仍无法达成一致 → @pangtong-fujunshi 请求仲裁
三、改动总览
| 文件 | 改动 | 行数 |
|---|---|---|
src/daemon/ticker.py |
review verdict 非 approved 时 @mention 被审 agent | ~15 行 |
prompt_templates/executor.md |
新增"需求不清晰时 @pangtong-fujunshi" | ~8 行 |
prompt_templates/reviewer.md |
新增 rebuttal 处理指引 | ~8 行 |
prompt_templates/review_pangtong.md |
新增仲裁指引 + 反需求降级 | ~10 行 |
prompt_templates/review_simayi.md |
新增 rebuttal 处理指引 | ~8 行 |
| 净增 | ~49 行 |
四、验收标准
- 司马懿审完 rejected/needs_revision → 自动 @mention 被审 agent
- Agent prompt 明确引导"需求不清晰 → @pangtong-fujunshi"
- 庞统回复时对照原始目标,不做需求降级
- Rebuttal 最多 2 轮,超限庞统裁决
- 现有测试不 regression
五、不做的事
- 不做 daemon 层面的自动 rebuttal 触发(靠 agent 自主 + @mention)
- 不做专门的 rebuttal API 端点(复用 comment + mention)
- 不做 rebuttal 状态机扩展(复用 RebuttalManager 已有逻辑)