1. HATT 在 delivcoal 里为什么失败
v0.12 之后的主问题是:HATT v2.0 在 capcoal 这类能力匹配问题里比较自然,但到 delivcoal 配送场景中会不稳定,常见表现是反复待命、探索效率低、best checkpoint 和 last checkpoint 差距大。
做过的尝试
- 加 decoder-only 信息路径消融:
raw、physics、taskattn。 - 加资源和候选集合上下文:
resource、setctx。 - 加
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。
验证了什么
- 简单 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
- 环境判断 agent 是否 active,需要重新请求动作。
- actor 先采样 gate action:是否重新决策。
- 如果 gate 关闭,保持当前任务。
- 如果 gate 打开,再从 HATT task distribution 里选任务。
- 当前任务完成、失效、全队停住等 mandatory 场景强制打开。
- rollout 保存 gate action。
- PPO update 时用保存的 gate action 重算 log prob。
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 到底有没有实际贡献。如果 event 和 event_or_learned 接近,说明 learned 部分还没带来多少收益;如果 force_open 或 force_closed 明显变差,可以进一步确认“总是重选”和“总是保持”都不是好策略。
detached × coverage 因子实验
这组重新训练,用 event 重组固定决策时机,把两个已经被证明重要的方向做 2×2 三 seed 对照:
- plain:原 HATT v2.0。
- detached:特殊动作不进配送联盟聚合。
- coverage:探索动作带覆盖信息。
- detached + coverage:同时使用特殊动作分离和 coverage。
它要回答的是:coverage 和特殊动作分离到底是各自独立有用,还是主要由其中一个解释;两者叠加后能不能比单独 coverage 或 detached 更稳。这个实验比继续调 learned gate 更基础,因为如果状态表示和动作表示本身还没理顺,gate 学得再复杂也可能只是在补前面的坑。
8. 一句话总结
v0.12 以来的工作不是简单“调 HATT 参数”,而是在逐步拆解 delivcoal 失败来源:先排查信息路径,再定位特殊动作和 Idle 污染,再修探索观测,之后检查 reserve 是否真的有价值,最后复现并扩展原文动态重组机制。现在比较确定的是:coverage 和特殊动作分离是实质性有效方向;hierarchical gate 是更合理的 learned 重组建模方式,但还没有证明能带来稳定性能提升。