H²R
Agent 记忆 · 经验反思 · arXiv 2025

H²R:把一条整任务经验拆成「做什么」和「怎么做」两本账,检索时才不会互相污染

现有多任务智能体把一次经验打包成一条记忆,新任务里哪怕只有一个子目标可复用,也会把无关的子目标一并检索进来。 这篇论文把记忆拆成高层规划记忆与低层执行记忆,用一套事后反思流程从轨迹里自动建起来,测试时 Planner 只查高层、Executor 只查低层。

H²R: Hierarchical Hindsight Reflection for Multi-Task LLM Agents · 中山大学等 arXiv 2509.12810 ↗
TL;DR · 30 秒抓住核心

问题的根不在「检索得不够准」,而在检索粒度和知识粒度不对齐:记忆单元是整任务的,需要复用的却只是一个子目标。论文把它命名为 coarse-grained knowledge transfer。

解法是两层账本:高层单元存「任务描述 + 成功子目标序列 + 规划洞察」,供 Planner 用;低层单元存「单个子目标 + 对应子轨迹 + 执行洞察」,供 Executor 用。任何子目标都能独立被检索、独立被复用。

账本不是人工写规则,而是事后反思自动生成:先让 Planner 回退成「直接输出任务」,再对成功 / 失败轨迹做对比,用 add / modify / upvote / downvote 四种操作维护一张固定大小的洞察池,最后把相关洞察挂靠到每个记忆单元上。

80.5%
PDDLGame 成功率(Table 1)
ExpeL 72.2 · ReAct 66.7
27.7pt
去掉高层记忆后的跌幅(Table 2)
80.5 → 52.8
3 集
每个环境的 held-out 测试集数量(§V-A)
三次独立运行取平均
01

经验本身没错,错在把整条任务打包成一条记忆

读完后你能说清:为什么复用一条「整任务经验」会主动引入干扰。

LLM 智能体做多任务的通用套路是「经验库 + 检索」:把过去任务里学到的洞察抽出来存进记忆,遇到新任务就检索最相关的几条塞进 prompt。论文 §II-C 把现有做法归为这一类,Reflexion、Voyager、ExpeL 都是它的变体。

论文 §I 用一个例子点破问题所在:智能体学过「清洗平底锅并放到台面」,现在要「冷却生菜并放到台面」。两边共享的是「放到台面」这个子目标,但记忆是按整个任务存的——检索回来的是「清洗平底锅并放到台面」这一整条单元,里面大量内容都在讲「清洗平底锅」。

核心矛盾

检索是最相关的,但携带的知识是最不相关的

整任务记忆在检索阶段看起来没问题——新任务确实和旧任务相似。可一旦进了上下文,真正能复用的那一个子目标只占一小块,其余全是当前用不上的子目标。论文说这会「分散注意力、增加认知开销」(§I,引 [8])。

这意味着单纯改进检索器解决不了它:要检索的东西本身粒度错了。

论文 §III 把这个设定形式化为 POMDP:智能体在训练任务集 𝒟train 上积累经验,然后要在没见过的 𝒟test 上表现好。核心挑战就是「遇到新任务时实现高效的知识迁移」。于是问题变成:记忆应该以什么粒度存储,才能让「相似」在检索时恰好等于「可复用」?

02

已有两条路:一条没记忆,一条有记忆但颗粒太粗

这是论文实验里的两个基线,也是它要跨过的两档。

ReAct

边想边做,不带记忆

推理与行动交替的范式(§II-A),每一步只依据当前轨迹和环境反馈决定下一步。

强项:通用、不需要任何工程化的记忆设施。

盲区:每个新任务都从零摸索——即便和旧任务高度同构,也复用不了半点经验。Table 1 里它是两条线上最低的。

ExpeL

有记忆,但记忆是整任务的

从成功与失败轨迹中抽取洞察,用 add / modify / upvote / downvote 维护一个洞察池(§II-C、§IV-B1)。

强项:确实能跨任务积累,Table 1 相对 ReAct 大涨。

盲区:论文认为它的经验单元是 monolithic 的——一条记忆代表整个任务,于是 §I 描述的那种「无关子目标混进来」的问题它没法避免。

值得注意的是,H²R 并没有另起炉灶:它的洞察抽取机制直接沿用 ExpeL 的那套四操作(§IV-B1 原文:using the mechanism proposed in ExpeL),连收集经验时用 Reflexion 分析失败轨迹也是「following the experience-gathering strategy of ExpeL」(§IV-B)。它改动的只有一件事——记忆的切分方式。这也让 Table 1 的对比变得干净:变量基本只剩粒度。

03

核心方法:两本账本,各记各的粒度

读完后你能说出每一类记忆单元存了什么、在测试时被谁检索。

单元结构(§IV-A、Fig. 1)

ℳ_high · 高层规划记忆

每个任务一个单元

  • 𝒳:任务描述
  • 𝒢:执行过程中实际达成的子目标序列
  • ℐ_plan:与规划相关的洞察
ℳ_low · 低层执行记忆

每个子目标一个单元

  • g:子目标描述
  • τ:该子目标对应的子轨迹
  • ℐ_low:与执行相关的洞察

两层都只存成功轨迹里得到的子目标序列,失败轨迹不单独成册,而是作为对比材料进入洞察抽取。低层单元只从成功轨迹里推断出的子目标来建,论文的理由是「保证低层记忆单元的可靠性」(§IV-B2)。

论文强调这和 RAG 的差别:这些单元来自智能体与环境的交互与事后反思,而不是事先给定的外部知识库(§IV-A)。

怎么让 Planner 与 Executor 各用各的(§IV-C)

测试时是标准的 Planner–Executor 拆分,记忆的接法很直接:

ℳ_highrel = top-km∈ℳ_high sim(𝒳, 𝒳i)     ℳ_lowrel = top-km∈ℳ_low sim(g, gi)
Eq. 5 / Eq. 6 · 高层按任务描述查,低层按子目标描述查;sim 为预训练句向量编码器的余弦相似度,实现可用 FAISS

关键在于:检索对象变了。高层检索时对比的是任务,所以「冷却生菜放台面」会把「清洗平底锅放台面」整条任务拉回来,但它只带着子目标序列和规划洞察;当 Planner 说要执行「放到台面」时,Executor 检索的是低层库里的子目标,命中的是「放到台面」那一个单元,而「清洗平底锅」那批低层单元根本不会被检索到。

自己点一下:同一条旧经验,两种粒度检索结果差在哪

场景取自论文 §I 的例子。下面是一条旧任务的整任务经验;切换「整任务记忆 / 分层记忆」两种模式,点选新任务的子目标,看 Executor 实际拿到哪些内容。

ℳ_high · 高层(按任务描述检索)
ℳ_low · 低层(按子目标检索)
当前要执行的子目标(点一个)
检索结果
先选一个子目标。
这个演示用了什么、没用什么?简化说明

记忆单元的内容、高 / 低两层的划分、Planner 查高层 / Executor 查低层,都按论文 §IV 的描述构造;「放到台面」「冷却生菜」「清洗平底锅」三个子目标出自 §I 的引言例子。

指标栏里的不相关子目标子单元和无关规划洞察,是把 §I 所说的「整任务单元可能携带无关子目标知识」做成可数的代理量;检索命中情况则按 §IV-C 的「按子目标相似度取 top-k」规则演示。论文没有给出各类单元的统计数字,这里也不假装有。

真实的句子编码器、top-k 的 k 取值与 FAISS 检索都没有模拟——这一步只负责说明「粒度」如何决定 Executor 看到什么。

04

怎么建:四次 LLM 调用把一条轨迹拆成两本账

读完后你能复述 Algorithm 1 的主循环,并知道每一步为什么放在这个位置。

采集阶段先做一个反直觉的改动

§IV-B 说:Planner 对任务内部结构了解有限,可能生成「贡献很小甚至阻碍进度」的子目标。所以在训练 / 采集经验阶段,高层 Planner 被约束成直接输出当前任务,不生成任何子目标;失败轨迹用 Reflexion 分析,沿用 ExpeL 的经验采集策略,目的是让同一任务下一次尝试更容易成功。采集到的是「带成功 / 失败标签的轨迹」,子目标结构留给事后反思去推。

四个模块(Algorithm 1 主循环:第 2–16 行)

𝒢i ← ℱsubgoal(𝒳i, τi)     ℐhigh ← ℱhigh(𝒳i, τ+i, τ−i, 𝒢+i, 𝒢−i, ℐhigh)
𝒯 ← ℱtrajectory(𝒳i, τ+i, 𝒢+i)     ℐlow ← ℱlow(gi, τ+i, τ−i, ℐlow)
Eq. 1–4 · 紫色是高层反思,红色是低层反思;每个模块都是一次 LLM 提示(附 one-shot 示例,见 Fig. 1)
F_subgoal

子目标推断

对成功轨迹 τ₊ 和失败轨迹 τ₋ 各自推断一遍子目标序列(Algorithm 1 第 4–5 行)。理由是:要评价 Planner 提的子目标好不好,得先知道这条轨迹里实际达成了什么。推断出的子目标锚定在智能体真实执行过的动作上,论文据此假定 Executor 已成功执行它们。

F_high

高层洞察抽取:成功 vs 失败对比

在固定大小的集合 ℐhigh 上,让 LLM 对洞察做添加、修改、点赞(提高重要性)、点踩(降低重要性)四种操作——机制直接来自 ExpeL。同一任务的成功轨迹与失败轨迹成对进入,因此这种反思天然是对比式的。

F_trajectory

子轨迹切分

只切成功轨迹:按成功子目标序列 𝒢₊ 把整条轨迹切成一一对应的子轨迹 𝒯。这一步是把经验「降粒度」的关键动作,也是低层记忆能「一个子目标一个单元」的前提。

F_low

低层洞察抽取

每个子目标 gi 结合它的子轨迹与同一任务的失败轨迹,更新 ℐlow。Fig. 1 给出的低层洞察例子是「动作失败时,检查当前合法动作列表」。

最后一步把所有单元回填洞察

主循环里先只放 (𝒳i, 𝒢+i, ∅) 和 (gi, τ+i, ∅),洞察位置留空(Algorithm 1 第 8、14 行)。等全部洞察挖完,再遍历每个单元,用一个 LLM grounding 函数 Fground 从整张洞察池里挑出与该单元相关的洞察挂上去(第 18–25 行)。

设计要点

为什么要「两遍」而不是边挖边挂

高处与低处共享同一个任务的成败对比,但低层反思建立在高层的产物之上——子目标序列先出来,子轨迹才能切,低层洞察才有载体。论文正是因此把方法命名为 Hierarchical Hindsight Reflection(§IV-B2)。
后置的挂靠也让 ℐhigh、ℐlow 两个固定大小的池子在不断被 add / modify / vote 的过程中保持开关一致,挂靠时每个单元看到的是最终完整版本。

开了几个 LLM 和要多少钱(论文没给的,这里也不编)

§V-A 只交代了模型与评测规模:所有组件——反思、规划、执行——都用 Qwen3-235B-A22B-Instruct-2507,检索相似度用 Qwen3-Embedding-0.6B。反思成本用调用次数粗算:一次采集出的(成功, 失败)轨迹对,2 次子目标推断 + 1 次高层反思 + 1 次子轨迹切分 + 每个子目标 1 次低层反思,再加全部单元各一次 grounding。论文没有报告 token 开销、延迟或与 ExpeL 的成本对比。

05

整条流水线:离线建账,在线分账

把上面两节连起来看:左半边只在离线做一次,右半边每个测试任务都在跑。

离线 · 在 𝒟_train 上建账(§IV-B) 在线 · 在每个 𝒟_test 任务上分账(§IV-C) 采集轨迹 Planner 直接输出任务不拆子目标 Reflexion 分析失败 沿用 ExpeL 采集策略 ℱ_subgoal 成功 / 失败各推一遍子目标序列 ℱ_high · 高层洞察池 add / modify / upvote / downvote ℱ_trajectory 成功轨迹按子目标切成子轨迹 ℱ_low · 低层洞察池 每个子目标 + 子轨迹 + 同任务失败轨迹 F_ground 回填:为每个单元挂上相关洞察 ℳ_high = (𝒳, 𝒢₊, ℐ_high) · ℳ_low = (g, τ₊, ℐ_low) Planner 任务 + 规划历史 + 轨迹 + top-k 高层记忆 → 子目标 低层检索 按子目标 g 取 top-k ℳ_low Executor 子目标 + 轨迹 + 低层记忆 → 原子动作 / a₊ / a⁻ 环境 返回 observation a₊/a⁻ 触发重新规划 ℳ_h Planner 只读高层 · Executor 只读低层 参数符号用 ℳ_h / ℳ_l 简写
依据 §IV-B、§IV-C 与 Algorithm 1 重绘的流水线(原 Fig. 1 / Fig. 2 为位图)。左半部分离线完成,右半部分每个测试任务执行一轮。
展开说明 ▸
  • 采集阶段的反常之处:Planner 在采集时被禁用拆分能力,直接输出任务本身。论文的解释是避免「不合适的子目标」污染采集到的轨迹(§IV-B)。
  • 反思阶段是离线的:Algorithm 1 在全部(成功, 失败)轨迹对上一次性跑完,最后才统一 grounding。在线阶段不再调用任何反思模块。
  • 在线循环:Planner 出子目标 → Executor 逐动作执行 → 环境反馈 → Executor 判定完成后给出 a₊,或判定不可达时给出 a⁻ → 两种情况都回到 Planner 重新规划。AlfWorld 每回合上限 30 步,PDDLGame 40 步(§V-A)。
  • 虚线回路表示 a₊ / a⁻ 触发的重新规划;这样 Executor 不必把子目标硬做到底,规划与执行可以来回协商。
06

效果:两个基准都赢,复杂规划环境赢得最多

先把论文给的三张数表摆全,再说反直觉的地方和它没说的部分。

方法AlfWorld 成功率PDDLGame 成功率
ReAct46.366.7
ExpeL72.472.2
H²R75.980.5

Table 1 · 相对 ExpeL 的提升:AlfWorld +3.5,PDDLGame +8.3(论文原文口径,§V-B)

实验设置(§V-A):两个基准的数据集各切一半做训练、一半做评测;AlfWorld 包括 pick_and_place、pick_clean_then_place、pick_heat_then_place、pick_cool_then_place、look_at_obj、pick_two_obj 六类任务,PDDLGame 包括 barman、gripper、tyreworld 三类。

消融:两本账缺一本都塌,缺高层塌得更狠

Table 2 只报告了 PDDLGame(注意:AlfWorld 没有给消融数据)。论文正文把跌幅写成 27.7% 和 19.4%,下面是按成功率点差还原的绝对差距。

去掉该层后保留的百分点 相对完整 H²R 的损失
怎么读
完整 H²R 为 80.5。去掉高层记忆后只剩 52.8——Planner 再也拿不到子目标序列和规划洞察,「只能在没有战略规划知识的情况下运行」(§V-C)。去掉低层记忆后剩 61.1,Executor 拿不到执行洞察和子目标级模式。 缺高层比缺低层多丢 8.3 个点,与 PDDLGame 更偏「分层规划」的假设一致。

三个不仔细读就会误读的地方

读数一

正文写的「3.5% / 8.3%」是百分点,不是相对提升

原文写 representing relative improvements of 3.5% and 8.3%,但 75.9 − 72.4 = 3.5、80.5 − 72.2 = 8.3,都是成功率之差。若按真正的相对提升算,AlfWorld 约为 4.8%、PDDLGame 约为 11.5%。引用时以点差为准。

读数二

「27.7% / 19.4%」也不是成功率本身

它们是相对 80.5 的下降比例:13.4 / 80.5 ≈ 16.6%,8.3 / 80.5 ≈ 10.3%,与正文数字对不上;而原始点差正是 27.7 与 19.4。因此正文这两个数字只能理解为绝对降幅的另一个说法(或论文的笔误),消融图按点差画。

读数三

评测面很小,没有置信区间

§V-A:evaluated on three held-out test episodes per environment,averaged across three independent runs。每个环境只有 3 个 held-out episode,论文没有报告方差、区间或显著性检验。75.9 与 72.4 之间 3.5 点的差距是否稳定,仅凭 Table 1 无法判断。

换一种读法:论文的「反直觉」不是 H²R 赢了,而是它赢在 ExpeL 没有改动的地方——洞察抽取机制、反思采集策略、甚至基座模型都是同一套,唯一动的是「一条经验存成几个单元、每个单元存什么」。同样的原料换一种切法,PDDLGame 上就多了 8.3 个点。

07

什么时候它不够用

按证据强度从硬到软排列。前两条是原文数据里的问题,后三条是根据流程推导的边界。

边界一 · 原文数据

只测了两个离散的文本环境

AlfWorld 与 PDDLGame 都是文本、离散动作空间。连续动作(机器人控制)或高维视觉输入下,怎么把轨迹切成「子轨迹」、怎么用句向量比较「子目标」,论文都没有验证。§VI 自己也把「更复杂、更动态的环境」列为未来工作。

边界二 · 原文数据

评测规模撑不起细粒度结论

每个环境 3 个 held-out episode、3 次运行,无方差报告。Table 2 只有 PDDLGame,所以「去高层比去低层更伤」这一结论在 AlfWorld 上没有得到验证。

边界三 · 流程推导

整条链都建立在一个 LLM 的子目标推断上

低层记忆完全依赖 ℱsubgoal 从轨迹里推出来的子目标序列:子目标推错,子轨迹切错,低层单元就挂错。论文以「推断出的子目标锚定在真实动作上」为前提假定 Executor 执行成功(§IV-B1),但没有报告推断准确率,也没有做对该环节的敏感性分析。

边界四 · 流程推导

记忆只增不改,固定大小的洞察池可能是瓶颈

Algorithm 1 只往 ℳhigh、ℳlow 里 add,没有删除、合并或淘汰机制;洞察池则是固定大小的集合,随着任务类型变多,新经验要挤进有限的名额。开放世界中规则不断变化的场景下,这套账本如何遗忘与压缩,原文未涉及。

边界五 · 流程推导

离线反思的成本被完整跳过

每个(成功, 失败)轨迹对至少四次 LLM 调用,再加每个子目标一次低层反思、每个单元一次 grounding;而且全部使用 Qwen3-235B-A22B-Instruct-2507。论文没有给出 token 数、耗时或与 ExpeL 的成本对比,所以「精度提升了多少倍代价」目前无从判断——这也是未来应用时最该先补的实验。

一句话总结:H²R 解决的是「记忆粒度与复用粒度不对齐」,不是「记忆不够多」。如果你的场景里子目标是清晰、可切分、可复用的,这套两层账本值得照抄;如果经验本身就是粒度粗糙的,或者对成本敏感,先把子目标推断的准确率和反思开销测清楚再说。