回应 Fasthei 终审三点: 1) [P1 文档/代码冲突 + 死代码] 删除从不被调用的 *_enabled() helper(autonomous_tasks.proposals_enabled / task_competition.task_competition_enabled / convergence.convergence_report_enabled)及其 import os;模块 docstring 与四份协议文档(autonomous-task-generation / task-competition-protocol / review-loop-protocol / convergence-protocol)从"默认关/未接入/待 PR/cutover 转无条件"全部改为 "无条件接入(无开关)",删除引用死 helper 的过时集成代码样例;同步删除三个模块单测里的 "flag default OFF" 断言。 2) [P1 验收] #6 "Closes" 降为 "Refs":#6 DoD 需 ARB 决策记录链接,当前只有 owner 指示断言、无链接。 product-positioning.md 改为如实记录决策来源(owner 指示 + 本 PR + 文档)并把"补 ARB 记录链接(或 owner 明确接受断言)"列为关闭 #6 的前置;纠正其"flag 门控、默认行为不变"的过时表述(重构已无条件)。 3) [P2 契约卫生] assess_swarm_health 不再 emit_event("swarm.health")(避免向订阅全部的 Manager 回调 投递未注册事件);改为存 run.metadata["health"] + 内部 health_log。test-swarm-guard 相应断言 "无 swarm.health 外发 + 内部 health_log 已记"。 本地受影响 11 套全绿。影响范围:agent_swarm(orchestrator 模块/文档/测试);不改 Manager↔Swarm 契约。 Refs #6 Refs #7 Refs #8 Refs #11 Refs #12 Refs #18 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
8.5 KiB
Review Loop 协议:从 Supervisor Retry 到蜂群交叉验证(issue #11)
状态:已接入在线 finalize 路径(去中心化重构 P5)。
main.py新增review_decisionWS 分支与handle_review_decision(收集 ≥2 同伴独立评审)+run_cross_review(聚合仲裁→分歧记录→拒绝则 reopen 返工目标 + 归因),在refresh_swarm_run_status中先于单 critic Master 评审。feature flagENABLE_CROSS_REVIEW(构建期;cutover 取代 Master 评审)。集成测试scripts/test-swarm-cross-review.py,模块单测scripts/test-cross-review.py。对应 issue #11 —「Review Loop 等价于 Supervisor Retry:评审重做机制未形成蜂群协同验证闭环」。
实现:
orchestrator/cross_review.py(纯模块,仅依赖标准库)。单测:scripts/test-cross-review.py。 配套:../benchmark/swarm-metrics-schema.md(P_rework/Reward)、orchestrator/main.py(现有评审循环)、orchestrator/master_agent.py、orchestrator/planner.py。
1. 现状:今天的评审循环是「单评审 + 重试」
当 ENABLE_REVIEW_LOOP=1 时,orchestrator/main.py 在 run 完成前调用一次主控评审(maybe_run_review_cycle):
master_agent.review_and_decide(objective, tasks, results)委托planner.review(...);planner.review用单个 LLM(或无模型时的启发式一致性检查)返回{accepted, summary, retry_tasks};- 若
accepted=False,编排器把retry_tasks里的任务reopen_task重新入队,review_cycles += 1,run 退回running,受MAX_REVIEW_CYCLES(默认 2)约束; - 重做完成后再次 finalize;预算耗尽或无可重做项即接受。
本质:这是一个 Supervisor Retry。 由单一权威(主控)判 pass/fail 并指派重做,没有第二个独立意见、没有记录分歧、没有结构化的「为什么重做 / 谁引入的缺陷」。因此:
- 不构成蜂群式交叉验证闭环(cross-validation)——验证仍是中心化的一票否决;
- 无法为基准
P_rework(见 §4)提供可归因的输入:每次重做只是一个无差别的 retry 计数,无法区分是需求 / 实现 / 测试 / 文档 / 协作哪一环引入。
2. 目标:多评审交叉验证 + 重做归因
orchestrator/cross_review.py 提供一个纯协议层(无 Redis / 无 WebSocket / 无模型调用),把「单评审 pass/fail」升级为「≥2 独立评审 → 检测分歧 → 仲裁 → 结构化重做归因」:
| 能力 | 今天(Supervisor Retry) | 交叉验证(本模块) |
|---|---|---|
| 评审者数量 | 1(主控) | ≥ 2 独立评审者(aggregate_reviews 强制) |
| 分歧 | 不存在概念 | disagreement 显式检测并记录 |
| 仲裁 | 主控单方裁定 | majority / weighted,平票安全偏向拒绝 |
| 证据 | summary 一行 |
evidence / failed_criteria / affected_tasks 结构化 |
| 重做归因 | 仅 retry_tasks |
rework_reason / root_cause / source_task_id / introduced_by_agent_id |
| 基准输入 | 无差别 retry 计数 | 按 ReworkCategory 分类的 P_rework 输入 |
2.1 数据结构
-
ReviewDecision(单评审者的结构化裁决)verdict:"pass"/"fail"(构造时校验,非法即ValueError);reviewer_agent_id(必填)、evidence[]、failed_criteria[]、affected_tasks[]、recommended_rework[];confidence(自评 0–1)、weight(仲裁权重,如角色信任 / 资历)、summary。
-
AggregatedVerdict(交叉验证结果)accepted、method(实际使用的仲裁法)、disagreement、pass_votes/fail_votes、rework_targets[]、decisions[]、summary。
-
ReworkAttribution(一次重做的归因)target_task_id、rework_reason、root_cause(ReworkCategory)、source_task_id、introduced_by_agent_id、detected_by_agent_id、evidence[]。
-
ReworkCategory:requirement/implementation/test/doc/collaboration/unknown。unknown是显式取值:无信号不伪造原因(组织诚信规则 #9)。
2.2 仲裁规则(aggregate_reviews)
- 强制 ≥ 2 评审者——单评审者就是 Supervisor Retry,不是交叉验证,少于 2 抛
ValueError; - 检测分歧:pass 与 fail 同时出现 →
disagreement=True,并写入summary; - 仲裁:
majority:fail 多于 pass → 拒绝;平票安全偏向拒绝(绝不静默接受分裂裁决);weighted:比较 pass 侧与 fail 侧的Σ(weight·confidence),重侧胜,平局 → 拒绝;
- 合并重做目标:取所有 fail 评审者 的
recommended_rework ∪ affected_tasks,去重保序; - 接受条件:仲裁非拒绝 且 无重做目标。
2.3 重做分类(classify_rework)
确定性关键词打分(与 planner._heuristic_consistency_check 同族,可解释、无模型):
- 各
ReworkCategory有关键词信号集;命中即加分,最高分胜; - 分歧偏置:当
disagreement=True时,collaboration既 +1 票又赢平票——评审者分裂本身就是跨专家一致性缺口的证据; - 全无信号 →
unknown(不伪造)。
3. 接入现状(已无条件接入,取代单评审)
同伴交叉评审是蜂群唯一的评审路径,无开关:去中心化重构已删除单 critic 主控评审环(
maybe_run_review_cycle/review_loop_enabled)。main.py: run_cross_review在refresh_swarm_run_status中无条件运行(<2 评审时为 no-op,放行收敛)。
3.1 评审者来源(≥ 2 独立意见)
同伴 Agent 经 WS review_decision 消息提交独立评审 → main.py: handle_review_decision 累积到 run.metadata["reviews"];run_cross_review 在收齐 ≥ 2 条时 aggregate_reviews(...) 仲裁。reviewer_agent_id 取提交者,weight 可按角色信任赋值。weighted 法用 weight·confidence 比较,平票安全偏向拒绝。
3.2 状态与事件
- 状态:
run.metadata["cross_review"]存AggregatedVerdict.to_dict(),run.metadata["rework_attributions"]存[ReworkAttribution.to_dict()],与review_cycles并存(MAX_REVIEW_CYCLES预算复用);拒绝则reopen_task返工目标、run 退回running。 - 事件不进 Manager 流:
review.*/rework.*的 payload builder 已实现但不经emit_event外发(未在 Manageragent_callback.go注册;与swarm.health/convergence.*同策略,避免向订阅全部的回调投递未登记事件)。重开通过既有timeline.updated反映。登记后方可启用 Manager 侧发送。
3.4 不变量
- 不改 Manager 面接口、HMAC 回调、审批链、计费 / 审计字段语义;
- 信息素学习(
decision_engine)、沙箱双门控(quality)等其它开关不受影响; - 纯协议层无副作用:可在无密钥、无 Redis、无 WS 的环境单测(见 §5)。
4. 与基准 P_rework / Reward 的关系
基准执行层(swarm-metrics-schema.md §2):
R = ... − w₈·P_rework (w₈ = 0.05)
P_rework = ReworkCount/TotalTasks×100
schema 标注 P_rework 当前是「retry 派生、已知低估口径」。本模块把每次重做升级为带 root_cause 的 ReworkAttribution:
ReworkCount可由rework.requested事件数(或rework_attributions长度)精确计数,而非从retry_count反推;- 可按
ReworkCategory分桶(requirement/impl/test/doc/collaboration),让采集器区分重做归属的阶段,而不是一个无差别 retry 数; collaboration类重做(评审者分歧驱动)正是「蜂群协同验证」要暴露的信号——它对应S_collaboration(§3 蜂群层)的反面证据。
接入采集是后续工作:本任务仅提供结构化输入与协议;
benchmark/collectors/run_collector.py的消费留待接入 PR,且须遵守 schema 的「无信号 → NaN,不伪造」口径。
5. 测试
..\.venv\Scripts\python.exe scripts\test-cross-review.py
Hermetic(无 WS / 无模型 / 无 Redis),覆盖:单评审者被拒绝;两评审者分歧检测与 majority/weighted 仲裁;一致通过即接受;三评审者多数否决与重做目标去重;重做归因与 ReworkCategory 分类(含分歧偏置 collaboration、无信号 → unknown);四个事件 payload builder;非法 verdict / 缺评审者 id 的构造校验。