Files
Agentswarm/docs/swarm/task-competition-protocol.md
T
Songhaoz666andClaude Opus 4.8 f2662e4268 复审整改(PR #26):删死开关 helper、文档对齐"无条件"、swarm.health 改内部、#6 降为 Refs
回应 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>
2026-06-10 16:48:27 +08:00

8.0 KiB
Raw Blame History

Agent 任务竞争协议(Task Competition Protocol)

解决 issue #8:「Agent 自主竞争机制缺失:任务无法被抢占、竞价、协商或重新接管」。

本文档是该机制的唯一入口。机制实现于 orchestrator/task_competition.py(纯仲裁),已接入 WS 主循环(去中心化重构 P4):main.py 新增 task_bid/task_yield/task_takeover_request 分支与 handle_task_bid/arbitrate_and_assign/handle_task_yield/handle_task_takeover——竞价收集→确定性仲裁(τ 加权)→择优 finalize_dispatch 分派;让渡复用 release_task;接管须 decisive 胜出方可重分派。仲裁/竞价/让渡审计存 run.metadata(内部遥测)。feature flag ENABLE_TASK_COMPETITION(构建期;cutover 转无条件)。集成测试 scripts/test-swarm-competition.py。模块单测 scripts/test-task-competition.py。

1. 背景与缺口

当前派发是单向拉取:空闲 Agent 拉取就绪任务(task_queue.get_ready_pending_task),由到达顺序固定 Agent 一侧;ACO 决策引擎(decision_engine.py)在 ENABLE_ACO_DISPATCH=1 时按 P_i = τ^α·η^β / Σ 采样任务,但仍是「Agent 挑任务」的单边匹配。缺失的是 Agent 之间围绕同一个任务的主动博弈:

  • 竞价(bid):多个 Agent 同时声明「我能做这个任务」,附上自评置信度、成本、耗时、风险。
  • 让渡(yield):持有任务的 Agent 主动释放,给出理由,并可推荐接手者。
  • 接管(takeover):另一个 Agent 请求从当前持有者手中接过任务(持有者卡住、或请求者更合适)。
  • 仲裁(arbitrate):一个确定性、可审计的裁决器在竞价者中选出赢家,并记录理由与落败者。

2. 接入现状(已无条件接入,无开关)

竞争协议是蜂群固有行为,无 ENABLE_* 开关(本仓即 swarm 运行时)。main.py 始终生效的 WS 分支 task_bid / task_yield / task_takeover_request → handle_task_bid(累积竞价到 run.metadata["bids"])/ arbitrate_and_assign(τ 加权确定性仲裁 → finalize_dispatch 择优分派)/ handle_task_yield(复用 release_task)/ handle_task_takeover(须 decisive 胜出方可重分派)。仲裁/竞价/让渡审计存 run.metadata(内部遥测,非 Manager 事件)。task_competition.py 模块本身仍是纯逻辑 + 数据模型(不碰 Redis/WS/计费/审批链)。

3. 消息 / 数据模型(orchestrator/task_competition.py)

模型 字段 含义
TaskBid task_id, agent_id, confidence, estimated_cost, estimated_time, risk_score, reason, capabilities, current_load 一次竞价。confidence/risk_score∈[0,1];estimated_cost=占 run 预算比例;estimated_time=秒;current_load=在飞任务数
TaskYield task_id, agent_id, release_with_reason, recommend_agent? 主动让渡 + 理由 + 可选推荐接手者
TaskTakeoverRequest task_id, requesting_agent_id, current_agent_id?, reason, bid? 接管请求,可携带 bid 以便与持有者在同一标准下被仲裁
ArbitrationScore agent_id, total, components{} 单个竞价者的逐项打分明细(审计)
TaskArbitrationResult task_id, winner_agent_id, reason, decisive, scores[], losers[], policy, arbitrated_at 裁决结果:赢家、人读理由、是否「明确」、全量分数、落败者、所用策略

4. 仲裁算法(arbitrate(bids, policy, *, required_capabilities, historical_success))

纯函数,确定性。 每个竞价独立打分(无共享可变状态),然后按 (total 降序, agent_id 升序) 稳定排序,头部即赢家。agent_id 兜底排序消除了对输入顺序和字典迭代顺序的依赖 —— 相同输入恒得相同赢家、相同分数、相同有序落败列表。

每项分量先归一化到 [0,1] 再乘策略权重;「越低越好」的字段(成本/耗时/风险/负载)转为余量 1 - 归一值,使「越高越好」统一成立:

分量 来源 默认权重
capability 竞价 capabilities 对任务 required_capabilities 的覆盖率 0.25
historical_success(τ) 复用 ACO 信息素 trail 的「挣来的声誉」pheromone:{role}:{id};缺失 → 文档化中性 0.5(对所有竞价同值,不扭曲排序,同 decision_engine 对缺失 confidence 的处理) 0.25
confidence 竞价自评置信度 0.20
budget 成本余量(越便宜越高) 0.10
risk 1 - risk_score 0.10
time 速度余量(越快越高) 0.05
load current_load 余量(越闲越高) 0.05

权重由 ArbitrationPolicy 提供,非负、无需归一(相对比较)。decisive_margin(默认 0.02):当头两名分差低于它时,结果标记 decisive=False,理由中建议转 Manager 审核而非自动分配 —— 仲裁仍是确定的(赢家=稳定排序头部),但把「过于接近的平局」交回人工/审批链,符合 heicodeDocs 安全与审批约束。

τ 是真实输入:测试断言「其余完全相同、仅声誉不同」时高 τ 者胜,证明 historical_success 真正改变结果而非装饰字段。

5. 事件载荷构建器(builders)

下列函数只构建 payload dict,不发射。形状对齐既有 HM 事件(task_id + 角色/id + 人读 summary):

函数 event_type
bid_submitted_event(bid) task.bid_submitted
yielded_event(yield_msg) task.yielded
takeover_requested_event(req) task.takeover_requested
arbitrated_event(result) task.arbitrated(携带全量 scores 与 losers 审计)

6. 测试

scripts/test-task-competition.py:模块级、无 Redis / WS / 模型(task_competition 无副作用,直接测真实仲裁数学)。覆盖:两 Agent 同任务竞价→更优者胜并记录可审计理由与落败者;输入乱序 / 重复调用结果字节一致(确定性);τ 单因子决胜;死平局不 decisive 且兜底确定 + 建议审核;空竞价;让渡(带理由 + 推荐);接管请求并与持有者仲裁;自定义策略权重改变结果;全部事件 builder。

运行(在 agent_swarm_v6 下,先装依赖):

pip install -r orchestrator/requirements.txt
..\.venv\Scripts\python.exe scripts/test-task-competition.py

结果:35/35 PASS(ALL PASSED)。

集成现状(已接入)

已落地于 orchestrator/main.py(无开关):

  1. WS 入站分支(紧邻 peer_message/handoff_request):task_bid → handle_task_bid(按 agent 去重累积到 run.metadata["bids"]);task_yield → handle_task_yield(复用 task_queue.release_task,不增 retry_count);task_takeover_request → handle_task_takeover(请求者 bid 与持有者中性 bid 一并送 arbitrate)。
  2. 仲裁分派:arbitrate_and_assign(run, task_id) 取 run.metadata["bids"] → arbitrate → 赢家经 finalize_dispatch 分派;审计存 run.metadata["arbitrations"]/["yields"]。
  3. τ 注入:historical_success 由 decision_engine.get_tau(...) 逐竞价者取值(经 normalize_tau)传入 arbitrate,与自选/ACO 共用同一声誉源。
  4. 事件不进 Manager 流:task.bid_submitted/yielded/takeover_requested/arbitrated 的 builder 已实现但不经 emit_event 外发(未在 agent_callback.go 注册;与 peer_message/swarm.health 同策略——仅内部遥测)。登记后方可启用 Manager 侧发送。
  5. 审批 / 计费 / 审计(后续硬约束):decisive=False(接近平局)或接管已分配任务时,按 heicodeDocs 应走 Manager 审批链而非自动改派;当前实现仅在 decisive 胜出时改派,平票不改派(记录待 review)。任何改派保留 usage 与 X-Agent/X-Agnet 归属。专用「竞价窗口」收集期(定时触发 arbitrate_and_assign)为后续优化。