v0.12 以来 HATT / delivcoal 更新总结

按问题线索整理,不按版本流水账展开。重点看做过哪些尝试、验证和证伪了什么、现在还缺什么。

覆盖范围v0.12 到 v0.15.5
主线问题HATT 在 delivcoal 中的稳定性、探索、Idle 和动态重组
阅读方式先看问题结论,再看算法流程

1. HATT 在 delivcoal 里为什么失败

v0.12 之后的主问题是:HATT v2.0 在 capcoal 这类能力匹配问题里比较自然,但到 delivcoal 配送场景中会不稳定,常见表现是反复待命、探索效率低、best checkpoint 和 last checkpoint 差距大。

做过的尝试

  • 加 decoder-only 信息路径消融:rawphysicstaskattn
  • 加资源和候选集合上下文:resourcesetctx
  • no-idle 变体,把 persistent Idle 屏蔽单独拿出来看。
  • 加 finite idle timeout,把单次 Idle 最长等待限制到固定步数。
  • 加 allocation diagnostics,统计 payload shortage / surplus、harmful idle、useful idle 等指标。
  • 加特殊动作对照:clean no-idle、special action detached、split head、任务类型编码和 gate。

验证了什么

  • HATT 的失败不只是“一次 Idle 卡太久”。有限 Idle 能把单次待命限制住,但 HATT 被唤醒后仍会继续选 Idle。
  • Idle 确实是有害自由度。No-Idle 明显强于 Idle-25,说明当前策略没有合理利用 Idle。
  • 特殊动作污染很关键。Explore / Idle / Resupply 和 Deliver 共用候选任务表示、共用联盟聚合时,会干扰配送任务关系建模。
  • detached 之后 HATT best 明显改善,说明把特殊动作从配送联盟聚合中分出去是有效方向。

证伪了什么

  • 单靠 finite idle timeout 不能修复 HATT。
  • 单靠给 decoder 加 raw task row、物理量、资源阶段或候选集合上下文,还不能稳定解决 delivcoal。
  • 单纯说“Idle 联盟上下文导致一切问题”也不够。清空 Idle 联盟上下文会降低 Idle 倾向,但差 checkpoint 仍可能继续 Idle。

剩下的问题

  • 特殊动作 detached 能让 best 变强,但训练末期仍退化。
  • MAPPO 在部分相同条件下仍比 HATT 更稳,说明 HATT 结构和 PPO 训练稳定性还有问题。
  • 现在更像是找到了主要污染源,但还没形成最终稳定方法。

2. 探索为什么失败

v0.14.0-v0.14.2 把探索问题拆开看:到底是找不到任务,还是找到任务后不会配送。

做过的尝试

  • sector 探索改成 agent-relative 表示:每个 agent 看到的是自己从当前位置出发会去的目标。
  • agent 到达 sector 目标后重新决策。
  • 发现新任务后打断旧探索动作,允许转去配送。
  • 屏蔽地图边界处无效探索方向。
  • 加 coverage 网格,记录地图哪些区域已经被搜索。
  • Explore 观测加入候选路径的新覆盖面积、路径长度、全局未搜索比例。
  • 加 all-visible 和 delivery-only 评估开关,把探索和配送拆开诊断。

验证了什么

  • 原 sector 表示不够。它不能表达“当前 agent 走这个方向能搜到什么”。
  • 直接前往最近未发现任务给了过强先验。改成真实方向探索后,任务明显更难。
  • 到达探索目标后重新决策很关键,否则 agent 会继续执行已经没有意义的探索。
  • coverage 是关键状态信息。HATT+coverage 的发现率、任务完成率、成功率都明显提高。
  • RNN 单独不是主要解法。coverage 比 recurrence 更像是在补探索状态缺口。

证伪了什么

  • “只要加记忆就能解决探索”不成立。
  • “探索失败只是一个调度 bug”不完整。调度语义要修,但观测也缺信息。
  • “找任务”和“配送”不能混在一起看。all-visible / delivery-only 结果显示,任务可见性变化会显著改变结论。

剩下的问题

  • coverage 是近似网格,不是精确几何覆盖。
  • HATT+coverage best 很好,但 last 仍会低于 best。
  • 纯配送条件下仍有待命和补给调度问题。

3. Idle 是否应该被惩罚,是否需要预留空闲运力

v0.14.4-v0.14.6 进一步检查 Idle 的语义:agent 选 Idle 到底是错,还是有时应该主动保留空闲运力。

做过的尝试

  • 在所有任务已知且禁止 Explore 的条件下,检查 agent 选择 Idle 时是否还能为未完成任务补足载荷。
  • 把“可疑 Idle”从只看 Deliver 扩展到 Resupply:如果全局缺载荷、agent 空载且能补给,不应直接 Idle。
  • 取消 Idle 额外时间惩罚,改成统一时间成本。
  • 构造第二批任务延迟出现的场景,比较“多余 agent 原地待命”和“加入当前配送”。
  • 改待命位置、加入短期服务承诺、调整卸货方式,检查 reserve 的物理收益来自哪里。

验证了什么

  • 去掉 Idle 额外惩罚后,HATT best 明显改善。
  • 但改善不是因为模型学会了合理 reserve。控制状态诊断里,HATT 仍不会稳定保留空闲运力。
  • reserve 不是天然有价值。原地待命可能减少总路程,但不一定缩短完成时间。
  • reserve 的收益依赖具体机制:等在哪里、是否有服务承诺、能耗预算和任务出现位置。

证伪了什么

  • “HATT 差只是因为 Idle 被奖励函数惩罚”不成立。
  • “应该鼓励长期空闲 reserve”没有被当前环境支持。
  • “卸货方式导致载荷天然浪费”也被排除;按比例卸货和重新分配没有带来额外改善。

剩下的问题

  • 如果以后要研究 reserve,需要先明确现实机制:待命位置、能耗、服务承诺、任务到达过程。
  • 当前环境下不应把长期 Idle 当成显式目标。

4. 原文联盟重组机制是否有用

v0.15 开始重点转向原文动态联盟重组机制:智能体是否应该保持当前任务,还是在事件、周期或学习式 gate 下重新选择任务。

做过的尝试

  • 复现多种重组方式:原有行为、每次都重选、固定周期、任务事件、任务紧迫度和 learned gate。
  • 修复评估配置,保证 checkpoint eval 继承训练时的重组设置。
  • 加显式 reconfiguration context,让 gate 看到新任务、任务完成、当前任务是否有效、距上次重选多久、episode 进度和紧迫度。
  • 加 switch gate,让 gate 直接表示“离开当前任务”的概率。
  • 加 gate override,用同一 checkpoint 做 force-open、force-closed、event、event_or_learned 干预。
  • 加 hierarchical gate,把“是否重新决策”和“重新决策后选哪个任务”拆成两层动作。
  • 保存 gate action,并在 PPO update 时重放,避免训练时重新采样 gate 导致 ratio 对不上 rollout 动作。
  • 加 reconfiguration decision cost,筛选非强制状态下主动重选是否需要更稀疏。
  • 加 gate metrics,统计 mandatory open rate 和 learned open rate。
hierarchical gate 仍然算 learned 方法。它不是像 event / periodic / urgency 那样用固定规则决定重组;它只是在建模上把 learned gate 拆成两步:先学“非强制状态下要不要重新决策”,再在开门后交给 HATT 选任务。mandatory open 是环境强制部分,不属于 learned;真正需要评估的是 learned open 是否真的带来收益。

验证了什么

  • 简单 event 规则和原有 legacy 比当前 learned gate 更稳。
  • learned gate 能减少“每次重选决策真的换任务”的比例,但没有换来更高成功率。
  • 每次都重选会退化,容易频繁待命和少探索。
  • 只加显式 context 不够。
  • switch gate 更可解释,但成功率没有稳定提升。
  • force-closed 很差,说明“保持当前任务”不是简单修复。
  • hierarchical gate 是更干净的 learned 方法。gate action 可解释,PPO replay 对齐,也没有明显 Idle collapse。
  • mandatory open 正常,说明强制重选链路执行没问题。
  • learned open 偏保守,而且和成功率关系还不清楚。

证伪了什么

  • “原文重组机制复现后自然提升”不成立。
  • “重选越频繁越好”不成立。
  • “给 gate 加事件信息就够了”不成立。
  • “把 gate 改成可解释 switch 形式就够了”不成立。
  • “cost0.05 单种子最好,所以就是最终方法”不成立;seed2 / seed3 没有复现更强优势。

剩下的问题

  • hierarchical gate 现在只是更可解释、更正确的建模方式,还没有证明能提升成功率。
  • learned gate 还没学会“什么时候主动重选真的有用”。
  • event / legacy 仍是更稳的重组基线。
  • 需要把 gate open 时刻和具体任务事件、任务完成、响应时间联系起来看。

5. 当前方法的大致算法流程

观测

每个 agent 得到结构化观测:ego 是自身状态,others 是队友状态,tasks 是配送任务和特殊动作槽,reconfiguration 是可选重组上下文。

HATT 编码

  • agent-agent attention:看队友。
  • task-agent attention:看每个任务和 agent 的匹配。
  • coalition aggregation:看当前任务已有联盟成员。
  • task decoder:对每个候选动作打分。

特殊动作处理

Deliver 是真实配送任务,Explore / Idle / Resupply 是控制动作。后续结论说明,它们不应该无脑共享 Deliver 的联盟聚合,否则特殊动作会污染配送任务之间的关系。

探索 coverage

Explore 不再只是抽象方向,而是带有实际搜索收益:这个方向能覆盖多少新区域、要走多远、全局还有多少区域没搜。这样 HATT 能更早停止重复探索,把时间留给配送。

hierarchical gate

  1. 环境判断 agent 是否 active,需要重新请求动作。
  2. actor 先采样 gate action:是否重新决策。
  3. 如果 gate 关闭,保持当前任务。
  4. 如果 gate 打开,再从 HATT task distribution 里选任务。
  5. 当前任务完成、失效、全队停住等 mandatory 场景强制打开。
  6. rollout 保存 gate action。
  7. PPO update 时用保存的 gate action 重算 log prob。
这样做的好处是:gate 不再是从最终任务动作里猜出来的,而是 PPO 真正训练过的动作变量。

6. 现在还缺什么

  • HATT+coverage 的训练稳定性仍未完全解决。best 可以很强,但 last / p90 仍会波动。
  • learned reconfiguration 还没有超过 event / legacy。
  • hierarchical gate 只证明了建模更清楚,没有证明最终效果更强。
  • learned open rate 和成功率之间的关系还不明确。
  • 纯配送场景里仍存在待命、补给和任务切换问题。
  • reserve idle 的价值没有被当前环境自然支持,除非后续明确建模能耗、等待位置或服务承诺。
  • 多 seed 证据还不够。很多判断已经有方向,但最终方法选择还需要更统一的统计口径。

7. 下一阶段正在补的证据

最新一轮对话已经把后续验证拆成两组正式入口。

gate 因果评估

这组不重新训练,直接复用已经训练好的 hierarchical cost0.05 三个 seed,在 best / last checkpoint 上做四种 gate 干预:

  • event_or_learned:事件强制开门,其余状态交给 learned gate。
  • event:只在任务事件中开门,去掉 learned off-event 开门。
  • force_open:所有可决策状态都开门。
  • force_closed:非强制状态全部关门。

它要回答的问题很直接:hierarchical gate 现在的 learned open 到底有没有实际贡献。如果 eventevent_or_learned 接近,说明 learned 部分还没带来多少收益;如果 force_openforce_closed 明显变差,可以进一步确认“总是重选”和“总是保持”都不是好策略。

detached × coverage 因子实验

这组重新训练,用 event 重组固定决策时机,把两个已经被证明重要的方向做 2×2 三 seed 对照:

  • plain:原 HATT v2.0。
  • detached:特殊动作不进配送联盟聚合。
  • coverage:探索动作带覆盖信息。
  • detached + coverage:同时使用特殊动作分离和 coverage。

它要回答的是:coverage 和特殊动作分离到底是各自独立有用,还是主要由其中一个解释;两者叠加后能不能比单独 coverage 或 detached 更稳。这个实验比继续调 learned gate 更基础,因为如果状态表示和动作表示本身还没理顺,gate 学得再复杂也可能只是在补前面的坑。

这两组目前还是实验入口和运行流程,不能写成结论。等评估完成后,才应该回填成功率、任务完成数、gate 干预差异和 detached×coverage 的交互效果。

8. 一句话总结

v0.12 以来的工作不是简单“调 HATT 参数”,而是在逐步拆解 delivcoal 失败来源:先排查信息路径,再定位特殊动作和 Idle 污染,再修探索观测,之后检查 reserve 是否真的有价值,最后复现并扩展原文动态重组机制。现在比较确定的是:coverage 和特殊动作分离是实质性有效方向;hierarchical gate 是更合理的 learned 重组建模方式,但还没有证明能带来稳定性能提升。