把本仓从「Master 分解→派发→单评审」重构为去中心化自组织蜂群,并设为唯一行为
(本仓即 swarm 运行时,模式选择在仓外,无 ENABLE_swarm 开关)。依据:heicodeDocs 弱中心
定义 + 蜂群文章(stigmergy)+ OpenAI Swarm(handoff)。
流程(全部无条件生效):
- 播种 build_seed_task_specs(不主控分解)→ 自选 swarm_dispatch(能力+τ+负载+预算,唯一派发)
→ 自主分解 task_proposal(autonomous_tasks)→ 竞争/接管 task_bid/yield/takeover(task_competition)
→ 同伴交叉评审 ≥2 评审者(cross_review,取代单 critic)→ 收敛 ConvergenceReport+termination_reason
(convergence)→ 守卫 guard.diagnose(检测无法运作并列原因)。
删除:planner 主控分解、贪心/ACO/scored 派发与 scored_matchmake、单 critic 评审环、
全部 ENABLE_* swarm 构建开关。master_agent.synthesize 作为汇总工具保留。
测试:test-workflow-e2e 改写为真实 swarm 全流程;test-merge-smoke 改为 seeder/cross-review;
新增 test-swarm-{seed,dispatch,autonomous,competition,cross-review,convergence,guard} + 模块单测;
CI 同步。本地 18 套全绿。
影响范围:agent_swarm(orchestrator + 新模块 + 测试 + docs + CI)。不改 Manager↔Swarm 事件契约
(新事件均为运行时内部状态/遥测,不进 HM 注册表);不影响 Client/计费/密钥/审计/发布链路。
无新增长期开关。
诚实边界:不动 benchmark 验收(G_E 仍需真实 run,#13);convergence 暂为解释性(不强制覆盖
run.status);前端可见状态为跨端(#18);「去中心化是否更优」未证(需 Group C)。
#6 的 DoD(Path B 决策 + 定位文档)本 PR 已满足并实现 Path B → 关闭 #6。
#7/#8/#11/#12 的运行时机制已落地(事件 + e2e),但其 DoD 含前端可见状态(跨端 #18)与
多 Agent 回放,故以 Refs 链接、不自动关闭,留维护者在前端/验收就绪后关闭。
Closes #6
Refs #7
Refs #8
Refs #11
Refs #12
Refs #18
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
12 KiB
去中心化蜂群重构计划(Decentralized Swarm Rework)
状态:进行中(先建核心管线 → 切换为唯一路径 → 最后写守卫)。 依据:去中心化自组织蜂群模型(信息素/stigmergy)+ heicodeDocs 弱中心定义 + 复审工单 #6/#7/#8/#9/#11/#12。 关联:product-positioning.md(本计划即 ARB Path B)、swarm-definition-gap.md、各模块协议文档。
0. 范围与边界(重要)
- 本仓 = 蜂群运行时本身。模式选择(single/chain/sub/swarm)由项目其他部分负责,不在本仓。
- 因此本仓不设「启用 swarm」开关——swarm 不是本仓的一个可选模式,而是本仓的全部行为。
- 删除一切非 swarm 路径:Master 上游分解(planner fallback)、贪心/单 Agent 兜底、派发「模式」开关等作为本仓的替代路径一律移除。
- 唯一保留的兜底是「守卫(guard)」:检测「swarm 无法正常运作」并列出原因(如无可用 Agent、无模型、依赖死锁、预算耗尽)。守卫在整套程序构建完成后最后编写。
- Manager↔Swarm 契约保留:Manager 仍可经
/api/swarms下发;若提供agents明细,作为种子集;否则由 objective 播种。契约本身不删。
1. 目标形态(要把系统改成什么)
从「Master 中心化:主控分解 → 派发 → 评审」改为「去中心化自组织:编排器只播种 + 托管共享状态,Agent 自组织」。秩序与质量是涌现的,不是命令出来的。
核心循环(每个 Agent 重复直到收敛):
感知(perceive) → 决策(decide) → 执行(act) → 信息素沉积(stigmergy) → 收敛检查(converge)
- 播种器(Seeder):把用户 prompt 变成 1~少数种子任务写入共享池;不做完整主控分解、不做中心派发。(取代 Master planner 的「指挥」角色)
- Agent 自选/自生成/竞争:从共享池自选任务(信息素 τ + 启发式 η 驱动),可自主生成后续子任务(#7),多 Agent 可竞争/让渡同一任务(#8)。
- 质量靠同伴交叉评审 / 留出测试:不是自评通过(自评只用于 Agent 自己路由);验收由同伴 cross-review(#11)或 held-out 测试(Group B)裁定。
- 轻量仲裁者(Arbiter):仅在(a) Agent 间冲突、(b) 最终收敛/验收时介入;产出
termination_reason(#12)。不得退化为逐任务的 Master。 - 信息素(τ pheromone)为主协调媒介:成功/质量强化路径、随时间衰减——该引擎已存在(
decision_engine.py)。
三种协调通道(无中心调度器):stigmergy(信息素,主) / broadcast(消息总线) / handoff(交接)。任务带 DAG 依赖(Task.depends_on)。
2. 现状 → 目标 映射(已有积木 vs 缺口)
| 文章/标准概念 | 本仓现状 | 本次动作 |
|---|---|---|
| 信息素 / stigmergy | ✅ decision_engine.py τ trail(沉积+衰减,Redis,学习常开) |
升为主协调,非可选 |
| 共享环境 / 任务池 | ✅ task_queue(Redis)+ SwarmRun |
暴露为 Agent 可感知的共享状态(#7) |
| 去中心化自选 | 🟡 ACO/scored 仍由编排器循环驱动 | 转向 Agent 拉取自选(#9/#10 复用打分) |
| 自主任务生成 | 🟡 autonomous_tasks.py(已建未接) |
接线(#7) |
| 竞争/竞价 | 🟡 task_competition.py(已建未接) |
接线(#8) |
| 同伴交叉评审 | 🟡 cross_review.py(已建未接) |
接线(#11),取代单评审 |
| 收敛 + 终止原因 | 🟡 convergence.py(已建未接) |
接线进 refresh_swarm_run_status(#12) |
| Handoff | ✅ handoff_manager |
保留 |
| DAG 依赖 | ✅ Task.depends_on |
保留 |
| 「编排器只播种、不调度」 | ❌ 今天相反(planner + master_agent 指挥) | 核心改造(#6 Path B:播种器化) |
3. 分阶段计划(先建核心管线 → 切换为唯一路径 → 守卫)
无 ENABLE_SWARM_MODE 总开关(见 §0)。构建期为避免半成品成为唯一路径而打断仓库,旧 Master 路径临时保留,新管线逐件建好并单测;待核心管线(播种 + 自主分解 + 自选 + 交叉评审 + 收敛)齐备后,在 P-cutover 一次性切换为唯一路径并删除旧路径、改写测试。构建期的临时内部开关仅为「建到一半不破仓」,在 P-cutover 全部移除,不作为产品特性。
- P1 收敛/仲裁(最终门,#12):
convergence.py接入refresh_swarm_run_status,产ConvergenceReport+termination_reason。先 shadow(存run.metadata,不改run.status),cutover 时转 authoritative(收敛裁定决定终态)。✅ 已建 shadow。 - P2 播种器(#6 Path B 关键):
build_seed_task_specs把 objective 播为单一种子任务;不调用 master_agent.plan。✅ 函数已建(cutover 时成为唯一任务创建路径)。 - P3 自主任务生成(#7):✅ 编排器侧已接入(
main.py: handle_task_proposal+ WStask_proposal分支 +ENABLE_AGENT_TASK_PROPOSALS):Agent 提案 → 审查/去重/预算 → 入池为真实任务(带 lineage)。集成测试test-swarm-autonomous.py。剩余(Agent 侧):执行单元基于种子/共享态用 LLM 决定提哪些子任务(在 cutover e2e 用会提案的 stub agent 验证)。 - P4 竞争/让渡(#8):✅ 已接入(
main.pyWStask_bid/task_yield/task_takeover_request分支 +handle_task_bid/arbitrate_and_assign/handle_task_yield/handle_task_takeover+ENABLE_TASK_COMPETITION):竞价→τ 加权确定性仲裁→finalize_dispatch分派;让渡复用release_task;接管须 decisive。集成测试test-swarm-competition.py。 - P5 同伴交叉评审(#11):✅ 已接入(
main.pyreview_decision分支 +handle_review_decision+run_cross_review+ENABLE_CROSS_REVIEW):收集 ≥2 同伴独立评审→aggregate_reviews仲裁(分歧记录、安全偏向)→拒绝则 reopen 返工目标 + 归因;在refresh_swarm_run_status先于单 critic Master 评审。集成测试test-swarm-cross-review.py。cutover 时取代 Master 评审。 - P6 去中心化自选:✅ 已建(
main.py: swarm_dispatch+ENABLE_SWARM_DISPATCH):每个空闲 Agent 感知共享池、按 capability+τ+load+budget 自选最适任务(统一 #9 可解释打分 + #10 信息素 τ),记录可解释dispatch.decision_made。集成测试test-swarm-dispatch.py。cutover 时成为唯一派发,删除 greedy/ACO/scored 与各模式开关。 - P-cutover 切换为唯一路径:✅ 已完成。
swarm_dispatch为唯一派发(删 greedy/ACO/scored 分支 +scored_matchmake);build_seed_task_specs为唯一任务创建(删 planner-fallbackbuild_planner_task_specs/planner_fallback_enabled);删单 critic Master 评审环(maybe_run_review_cycle/review_loop_enabled),run_cross_review为唯一评审;收敛/提案/竞争/评审原语全部无条件(移除全部ENABLE_*构建开关);test-workflow-e2e改写为 seed→自选→自主分解→执行→收敛全流程(stub agent 改为感知种子后提案分解),test-merge-smoke的 planner/单评审用例改写为 seeder/cross-review;CI 同步。master_agent.synthesize作为汇总工具保留。 - P-guard 守卫(最后):✅ 已完成。
orchestrator/guard.py: diagnose(纯函数)检测NO_AGENTS_CONNECTED/NO_CAPABLE_AGENT/DEPENDENCY_DEADLOCK/BUDGET_EXHAUSTED/SEED_UNDECOMPOSED并给出可读原因;main.py: assess_swarm_health在派发环检测到「有待办却本 tick 无任何分派」时诊断受影响 run,存run.metadata["health"]并在不健康时发内部swarm.health事件(仅诊断,不改 run)。测试test-swarm-guard.py。这是唯一保留的非正常路径处理。
重构完成(P1–P6 + cutover + guard 全部落地)
去中心化蜂群已是本仓唯一行为:播种 → 自选 → 自主分解 → 竞争/接管 → 同伴交叉评审 → 收敛,外加健康守卫。无 ENABLE_* 模式开关;旧 Master 中心化路径(planner 分解、贪心/ACO/scored 派发、单 critic 评审)已删除。剩余为后续打磨(如 convergence authoritative 状态覆盖、真实多 Agent 竞争 e2e、benchmark Group C 度量去中心化是否更优)。
4. 契约要点(接线时遵守)
- 冲突检测:artifact 不一致 / 测试失败 / 评审分歧 / 依赖不一致(
convergence.py已定义)。 - 终止原因:
quality_reached/budget_exhausted/max_rounds_reached/risk_blocked/tasks_completed(终态必带其一)。 - 交叉评审:≥2 独立评审者;分歧→仲裁;安全偏向(平票→拒绝);返工归因供
P_rework。 - Manager 契约:新事件类型(
task.proposal_*/task.bid_*/review.*/convergence.*/dispatch.decision_made)默认只进 Swarm 内部状态/事件流,不进 Manager 回调注册表,除非在event-schema.md §4注册并与 HM 联调(跨端,单列)。
5. 诚实边界(本次重构不主张的)
- 不动 benchmark 验收:
G_E/Benchmark_Agent仍需真实模型 run(Group C/#13)。 - 去中心化是否优于中心化未证:是经验命题,需 Group C 对比 harness;但本仓不因此保留中心化兜底——本仓职责就是 swarm,模式取舍在仓外。
- 前端可见状态为跨端(#18):本仓只产出事件/状态,UI 由 Frontend 团队消费。
- cutover 后删除 Master/planner/贪心兜底:Master 不再是「中心化备选」,其
plan/review/synthesize中仍被 swarm 流程复用的部分(如汇总)保留为 swarm 内的工具函数,但不再作为独立的中心化派发/分解路径。
6. 参考实现:OpenAI Swarm(github.com/openai/swarm)映射
OpenAI Swarm 是轻量、教学型多 Agent 编排框架。其核心原语印证并细化本次设计:
| OpenAI Swarm 原语 | 含义 | 本仓映射 |
|---|---|---|
Handoff:函数 return another_agent 转移控制 |
无中心调度器;Agent 运行时自行决定把控制权交给谁 | 去中心化协调的核心:Agent 结果可声明「交给哪个角色/能力」(handoff_manager + #8 接管),取代中心派发 |
Result(value, agent, context_variables) |
一次函数返回可同时携带:输出 + handoff 目标 + 共享态更新 | 任务结果可同时携带:产物 + handoff/接管目标(#8) + 共享态写入 + 提案的后续任务(#7) |
context_variables(贯穿的共享 dict) |
黑板/共享状态 | 本仓共享状态 = Redis run 状态 + 任务池 + 信息素图(τ);Agent 感知它来决策 |
client.run() 循环 + max_turns |
无状态循环:补全→执行工具→按 handoff 切换→更新共享态→无函数调用则停 | run 生命周期 + 收敛裁定(#12);max_turns 正是用户要的 守卫雏形(防死循环/无进展) |
| 动态 instructions(context_variables) | 提示随共享态变化 | 派发上下文 build_dispatch_context 已按角色/依赖产物动态拼装 |
采纳:handoff 作为去中心化协调原语;run 循环 + max_turns 作为收敛 + 守卫的骨架;Result 的「输出+handoff+共享态+提案」四合一作为任务结果契约。
差异(本仓是 Swarm 的超集):OpenAI Swarm 为单进程、同一时刻一个活动 Agent、同步 handoff;本仓为多 WS Agent 并发 + stigmergy 信息素自选(Swarm 没有)。即:Swarm 的 handoff 原语 + 蜂群文章的并行/信息素。模型经本仓网关,非直连 OpenAI。
7. 受影响文件(预期)
- 代码:
orchestrator/main.py(派发环/refresh_swarm_run_status/WS 分支/播种/cutover 删旧路径)、orchestrator/swarm_runtime.py(状态字段)、接入autonomous_tasks/task_competition/cross_review/convergence/dispatch_score/decision_engine、新增guard(最后)。 - 文档:本计划、
product-positioning.md(Path B)、swarm-definition-gap.md、各协议文档(状态对齐)、README.md、CLAUDE.md、docs/TESTING.md。 - 测试:各阶段 hermetic 测试 + 改写
test-workflow-e2e/test-merge-smoke为 swarm 流程 + CI。