一、层级规划为什么越拆越散
很多团队把单步 Agent 升级为层级规划后,任务完成率反而下降。HTN 拆分子目标后,中层计划与底层执行频繁脱节。
1.1 高层目标与子行动的断裂
Agent 收到"预订北京到上海商务舱机票"目标,HTN 拆分为查询航班、选择舱位、填写信息、支付四个子目标。实际运行中子目标 2 选了商务舱,子目标 3 却沿用经济舱证件要求导致提交失败。高层意图在分解中被稀释,子行动与原始目标出现语义断层。
[外链图片转存中…(img-NTuJl8FG-1779258310576)]
🔍 这是典型的承诺漂移:规划承诺与执行环境不一致。⚠️ 还有边界漂移:相邻子目标状态互相侵入。🔄 以及回退缺失:失败后缺乏局部回滚。
| 漂移类型 | 典型表现 | 影响范围 |
|---|---|---|
| 承诺漂移 | 查询结果过期仍被使用 | 单个子目标 |
| 边界漂移 | 状态假设跨层污染 | 相邻子目标对 |
| 回退缺失 | 失败后无状态重置 | 整个任务链 |
[外链图片转存中…(img-8Yu0WQvW-1779258310582)]
二、HTN 规划失稳的根因
分解深度超过三层时,原始意图保留率急剧下降。实验表明五个子目标的链中,根节点关键约束仅四成穿透到底层。💡 分解函数只传显式参数,隐式约束如"商务舱"在逐层传递中丢失。
多数实现采用规划与执行分离架构。规划器在 t0 生成完整子目标链,执行器在 t1 到 tn 依次消费。环境变化后早期承诺过期,Agent 缺乏运行时验证机制。
三、Subgoal Verification 与回滚
解决思路是在子目标前后加入验证闸门。
3.1 子目标可达性预检
执行前运行轻量预检,验证环境是否满足入口条件。预检不修改环境,成本控制在单次执行的 5% 以内。
classSubgoalVerifier:def__init__(self,env_snapshot:dict):self.baseline=env_snapshotdefcheck(self,subgoal,current_env:dict)->bool:forkey,expectedinsubgoal.preconditions.items():ifcurrent_env.get(key)!=expected:returnFalsereturnTrue3.2 执行偏差检测与回滚
执行前创建环境快照,失败时恢复到上一稳定状态。
defrun_with_rollback(agent,plan):snapshots=[agent.env.snapshot()]forstepinplan.subgoals:ifnotverifier.check(step,agent.env):plan.replan_from(step)continuetry:step.execute(agent.env)snapshots.append(agent.env.snapshot())exceptExecutionError:agent.env.restore(snapshots[-1])plan.escalate(step)🛡️ 回滚细化到单个子目标后,重试率从 34% 降到 7%,恢复时间缩短为全量重试的八分之一。
[外链图片转存中…(img-FAJou9TP-1779258310585)]
四、效果验证
对比三种策略运行 500 条任务:
| 策略 | 完成率 | 平均步数 | 恢复时间 |
|---|---|---|---|
| 纯 HTN | 61% | 12.3 | 无 |
| HTN + 预检 | 74% | 11.8 | 无 |
| 完整方案 | 89% | 11.5 | 1.2s |
📊 预检解决承诺漂移,回滚解决回退缺失,叠加后边界漂移也大幅下降。⚡ 快照有存储成本,长任务建议增量快照,只存变更字段。
五、趋势判断
层级规划未来会朝两个方向演进:一是规划-执行耦合更紧密,ReAct 交错模式被吸收进 HTN。二是验证下沉到模型层,由基座模型输出前置条件与后置断言。
🎯 工程团队最务实的做法是为现有 HTN 增加轻量验证层,在不替换架构前提下把完成率提升到可用水平。
总结
子目标漂移本质是信息分解丢失与承诺过期两个问题的叠加。引入预检与快照回滚可在不颠覆 HTN 前提下显著改善稳定性。关键是把验证粒度对齐到子目标边界。
🔥 你在层级规划中遇到过子目标与高层意图脱节的情况吗?欢迎分享实践经验。如果这篇文章对你有启发,记得点赞收藏,后续会持续更新更多 Agent 工程稳定性的深度分析。