Files
Agentswarm/docs/benchmark/decision-engine.md
T
Songhaoz666andClaude Opus 4.8 a289495823 复审整改(PR #24):沙箱 fail-closed 隔离门控 + 可回放 DecisionTrace
回应 Fasthei 的 Request changes 两个阻塞项:

1) 安全 / fail-closed 沙箱隔离(原仅靠 ENABLE_QUALITY_EVAL + 运维约定):
   - 新增第二道显式确认 HEICODE_SANDBOX_ISOLATED(断言运行在隔离 Pod 内)。
   - sandbox.run_tests() 与 quality.evaluate_run_quality() 执行任何代码前调用
     assert_isolated(),未确认即抛 SandboxIsolationError——不写文件、不起子进程。
   - 启动期 assert_quality_eval_safe():ENABLE_QUALITY_EVAL 开但隔离未确认 → 拒绝启动
     (平台级硬失败,非运维口头约定)。
   - 文档(security-boundary §8.1/§9、CLAUDE.md)与测试同步:test-sandbox/test-quality
     先断言未确认时硬失败,再显式确认后继续。

2) #10 DecisionTrace 可回放(原仅存被选中任务的标量):
   - Decision 现记录完整重放上下文:整个候选集(每候选 tau/eta/weight/p_norm/dependents)、
     alpha/beta/epsilon、seed、free_slots、total_weight、explore_draw、select_pick、
     select_index、explored 分支。
   - 新增 DecisionEngine.replay_decision(trace):仅凭一条 trace(无 RNG/活体状态)复现被选任务;
     test-decision-engine 断言「重放==实选」跨 50 次决策(探索+利用)成立。
   - decision-engine.md §3.3 更新为可回放 DecisionTrace。

附:新增 docs/TESTING.md(reviewer 速查:依赖安装 + 每套测试命令,复审者此前因缺 fakeredis
未能跑到断言)。本地 11 项 gate 全绿。

影响范围:Swarm(orchestrator + 测试 + 文档)。不改 Manager↔Swarm 契约;新增开关
HEICODE_SANDBOX_ISOLATED(默认未设=拒绝执行)。仍非验收:gain/Benchmark_Agent 仍 NaN。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 13:22:54 +08:00

6.6 KiB
Raw Blame History

ACO 决策引擎(Benchmark Group A):τ / η / P_decision

让标准 §3 的决策层指标由 NaN 转为可测:派发从「确定性贪心首配」变为「信息素 × 启发式的概率采样」。本文档是该机制的唯一入口。

1. 方案选型:Option A(score-at-pull,单边)

派发是双边匹配(任务挑 Agent / Agent 挑任务)。本实现取 Option A:

  • 候选集 = 「当前空闲 Agent 视角下的全部就绪任务」。Agent 由到达顺序固定,任务由 P_i = τ_i^α·η_i^β / Σ 采样选出(ε-greedy 探索,ε=0.10)。
  • 已知局限(单边):τ 影响的是「该 Agent 先做哪个任务」,而非「该任务给谁做」——强专家若晚到,仍可能输给先拉取的弱者。全局双边匹配(Option B:matchmaker 调度 tick + hold 策略)推迟到 Group C 基线就绪后再评估,因为「更优匹配」是一个当前无法度量的优化命题。
  • A 是 B 的严格子集:信息素库、η 评分、采样、遥测、collector 全部复用,B 只需更换选择触发点。

2. 双半开关(核心设计)

半边 开关 默认 行为
学习(信息素沉积) 无(常开) 开 任务到达终态即更新 τ trail。纯被动观察,不改变任何派发行为;为未来开启选择积累「实测声誉」而非冷启动先验
行动(概率选择) ENABLE_ACO_DISPATCH 关 关闭时派发与原贪心逐字节一致;开启时走采样路径并记录决策遥测

CI 同时跑两条:默认全套(flag off,证不变性)+ ENABLE_ACO_DISPATCH=1 ACO_SEED=42 的 e2e(证开启后工作流仍完整收敛)。

3. 机制

3.1 信息素 τ(pheromone:{agent_role}:{agent_id},Redis)

  • 更新(标准 §3.1):τ(t+1) = (1−ρ)·τ(t) + Δτ,ρ=0.10,夹紧到 [0.05, 1.0](正性保证 τ^α 良定义;上界即 trail 饱和)。
  • Δτ = metrics.pheromone(...),只喂真实信号:success(1/0)、quality(暂 = success,run 级 fixture 评分发生在任务完成之后、沉积之时不可得)、cost(任务成本/run 预算,未知则 0)。acceptance/time/risk/rollback 无信号 → 0,不伪造(规则 #9)。
  • 冷启动 τ₀ = 0.5(中性先验);单次 run 的 τ 多为先验,需多 run 积累才是「挣来的声誉」——已如实标注。
  • trail 按 (agent_role, agent_id) 键控、跨 run 持久(这正是 τ 的意义)。

3.2 启发式 η(纯函数,无新状态)

metrics.heuristic(...) 输入全部来自编排器既有状态:match(required∩caps 的 Jaccard,奖励专精)、urgency(任务等待时长,300s 饱和)、dependency(下游依赖数,3 饱和)、resource(Agent 空闲槽位)、confidence=0.5(无信号 → 对所有候选同值中性常数,不扭曲排序)、risk/budget_pressure=0(无信号)。下限夹紧 0.05。

3.3 选择与遥测

  • P_i = τ^α·η^β / Σ(α=1, β=2),ε-greedy 均匀探索防饿死(低 τ Agent 仍偶得任务,从而有机会重建 trail)。
  • 可回放 DecisionTrace(PR #24 复审整改):每次采样记录的不只是被选中任务,而是重放/解释该选择所需的全部上下文:
    • 被选中:task_id/agent_id/agent_role/tau/eta/p_norm/p_score;
    • 完整候选集 candidates[]:每个候选的 task_id/agent_role/tau/eta/weight/p_norm/dependents;
    • 超参与上下文:alpha/beta/epsilon/seed/free_slots/total_weight;
    • RNG 与分支:explore_draw(与 ε 比较的抽样)、explored(探索/利用分支)、select_pick(利用分支的绝对 pick)、select_index(解析出的候选下标)。 存入 SwarmRun.decisions(内部状态,不进 Manager 事件流,上限 1000 条)。
  • 重放验证:DecisionEngine.replay_decision(trace) 仅凭一条 trace(无 RNG、无活体状态)即可复现被选中的 task_id,逻辑与 select() 完全一致。test-decision-engine.py 断言「重放 == 实选」跨 50 次决策(探索+利用两分支)成立 → 满足 #10「DecisionTrace 可回放」DoD。
  • p_score = τ^α·η^β·100(标准 §3.3 的 P_decision 公式);p_norm 为该候选集内的归一化概率,两者并存以免混淆。
  • collector:run 级 tau/eta/p_decision = 决策记录的均值;无记录 → NaN + coverage=False。

3.4 确定性与 CI

随机源可经 ACO_SEED 固定(CI 用),生产不固定。超参可经 ACO_ALPHA/ACO_BETA/ACO_RHO/ACO_EPSILON 覆盖,默认取标准 §7.2 推荐值。

4. 文件

文件 职责
orchestrator/decision_engine.py τ 存取/沉积、η 评分、ε-greedy 采样、Decision 遥测载体
orchestrator/task_queue.py: get_ready_pending_tasks 候选枚举(不出队;选中后再 remove_pending_task)
orchestrator/main.py 派发环 ACO 分支 + 四个任务终态处的 deposit_pheromone + 决策落库
orchestrator/swarm_runtime.py: SwarmRun.decisions / record_decision 决策遥测存储
benchmark/collectors/run_collector.py tau/eta/p_decision 聚合
scripts/test-decision-engine.py 22 项断言(trail 数学/夹紧/键控、η 排序、种子化采样分布、探索、遥测→collector、枚举不出队)

5. 与 #9(dispatch scoring)的边界

Issue #9(调度评分)与 #10(τ/η/P 决策模型)耦合但分工明确:

  • #9 出「打分输入」:候选 Agent×任务的可解释评分维度(capability_match、load、budget_pressure、risk、historical_success、estimated_cost/time),以及每次派发的候选列表与排除原因(dispatch.decision_made)。
  • #10 出「概率决策」:把这些维度归一为 τ(历史)与 η(先验),按 P=τ^α·η^β/Σ 概率采样,并产出可回放的 DecisionTrace。

本仓 decision_engine.py 已实现 #10 的概率决策层与 τ/η 的最小喂入;#9 的「完整打分 schema + 候选/排除可解释性」为独立增量(docs/scheduling/dispatch-score-schema.md、dispatch.decision_made 事件),不在 #10 关闭范围内。

6. 诚实边界(本机制未关闭的)

  • 决策质量未证:概率派发是否优于贪心是经验命题,需 Group C 的对比 harness 才能回答;在此之前生产默认关闭。
  • τ 的 quality 输入暂 = success(无每任务质量信号);acceptance/time/risk 无信号 → 0。
  • 单边匹配(见 §1);Option B 推迟。
  • gain/s_swarm/g_e/g_e_cost/benchmark 仍 NaN——Group A 不动验收的针。