RL in Memory
背景知识
监督微调的做法是给它标准答案,让它模仿;强化学习的做法则是让模型先生成,再用一个奖励函数评价这次生成的结果,然后提高高奖励输出出现的概率,降低低奖励输出出现的概率。
把语言模型写成强化学习里的策略,记为 $\pi_\theta$。给定输入 $q$,模型生成一个输出序列 $o=(o_1,o_2,\ldots,o_T)$。在自回归模型里,第 $t$ 个 token 的生成概率是:
\(\pi_\theta(o_t \mid q,o_{<t})\) 完整输出的概率可以写成每一步 token 概率的乘积:
\[\pi_\theta(o \mid q)=\prod_{t=1}^{T}\pi_\theta(o_t \mid q,o_{<t})\]如果奖励函数 $R(q,o)$ 认为某个输出更好,我们就希望模型以后更容易生成类似的输出。最直接的策略梯度形式可以理解为:
\[\nabla_\theta J(\theta) = \mathbb{E} \left[ A(q,o)\nabla_\theta \log \pi_\theta(o \mid q) \right]\]这里的 $J(\theta)$ 表示我们希望最大化的训练目标,$\nabla_\theta J(\theta)$ 就是参数应该往哪个方向更新。右边的 $\nabla_\theta \log \pi_\theta(o \mid q)$ 会提高当前输出的概率,而 $A(q,o)$ 决定提高多少。$A(q,o)$ 是优势函数,它关心的是“这个输出比当前平均水平好多少”。如果 $A(q,o)>0$,说明这个输出比预期更好,训练会提高它的概率;如果 $A(q,o)<0$,说明这个输出比预期更差,训练会降低它的概率。
优势函数很重要,因为奖励本身可能尺度不稳定。比如一道题的奖励是 $0.8$,另一道题的奖励也是 $0.8$,它们未必表示同样的训练信号。前者可能已经是同组样本里最好的结果,后者可能只是中等水平。强化学习真正关心的是相对当前策略还能改进多少。
PPO(Proximal Policy Optimization)解决的是一个现实问题:如果一次更新太大,模型很容易被奖励函数带偏。我们当然希望提高高奖励输出的概率,但不能让新模型和旧模型差得太远。PPO 用新旧策略的概率比值来描述这一步更新幅度:
\[r_t(\theta) = \frac{ \pi_\theta(a_t\mid s_t) }{ \pi_{\theta_{\mathrm{old}}}(a_t\mid s_t) }\]在语言模型里,状态 $s_t$ 可以理解为当前已经看到的上下文 $(q,o_{<t})$,动作 $a_t$ 就是当前生成的 token $o_t$。如果 $r_t(\theta)>1$,说明新模型比旧模型更倾向于生成这个 token;如果 $r_t(\theta)<1$,说明新模型降低了这个 token 的概率。
如果只看策略梯度,我们会最大化下面这个目标:
\[\mathbb{E}_t \left[ r_t(\theta)A_t \right]\]这个式子很直观。若 $A_t>0$,增大 $r_t(\theta)$ 会让目标变大,模型会更偏向这个动作;若 $A_t<0$,减小 $r_t(\theta)$ 会让目标变大,模型会远离这个动作。问题在于,$r_t(\theta)$ 可能变得太大或太小,导致模型一步更新过猛。PPO 的做法是把概率比值裁剪在一个小范围内:
\[L^{\mathrm{CLIP}}(\theta) = \mathbb{E}_t \left[ \min \left( r_t(\theta)A_t,\, \operatorname{clip}(r_t(\theta),1-\epsilon,1+\epsilon)A_t \right) \right]\]这里的 $\epsilon$ 通常是一个较小的数,例如 $0.1$ 或 $0.2$。这个裁剪项的含义是:模型可以朝着奖励更高的方向更新,但当概率变化已经足够大时,就不再继续从这部分样本里获得更多收益。它并不精确限制每一个参数的变化,主要是用一个简单的目标函数让训练过程更稳。
上面的 $L^{\mathrm{CLIP}}(\theta)$ 只是 PPO 的策略更新项。大模型后训练里通常还会加上一个 KL 约束,让当前策略和参考模型保持接近。于是完整目标可以继续写成一个要最大化的 $J_{\mathrm{PPO}}(\theta)$:
\[J_{\mathrm{PPO}}(\theta) = L^{\mathrm{CLIP}}(\theta) - \beta \mathbb{E}_{q} \left[ D_{\mathrm{KL}} \left( \pi_\theta(\cdot\mid q) \parallel \pi_{\mathrm{ref}}(\cdot\mid q) \right) \right]\]这个式子可以分成两部分看:第一部分是前面讲过的 clipped policy update,第二部分控制模型与参考模型之间的距离。$\beta$ 越大,模型越保守;$\beta$ 越小,模型越容易被奖励函数牵着走。
PPO 还需要一个优势函数 $A_t$。最朴素的想法是:先看从状态 $s_t$ 开始实际拿到的后续回报,再和模型原本预估的价值做比较。记 $\hat{G}t$ 为从第 $t$ 步开始估计到的回报,$V\phi(s_t)$ 为价值模型对状态 $s_t$ 的预估,那么优势可以写成:
\[A_t = \hat{G}_t - V_\phi(s_t)\]这个式子里的 $V_\phi(s_t)$ 可以理解为基线。如果实际回报 $\hat{G}_t$ 高于这个基线,说明当前动作带来的结果比预期更好;如果低于这个基线,说明它比预期更差。
直接估计 $\hat{G}_t$ 方差会比较大,所以实践中常用 GAE(Generalized Advantage Estimation)来计算优势。它先定义一步的时序差分误差:
\[\delta_t = \rho_t+\gamma V_\phi(s_{t+1})-V_\phi(s_t)\]这里用 $\rho_t$ 表示第 $t$ 步的即时奖励,避免和前面的概率比值 $r_t(\theta)$ 混在一起。$\delta_t$ 衡量的是:拿到当前即时奖励并进入下一个状态后,结果是否超过了价值模型对 $s_t$ 的原本预期。GAE 再把后续多步的 $\delta$ 加权累积起来:
\[A_t^{\mathrm{GAE}} = \sum_{l=0}^{\infty} (\gamma\lambda)^l \delta_{t+l}\]这里两个公式里的 $\gamma$ 是同一个折扣因子,用来降低远期奖励和远期价值的权重。$\lambda$ 是 GAE 额外引入的平滑参数,用来控制看多远的时序差分误差,也就是后续每一步的“实际结果和原本价值预估之间的差”:$\lambda$ 越小,优势估计越接近一步时序差分,方差更低但偏差更大;$\lambda$ 越大,越接近完整回报,偏差更小但方差更高。因此 $(\gamma\lambda)^l$ 可以理解为“越往后的误差信号权重越低”。
这套做法在传统强化学习里很自然,因为环境经常能在每一步给出奖励。但语言模型的生成任务有一点特殊:很多时候,奖励函数只对完整输出给一个分数。模型生成了几十个或几百个 token,最后才知道这段输出整体好不好。为了把这个序列级奖励拆到 token 级别,PPO 需要价值模型、GAE、KL shaping 等一整套机制。它能工作,但系统会比较重。
GRPO(Group Relative Policy Optimization)可以看作是对这个问题的一种简化。它去掉了额外的价值模型,对同一个输入采样多个输出,再用组内相对分数来构造优势。
假设对同一个输入 $q$,旧策略一次采样出 $G$ 个输出:
\[\{o_1,o_2,\ldots,o_G\} \sim \pi_{\theta_{\mathrm{old}}}(\cdot\mid q)\]奖励函数分别给出分数:
\[R_i = R(q,o_i), \quad i=1,\ldots,G\]GRPO 用这一组奖励的均值和标准差来标准化每个输出的优势:
\[A_i = \frac{ R_i-\operatorname{mean}(R_1,\ldots,R_G) }{ \operatorname{std}(R_1,\ldots,R_G)+\eta }\]$\eta$ 是一个很小的常数,用来避免标准差为零。这个公式的直觉很直接:同一个输入下,谁比同组其他输出更好,谁就得到正优势;谁比同组平均水平更差,谁就得到负优势。
举一个简单例子。对同一个问题,模型采样了四个回答,奖励分别是:$0.9,\quad 0.6,\quad 0.2,\quad 0.1$,这组奖励的均值是 $0.45$,标准差约为 $0.32$。四个回答对应的优势大约是:$1.41,\quad 0.47,\quad -0.78,\quad -1.09$ 。于是前两个回答会被强化,后两个回答会被压低。
在具体优化时,GRPO 仍然保留 PPO 的概率比值和裁剪思想。对第 $i$ 个输出的第 $t$ 个 token,定义:
\[r_{i,t}(\theta) = \frac{ \pi_\theta(o_{i,t}\mid q,o_{i,<t}) }{ \pi_{\theta_{\mathrm{old}}}(o_{i,t}\mid q,o_{i,<t}) }\]然后把组内优势 $A_i$ 分配给这个输出里的 token。一个常见的 GRPO 目标可以写成:
\[J_{\mathrm{GRPO}}(\theta) = \mathbb{E} \left[ \frac{1}{G} \sum_{i=1}^{G} \frac{1}{|o_i|} \sum_{t=1}^{|o_i|} \min \left( r_{i,t}(\theta)A_i,\, \operatorname{clip} \left( r_{i,t}(\theta), 1-\epsilon, 1+\epsilon \right) A_i \right) - \beta D_{\mathrm{KL}} \left( \pi_\theta \parallel \pi_{\mathrm{ref}} \right) \right]\]最里面的 $\min(\cdot)$ 是 PPO 的裁剪目标;$A_i$ 来自同一输入下多个输出的相对奖励;最后的 KL 项用来约束当前模型和参考模型之间的距离。GRPO 的主要变化在于优势函数的来源:PPO 依赖价值模型估计每一步的优势,GRPO 直接用组内奖励标准化得到序列级优势,再把它用于这个输出序列的 token。
Memory-R1
Memory-R1 把系统拆成两个可以分别训练的 agent:Memory Manager 负责维护记忆库,Answer Agent 负责从检索到的记忆里筛选信息并回答问题。两者都可以用 PPO 或 GRPO 训练。
对于 Memory Manager。给定一条新信息 $x$ 和当前已有的记忆库 $\mathcal{M}_{\mathrm{old}}$,我们把它们合在一起记为输入:
\[q^{\mathrm{mem}} = (x,\mathcal{M}_{\mathrm{old}})\]Memory Manager 的输出是一个结构化动作,记为:
\[o^{\mathrm{mem}} = (u,m')\]其中 $u$ 是操作类型,可以是 $\texttt{ADD}$、$\texttt{UPDATE}$、$\texttt{DELETE}$ 或 $\texttt{NOOP}$;$m’$ 是这次操作对应的新内容或修改后的内容。于是 Memory Manager 就可以写成一个策略:
\[o^{\mathrm{mem}} \sim \pi_\theta(\cdot \mid q^{\mathrm{mem}})\]模型需要在当前记忆状态下选择一个操作。比如新信息和旧信息互补时,更合理的动作可能是 $\texttt{UPDATE}$;新信息是全新事实时,可能是 $\texttt{ADD}$;如果没有值得保存的内容,则应该是 $\texttt{NOOP}$。
Memory-R1 的奖励直接取决于这次操作更新后的记忆库能不能帮助下游问答。记更新后的记忆库为:
\[\mathcal{M}_{\mathrm{new}} = T(\mathcal{M}_{\mathrm{old}},o^{\mathrm{mem}})\]这里的 $T(\cdot)$ 表示按照操作 $o^{\mathrm{mem}}$ 更新记忆库。然后把 \(\mathcal{M}_{\mathrm{new}}\) 交给冻结的 Answer Agent,让它回答关联问题,得到预测答案 $y_{\mathrm{pred}}$ 。Memory Manager 的奖励来自答案是否正确:
\[R^{\mathrm{mem}} = \mathrm{EM}(y_{\mathrm{pred}},y_{\mathrm{gold}})\]$\mathrm{EM}$ 是 exact match,即预测答案和标准答案是否精确匹配,直接评价记忆操作的最终效果。
如果用 PPO 训练 Memory Manager,公式和上一节完全一致。对一次采样出的操作 $o^{\mathrm{mem}}$,概率比值可以写成:
\[r(\theta) = \frac{ \pi_\theta(o^{\mathrm{mem}}\mid q^{\mathrm{mem}}) }{ \pi_{\theta_{\mathrm{old}}}(o^{\mathrm{mem}}\mid q^{\mathrm{mem}}) }\]然后最大化 clipped objective:
\[J_{\mathrm{PPO}}^{\mathrm{mem}}(\theta) = \mathbb{E} \left[ \min \left( r(\theta)A,\, \operatorname{clip}(r(\theta),1-\epsilon,1+\epsilon)A \right) \right]\]这里的 $A$ 来自答案正确性奖励 $R^{\mathrm{mem}}$。如果这次记忆操作让后续问答变得正确,它会得到更高优势;如果更新后的记忆状态导致回答失败,它的优势就会更低。
GRPO 版本中,对同一个 $q^{\mathrm{mem}}$,策略一次采样 $G$ 个候选记忆操作:
\[\{o^{\mathrm{mem}}_1,\ldots,o^{\mathrm{mem}}_G\} \sim \pi_{\theta_{\mathrm{old}}}(\cdot\mid q^{\mathrm{mem}})\]每个候选操作都会更新一次记忆库,并通过冻结的 Answer Agent 得到一个答案正确性奖励:
\[R_i^{\mathrm{mem}} = R^{\mathrm{mem}}(q^{\mathrm{mem}},o_i^{\mathrm{mem}})\]再按组内相对分数计算优势:
\[A_i^{\mathrm{mem}} = \frac{ R_i^{\mathrm{mem}} - \operatorname{mean}(R_1^{\mathrm{mem}},\ldots,R_G^{\mathrm{mem}}) }{ \operatorname{std}(R_1^{\mathrm{mem}},\ldots,R_G^{\mathrm{mem}})+\eta }\]这个式子和前面的 GRPO 公式是同一个思想,只是奖励变成了“这次记忆操作是否让后续问答正确”。Memory-R1 论文里的 GRPO 目标写得更紧凑,本质上就是把 $A_i^{\mathrm{mem}}$ 放回 PPO 式的概率比值更新里,并加上 KL 约束:
\[J_{\mathrm{GRPO}}^{\mathrm{mem}}(\theta) = \mathbb{E} \left[ \frac{1}{G} \sum_{i=1}^{G} r_i(\theta)A_i^{\mathrm{mem}} - \beta D_{\mathrm{KL}} \left( \pi_\theta \parallel \pi_{\mathrm{ref}} \right) \right]\]这里省略了 token 级求和,因为 Memory-R1 在 Memory Manager 公式里把一次结构化操作作为整体动作来写
Answer Agent 的训练更接近普通问答。给定问题 $q$ 和检索得到的候选记忆 $\mathcal{M}_{\mathrm{ret}}$,论文按照 Mem0 风格检索 60 条候选记忆,然后让 Answer Agent 先做 memory distillation,再生成答案。输入是:
\[q^{\mathrm{ans}} = (q,\mathcal{M}_{\mathrm{ret}})\]输出是答案:
\[o^{\mathrm{ans}} = y\]因此策略可以写成:
\[y \sim \pi_\theta(\cdot\mid q^{\mathrm{ans}})\]Answer Agent 的奖励也用 exact match:
\[R^{\mathrm{ans}} = \mathrm{EM}(y_{\mathrm{pred}},y_{\mathrm{gold}})\]如果用 GRPO,对同一个 $q^{\mathrm{ans}}$ 采样 $G$ 个候选答案 ${y_1,\ldots,y_G}$,再用 exact match 得到 $R_1^{\mathrm{ans}},\ldots,R_G^{\mathrm{ans}}$,组内标准化后得到:
\[A_i^{\mathrm{ans}} = \frac{ R_i^{\mathrm{ans}} - \operatorname{mean}(R_1^{\mathrm{ans}},\ldots,R_G^{\mathrm{ans}}) }{ \operatorname{std}(R_1^{\mathrm{ans}},\ldots,R_G^{\mathrm{ans}})+\eta }\]然后仍然使用同一个 GRPO 目标更新答案策略。和 Memory Manager 不同,Answer Agent 的输出就是答案文本,所以它的概率比值可以直接按生成序列来写:
\[r_{i,t}^{\mathrm{ans}}(\theta) = \frac{ \pi_\theta(y_{i,t}\mid q^{\mathrm{ans}},y_{i,<t}) }{ \pi_{\theta_{\mathrm{old}}}(y_{i,t}\mid q^{\mathrm{ans}},y_{i,<t}) }\]Mem-α
Mem-α 只学习如何构建和更新记忆,检索和问答模块保持固定。换句话说,训练信号来自“最终构造出来的记忆好不好”,而策略本身只负责写入、更新和删除。
设一条样本被切成一串上下文片段:
\[\mathcal{C} = \{c_1,\ldots,c_n\}\]模型从空记忆 $\mathcal{M}_0$ 开始,按顺序处理每个片段。第 $t$ 步的输入可以写成:
\[q_t^{\mathrm{write}} = (c_t,\mathcal{M}_{t-1})\]Mem-α 允许模型在一个片段上连续发出多个函数调用。记第 $t$ 步的输出为:
\[o_t^{\mathrm{write}} = a_t = \left(a_t^{(1)},\ldots,a_t^{(K_t)}\right)\]其中每个 $a_t^{(k)}$ 都是一个写操作,可以是 $\texttt{memory_insert}$、$\texttt{memory_update}$ 或 $\texttt{memory_delete}$。这些操作会依次作用在当前记忆上,这样处理完所有片段后,就得到最终记忆 $\mathcal{M}_n$ :
\[\mathcal{M}_{t}^{(0)} = \mathcal{M}_{t-1}\] \[\mathcal{M}_{t}^{(k)} = T\left( \mathcal{M}_{t}^{(k-1)}, a_t^{(k)} \right), \quad k=1,\ldots,K_t\] \[\mathcal{M}_t = \mathcal{M}_{t}^{(K_t)}\]Mem-α 的记忆结构分成三类:core memory、semantic memory 和 episodic memory。core memory 是持续可见的压缩摘要;semantic memory 存事实和知识;episodic memory 存带时间信息的事件。这个结构会影响函数调用是否合法,也会影响后面的内容质量奖励。
Mem-α 把最终问答正确性扩展成四项奖励:
第一项是正确性奖励。处理完整个上下文后,用固定 RAG 流程从 $\mathcal{M}_n$ 中检索并回答问题。对问题集合 $\mathcal{Q}={q_1,\ldots,q_m}$,记标准答案为 ${y_1,\ldots,y_m}$,固定检索器为 $\phi$,固定生成器为 $g$,则第 $j$ 个预测答案是:
\[\hat{y}_j = g(q_j,\phi(\mathcal{M}_n,q_j))\]正确性奖励写成:
\[R_1 = \frac{1}{m} \sum_{j=1}^{m} \mathbb{I} \left[ \operatorname{metric}(\hat{y}_j,y_j) \right]\]这里的 $\operatorname{metric}$ 取决于数据集,可以是 exact match、F1 或其他任务指标。$R_1$ 是全局奖励,它评价的是最终记忆 $\mathcal{M}_n$ 是否足够支持问答。
第二项是工具调用格式奖励。因为 Mem-α 的动作是真实函数调用,格式错误会导致更新失败。对第 $t$ 步的第 $k$ 个调用,定义:
\[s(a_t^{(k)}) = \begin{cases} 1, & \text{if } a_t^{(k)} \text{ executes successfully} \\ 0, & \text{otherwise} \end{cases}\]则第 $t$ 步的格式奖励是:
\[R_{2,t} = \frac{1}{K_t} \sum_{k=1}^{K_t} s(a_t^{(k)})\]第三项是压缩奖励。记所有输入片段的总长度为 $L_C$,最终记忆的总长度为 $L_M$,则:
\[R_3 = 1-\frac{L_M}{L_C}\]这个奖励鼓励模型把长上下文压缩为更短的记忆。它本身只关心长度,所以需要和正确性奖励一起看;只追求压缩很容易丢信息。
第四项是内容有效性奖励。Mem-α 用一个外部 LLM judge 检查每个写操作在语义上是否合理。对每个调用定义:
\[v(a_t^{(k)}) = \begin{cases} 1, & \text{if } a_t^{(k)} \text{ is semantically valid} \\ 0, & \text{otherwise} \end{cases}\]于是第 $t$ 步的内容奖励是:
\[R_{4,t} = \frac{1}{K_t} \sum_{k=1}^{K_t} v(a_t^{(k)})\]把四项合起来,第 $t$ 步动作的总奖励是:
\[R_t^{\mathrm{write}} = R_1 + R_{2,t} + w_3R_3 + w_4R_{4,t}\]这里 $R_1$ 和 $R_3$ 是全局项,同一条样本里的所有步骤共享;$R_{2,t}$ 和 $R_{4,t}$ 是局部项,每一步根据当前函数调用质量单独计算。
优化上,Mem-α 使用 GRPO。对同一个写入输入 $q_t^{\mathrm{write}}$,旧策略采样 $G$ 个候选动作序列:
\[\left\{ o_{t,1}^{\mathrm{write}}, \ldots, o_{t,G}^{\mathrm{write}} \right\} \sim \pi_{\theta_{\mathrm{old}}} (\cdot\mid q_t^{\mathrm{write}})\]每个候选动作得到一个总奖励 $R_{t,i}^{\mathrm{write}}$,组内标准化后得到:
\[A_{t,i}^{\mathrm{write}} = \frac{ R_{t,i}^{\mathrm{write}} - \operatorname{mean}(R_{t,1}^{\mathrm{write}},\ldots,R_{t,G}^{\mathrm{write}}) }{ \operatorname{std}(R_{t,1}^{\mathrm{write}},\ldots,R_{t,G}^{\mathrm{write}})+\eta }\]如果把候选动作序列展开成 token,概率比值可以写成:
\[r_{t,i,j}^{\mathrm{write}}(\theta) = \frac{ \pi_\theta(o_{t,i,j}^{\mathrm{write}}\mid q_t^{\mathrm{write}},o_{t,i,<j}^{\mathrm{write}}) }{ \pi_{\theta_{\mathrm{old}}}(o_{t,i,j}^{\mathrm{write}}\mid q_t^{\mathrm{write}},o_{t,i,<j}^{\mathrm{write}}) }\]于是目标函数可以和前面的 GRPO 写成同一种形式:
\[J_{\mathrm{GRPO}}^{\mathrm{write}}(\theta) = \mathbb{E} \left[ \sum_{t=1}^{n} \frac{1}{G} \sum_{i=1}^{G} \frac{1}{|o_{t,i}^{\mathrm{write}}|} \sum_{j=1}^{|o_{t,i}^{\mathrm{write}}|} \min \left( r_{t,i,j}^{\mathrm{write}}(\theta)A_{t,i}^{\mathrm{write}}, \operatorname{clip} \left( r_{t,i,j}^{\mathrm{write}}(\theta), 1-\epsilon, 1+\epsilon \right) A_{t,i}^{\mathrm{write}} \right) \right]\]这里有一个和上一节公式不同的细节:Mem-α 论文里去掉了 KL 项,理由是鼓励策略探索。这样做会让训练更依赖奖励设计本身的约束力,所以它才需要格式奖励和内容有效性奖励来限制函数调用质量。
DeltaMem
Memory-R1 用下游 QA 正确性作为奖励,Mem-α 给工具调用和最终记忆分别设计奖励;DeltaMem 强调应该被评价的是一次操作之后形成的记忆状态,操作字符串本身只是一条通向状态变化的路径。
DeltaMem 把记忆库看成一组带 ID 的原子事实,每条记忆包含内容、时间戳和唯一 ID。用状态记号写,可以把第 $t$ 时刻的记忆库表示为 $\mathbf{S}_t$
给定一个新 session $d_{t+1}$,memory manager 读取当前状态 $\mathbf{S}_t$,输出一组更新操作:
\[q_t^{\mathrm{delta}} = (d_{t+1},\mathbf{S}_t)\] \[o_t^{\mathrm{delta}} = \left( a_t^{(1)},\ldots,a_t^{(K_t)} \right)\]这些操作经过状态转移函数 $T$ 后得到预测的新状态:
\[\mathbf{S}_{\mathrm{pred}} = T(\mathbf{S}_t,o_t^{\mathrm{delta}})\]训练数据同时提供目标状态 \(\mathbf{S}_{\mathrm{target}}\) 。这里最关键的问题是:如何比较 \(\mathbf{S}_{\mathrm{pred}}\) 和 \(\mathbf{S}_{\mathrm{target}}\) ?如果直接比较操作序列,会遇到一个麻烦:不同的操作路径可能得到相同或相近的最终记忆。例如一次 $\texttt{update}$ 和一次 $\texttt{delete}+\texttt{add}$ 在字符串层面差异很大,但最终状态可能表达了同一个事实。DeltaMem 因此转向状态级评价。
它先取两个状态的相对差集:
\[\Delta_{\mathrm{pred}} = \mathbf{S}_{\mathrm{pred}} \setminus \mathbf{S}_{\mathrm{target}}, \quad \Delta_{\mathrm{target}} = \mathbf{S}_{\mathrm{target}} \setminus \mathbf{S}_{\mathrm{pred}}\]$\Delta_{\mathrm{pred}}$ 可以理解为预测状态里多出来或写错的记忆,$\Delta_{\mathrm{target}}$ 可以理解为目标状态里缺失的记忆。如果只做严格字符串匹配,那么距离就是 \(|\Delta_{\mathrm{pred}} + \Delta_{\mathrm{target}}|\) 。但自然语言记忆经常存在不同表述,所以 DeltaMem 会先尝试在这两个集合之间做语义匹配。
1 2 pred: User moved to Boston in March. target: User relocated to Boston around March.严格集合差会把它们当成一个多余项加一个缺失项,也就是 delete + insert。但语义上更像 substitution,而且代价应该低一些。
设 $\Phi_{ij}$ 表示 $\Delta_{\mathrm{pred}}$ 中第 $i$ 条记忆和 $\Delta_{\mathrm{target}}$ 中第 $j$ 条记忆的语义相似度。DeltaMem 在所有一对一匹配 $\Gamma$ 中寻找总相似度最高的匹配,这里的 $\gamma^*$ 可以理解为“哪些预测记忆和目标记忆可以视为语义对应”:
\[\gamma^* = \mathop{\arg\max}_{\gamma\in\Gamma} \sum_{(i,j)\in\gamma} \Phi_{ij}\]这里的 $\Gamma$ 有额外约束。原文会先用相似度阈值 $\tau$ 过滤掉低相似度 pair,并且移除来自非预期 $\texttt{update}$ 的匹配,避免模型通过错误 update 路径拿到过高 reward。也就是说,$\gamma^*$ 只在通过这些约束的一对一匹配里求最优。
为了避免只靠 embedding 相似度带来的误匹配,DeltaMem 还加入了关键词覆盖。对目标记忆 $y_j$,设它的关键词集合为 $\mathcal{K}_j$;如果预测记忆 $x_i$ 和目标记忆 $y_j$ 被匹配,则局部事实覆盖分数为:
\[s_{ij} = \frac{ \sum_{k\in\mathcal{K}_j} \mathbb{I}(k\in x_i) }{ |\mathcal{K}_j|+\eta } \in [0,1]\]这个分数衡量的是:预测记忆虽然语义上接近目标记忆,但是否真的覆盖了目标记忆里的关键事实。$\eta$ 仍然是数值稳定项,避免分母为零。(这个做法更像 precision / recall 里的 soft true positive)
有了匹配和关键词覆盖后,DeltaMem 定义了一个 memory-based Levenshtein distance。直觉上,它把未被很好覆盖的预测记忆看作冗余,把未被覆盖的目标记忆看作缺失:
\[D^+ = |\Delta_{\mathrm{pred}}| - \sum_{(i,j)\in\gamma^*} s_{ij} ,\quad D^- = |\Delta_{\mathrm{target}}| - \sum_{(i,j)\in\gamma^*}s_{ij}\]经典 Levenshtein 统计 insert / delete / substitute 的最小编辑代价。$D^+$ 可以理解为“预测中多余项的软计数”。如果某条 pred 能很好匹配 target,$s_{ij}$ 接近 1,它就不再算真正多余;如果匹配很差,$s_{ij}$ 接近 0,它仍然算多余。
$D^+$ 越大,说明预测状态里无效或多余的内容越多;$D^-$ 越大,说明目标状态里应该出现的信息缺得越多。
- $D^+$ 类似 soft false positive
- $D^-$ 类似 soft false negative
- $\sum_{(i,j)\in\gamma^*}s_{ij}$ 类似 soft true positive
接着把这个匹配质量转成 soft precision 和 soft recall:
\[P_{\mathrm{soft}} = \frac{ TP_{\mathrm{soft}} }{ TP_{\mathrm{soft}} +FP_{\mathrm{soft}} } = \frac{ \sum_{(i,j)\in\gamma^*} s_{ij} }{ |\Delta_{\mathrm{pred}}|+\eta } ,\quad R_{\mathrm{soft}} = \frac{ TP_{\mathrm{soft}} }{ TP_{\mathrm{soft}} +FN_{\mathrm{soft}} } = \frac{ \sum_{(i,j)\in\gamma^*} s_{ij} }{ |\Delta_{\mathrm{target}}|+\eta }\]$P_{\mathrm{soft}}$ 惩罚多写和乱写,$R_{\mathrm{soft}}$ 惩罚漏写。DeltaMem 最后用 soft F1 作为状态转移奖励:
\[R_{\mathrm{state}} = 2\cdot \frac{ P_{\mathrm{soft}}\cdot R_{\mathrm{soft}} }{ P_{\mathrm{soft}}+R_{\mathrm{soft}}+\eta }\]这就是 DeltaMem 的核心 reward。它关心模型生成的操作把记忆库带到了什么状态。只要最终状态接近目标状态,就应该得到较高奖励;如果状态里有很多冗余或遗漏,就应该被惩罚。
除了状态转移奖励,DeltaMem 还加入两个辅助奖励。格式奖励 $R_{\mathrm{format}}$ 检查轨迹是否符合 ReAct 范式,检索奖励 $R_{\mathrm{retrieval}}$ 检查模型在 $\texttt{update}$ 和 $\texttt{add}$ 时是否召回了相关旧记忆,最后把三项奖励加权:
\[R^{\mathrm{delta}} = w_{\mathrm{format}}R_{\mathrm{format}} + w_{\mathrm{retrieval}}R_{\mathrm{retrieval}} + w_{\mathrm{state}}R_{\mathrm{state}}\]论文里使用的权重是 $w_{\mathrm{format}}=0.1, w_{\mathrm{retrieval}}=0.1, w_{\mathrm{state}}=0.8$,也就是说,主要训练信号来自状态转移质量,格式和检索只是辅助约束。
优化仍然可以接回前面的 GRPO。对同一个输入 $q_t^{\mathrm{delta}}$,旧策略采样 $G$ 条候选操作轨迹:
\[\left\{ o_{t,1}^{\mathrm{delta}}, \ldots, o_{t,G}^{\mathrm{delta}} \right\} \sim \pi_{\theta_{\mathrm{old}}} (\cdot\mid q_t^{\mathrm{delta}})\]每条轨迹得到一个总奖励 $R_{t,i}^{\mathrm{delta}}$,组内标准化为:
\[A_{t,i}^{\mathrm{delta}} = \frac{ R_{t,i}^{\mathrm{delta}} - \operatorname{mean}(R_{t,1}^{\mathrm{delta}},\ldots,R_{t,G}^{\mathrm{delta}}) }{ \operatorname{std}(R_{t,1}^{\mathrm{delta}},\ldots,R_{t,G}^{\mathrm{delta}})+\eta }\]把候选轨迹展开到 token 级,概率比值写成:
\[r_{t,i,j}^{\mathrm{delta}}(\theta) = \frac{ \pi_\theta(o_{t,i,j}^{\mathrm{delta}}\mid q_t^{\mathrm{delta}},o_{t,i,<j}^{\mathrm{delta}}) }{ \pi_{\theta_{\mathrm{old}}}(o_{t,i,j}^{\mathrm{delta}}\mid q_t^{\mathrm{delta}},o_{t,i,<j}^{\mathrm{delta}}) }\]DeltaMem 采用标准 GRPO,因此目标函数可以写成:
\[J_{\mathrm{GRPO}}^{\mathrm{delta}}(\theta) = \mathbb{E} \left[ \frac{1}{G} \sum_{i=1}^{G} \frac{1}{|o_{t,i}^{\mathrm{delta}}|} \sum_{j=1}^{|o_{t,i}^{\mathrm{delta}}|} \left( \min \left( r_{t,i,j}^{\mathrm{delta}}(\theta)A_{t,i}^{\mathrm{delta}}, \operatorname{clip} \left( r_{t,i,j}^{\mathrm{delta}}(\theta), 1-\epsilon, 1+\epsilon \right) A_{t,i}^{\mathrm{delta}} \right) - \beta D_{\mathrm{KL}} \left( \pi_\theta \parallel \pi_{\mathrm{ref}} \right) \right) \right]\]MemAgent
MemAgent 重在训练一个长上下文压缩器:模型顺序读入很长的文本,每读完一段,就把之前的固定长度 memory 覆盖成新的 memory。memory 本身是普通 token 序列,和结构化数据库记录的形态不同。
设长文本被切成 $K$ 个片段:
\[\mathcal{C} = \left\{ c^1,\ldots,c^K \right\}\]模型维护一个固定长度的 token memory:
\[\mathbf{m}^k\in\mathbb{V}^{M}\]其中 $M$ 是 memory token 数,$\mathbb{V}$ 是词表。第 $k$ 步读入片段 $c^k$ 和上一轮 memory $\mathbf{m}^{k-1}$,然后生成新的 memory:
\[q_k^{\mathrm{agent}} = (c^k,\mathbf{m}^{k-1})\] \[o_k^{\mathrm{agent}} = \mathbf{m}^{k} \sim \pi_\theta(\cdot\mid q_k^{\mathrm{agent}})\]这里的动作不采用 $\texttt{ADD}$ 或 $\texttt{UPDATE}$ 这类 CRUD 操作;模型直接重写整段 memory。因为 \(|\mathbf{m}^k|=M\) 始终固定,所以每一步只需要处理当前 chunk 和固定长度 memory,计算量随 chunk 数线性增长。
论文还从语言模型分解的角度解释这个设计。标准自回归模型会把完整序列写成:
\[p(\mathbf{x}_{1:N}) = \prod_{n=1}^{N} p(x_n\mid\mathbf{x}_{1:n-1})\]这意味着所有历史 token 都在条件里。MemAgent 用一串 latent memory $\mathbf{m}^{1:K-1}$ 替代无限增长的历史,可以写成:
\[p(\mathbf{x}_{1:N}) = \sum_{\mathbf{m}^{1:K-1}} \prod_{k=1}^{K} p(c^k\mid\mathbf{m}^{k-1}) p(\mathbf{m}^k\mid c^k,\mathbf{m}^{k-1})\]这个公式里,$p(c^k\mid\mathbf{m}^{k-1})$ 是读当前片段,$p(\mathbf{m}^k\mid c^k,\mathbf{m}^{k-1})$ 是写下一轮 memory。直觉上,模型每次只带着一个有限状态继续往前读。
奖励设计是 outcome-driven。处理完所有 chunk 后,模型用最终 memory 生成答案 $\hat{y}$,再由规则 verifier 计算奖励。对于多个标准答案彼此等价的任务,奖励写成:
\[R^{\mathrm{agent}} = \max_{y\in Y} \mathbb{I} \left[ \operatorname{is\_equiv}(y,\hat{y}) \right]\]其中 $Y={y_1,\ldots,y_m}$ 是可接受答案集合。如果任务要求输出所有答案,例如 multi-value needle-in-a-haystack,奖励改成覆盖率:
\[R^{\mathrm{agent}} = \frac{ \left| \{y\in Y:\; y\in\hat{y}\} \right| }{ |Y| }\]普通 GRPO 对一个输入采样 $G$ 个输出,然后用组内 reward 标准化得到优势。MemAgent 的 rollout 更复杂:同一个 rollout 样本会生成多段相互独立的 conversation,因为每个 chunk 的 memory overwrite 都对应一次上下文处理。记第 $i$ 个候选 rollout 中一共有 $n_i$ 段 conversation:
\[\left( o_{i,1}^{\mathrm{agent}}, \ldots, o_{i,n_i}^{\mathrm{agent}} \right)\]最终答案只出现在最后一段 conversation 中,因此 reward $R_i^{\mathrm{agent}}$ 也只从最终答案得到。MemAgent 的做法是把这个最终 reward 形成的优势分配给同一 rollout 里的所有 conversation。论文把这个算法称为 Multi-Conv DAPO。按照前文记号,可以写成:
\[A_i^{\mathrm{agent}} = R_i^{\mathrm{agent}} - \operatorname{mean} \left( R_1^{\mathrm{agent}},\ldots,R_G^{\mathrm{agent}} \right)\]和前面标准 GRPO 略有不同,论文这里跟随 DrGRPO,没有再除以 reward 标准差。对第 $i$ 个 rollout、第 $j$ 段 conversation、第 $t$ 个 token,优势统一为:
\[A_{i,j,t}^{\mathrm{agent}} = A_i^{\mathrm{agent}}\]令 $h_{i,j}$ 表示第 $i$ 个 rollout 中第 $j$ 段 conversation 的输入上下文,也就是当前 chunk、上一轮 memory 以及必要的任务提示。概率比值仍然是新旧策略在当前 token 上的概率比:
\[r_{i,j,t}^{\mathrm{agent}}(\theta) = \frac{ \pi_\theta(o_{i,j,t}^{\mathrm{agent}}\mid h_{i,j},o_{i,j,<t}^{\mathrm{agent}}) }{ \pi_{\theta_{\mathrm{old}}}(o_{i,j,t}^{\mathrm{agent}}\mid h_{i,j},o_{i,j,<t}^{\mathrm{agent}}) }\]于是 Multi-Conv DAPO 的目标可以写成:
\[J_{\mathrm{DAPO}}^{\mathrm{agent}}(\theta) = \mathbb{E} \left[ \frac{1}{ \sum_{i=1}^{G} \sum_{j=1}^{n_i} |o_{i,j}^{\mathrm{agent}}| } \sum_{i=1}^{G} \sum_{j=1}^{n_i} \sum_{t=1}^{|o_{i,j}^{\mathrm{agent}}|} \left( C_{i,j,t} - \beta D_{\mathrm{KL}} \left( \pi_\theta \parallel \pi_{\mathrm{ref}} \right) \right) \right]\]其中:
\[C_{i,j,t} = \min \left( r_{i,j,t}^{\mathrm{agent}}(\theta)A_{i,j,t}^{\mathrm{agent}}, \operatorname{clip} \left( r_{i,j,t}^{\mathrm{agent}}(\theta), 1-\epsilon_{\mathrm{low}}, 1+\epsilon_{\mathrm{high}} \right) A_{i,j,t}^{\mathrm{agent}} \right)\]Memory-R2
Memory-R2 处理的是多 session 训练里的 credit assignment。标准 GRPO 默认同一个 group 里的 rollout 可以直接比较,但在 memory agent 里,前面 session 写入、更新或删除的内容会变成后面 session 的环境状态。这样一来,不同 rollout 到第 $t$ 个 session 时继承的 memory 可能已经不同,直接比较完整轨迹 reward 会把很多责任混在一起。
论文把 memory construction 写成一个 chunk-wise 的过程。第 $t$ 个 session 被切成 $K$ 个 chunk,记为 $x_{t,1},\ldots,x_{t,K}$。每个 chunk 先经过 fact extractor,得到要进入记忆候选的信息 $z_{t,k}$;memory manager 再根据当前 memory state 选择操作 $a_{t,k}$,例如 $\texttt{INSERT}$、$\texttt{UPDATE}$ 或 $\texttt{DELETE}$。记忆库的更新可以写成一个确定性转移:
\[\mathcal{M}_{t,k} = \mathcal{T} \left( \mathcal{M}_{t,k-1}, z_{t,k}, a_{t,k} \right)\]也就是说,第 $k$ 个 chunk 处理完后,memory 从 \(\mathcal{M}_{t,k-1}\) 变成 \(\mathcal{M}_{t,k}\) 。整个 session 可以写成:
\[\mathcal{M}_{t,0} \xrightarrow[\pi_{\mathrm{ext}},\,\pi_{\mathrm{mgr}}]{x_{t,1}} \mathcal{M}_{t,1} \xrightarrow[\pi_{\mathrm{ext}},\,\pi_{\mathrm{mgr}}]{x_{t,2}} \cdots \xrightarrow[\pi_{\mathrm{ext}},\,\pi_{\mathrm{mgr}}]{x_{t,K}} \mathcal{M}_{t,K}\]沿着所有 session 展开,一条 memory-construction rollout 记为:
\[\tau = \{z_{t,k},a_{t,k}\}_{t=1,k=1}^{T,K}\]它的概率可以分解成 extractor 和 manager 两部分:
\[p_{\theta}(\tau\mid\mathcal{D}) = \prod_{t=1}^{T} \prod_{k=1}^{K} \pi_{\mathrm{ext}} \left( z_{t,k}\mid x_{t,k} \right) \pi_{\mathrm{mgr}} \left( a_{t,k}\mid z_{t,k},\mathcal{M}_{t,k-1} \right)\]Memory-R2 的一个设计点是 extractor 和 manager 共享同一个 backbone,只用不同 role prompt 区分角色:
\[\pi_{\mathrm{ext}}(\cdot) = \pi_{\theta}(\cdot\mid p_{\mathrm{ext}},\cdot), \qquad \pi_{\mathrm{mgr}}(\cdot) = \pi_{\theta}(\cdot\mid p_{\mathrm{mgr}},\cdot)\]这里 $\theta$ 是共享参数,$p_{\mathrm{ext}}$ 和 $p_{\mathrm{mgr}}$ 是两个角色提示。好处是 extractor 和 manager 可以一起被训练,问题是:两个角色输出长度可能差很多。如果继续按 token 平均损失,输出更长的角色会天然占更大权重。Memory-R2 因此把一次 extractor 或 manager 调用视为一个 generation step。
设第 $u$ 个 generation step 生成的 token 下标集合为 $\mathcal{U}_u$。它先把 token-level 的概率比值聚合成 step-level ratio:
\[\rho_u = \exp \left( \frac{1}{|\mathcal{U}_u|} \sum_{\ell\in\mathcal{U}_u} \log \frac{ \pi_{\theta}(y_\ell\mid h_\ell) }{ \pi_{\theta_{\mathrm{old}}}(y_\ell\mid h_\ell) } \right)\]同时把 token-level advantage 聚合成 step-level advantage:
\[\bar{A}_u = \frac{1}{|\mathcal{U}_u|} \sum_{\ell\in\mathcal{U}_u} A_\ell\]其中 $y_\ell$ 是第 $\ell$ 个生成 token,$h_\ell$ 是它的自回归上下文。这个平均处理的含义很直接:不管某次 extractor 输出 20 个 token,还是某次 manager 输出 200 个 token,它们都先被聚合到一个 step,再进入后面的 LoGo-GRPO。
接下来是 Memory-R2 的核心:LoGo-GRPO。它把 reward 分成 global branch 和 local branch。先定义 session-level reward。设 $\mathcal{Q}_t$ 是证据属于 session $t$ 的 QA 集合,模型基于 memory bank $\mathcal{M}$ 回答这些问题,QA 质量用 token-level F1 平均:
\[\mathrm{QA}(\mathcal{M},\mathcal{Q}_t) = \frac{1}{|\mathcal{Q}_t|} \sum_{(q,a^*)\in\mathcal{Q}_t} \mathrm{F1}(\hat{a},a^*)\]为了避免 memory 无限膨胀,论文还加入 compression penalty。设 $\mathrm{Tok}(\cdot)$ 表示 token 数,$\alpha$ 是允许 memory 占累计 session token 的比例,则:
\[\mathrm{Comp}(\mathcal{M},t) = \begin{cases} 0, & \mathrm{Tok}(\mathcal{M}) \le \alpha\sum_{s=1}^{t}\mathrm{Tok}(S_s), \\[4pt] \dfrac{ \mathrm{Tok}(\mathcal{M}) - \alpha\sum_{s=1}^{t}\mathrm{Tok}(S_s) }{ \sum_{s=1}^{t}\mathrm{Tok}(S_s) }, & \mathrm{Tok}(\mathcal{M}) > \alpha\sum_{s=1}^{t}\mathrm{Tok}(S_s). \end{cases}\]最后 session-level reward 是:
\[R(\mathcal{M},\mathcal{Q}_t,t) = \mathrm{QA}(\mathcal{M},\mathcal{Q}_t) - \lambda_{\mathrm{comp}} \mathrm{Comp}(\mathcal{M},t)\]global branch 仍然保留长程目标。对第 $i$ 条完整 rollout,记它在所有 $T$ 个 session 结束后的 memory 为 $\mathcal{M}_{T}^{(i)}$。论文把 terminal memory 拿来回答证据属于 session $t$ 的问题:
\[r_{t,i}^{\mathrm{G}} = R \left( \mathcal{M}_{T}^{(i)}, \mathcal{Q}_t, T \right)\]然后像 GRPO 一样,在 $n$ 条 global rollout 内做组内标准化:
\[\hat{A}_{t,i}^{\mathrm{G}} = \frac{ r_{t,i}^{\mathrm{G}}-\mu_t^{\mathrm{G}} }{ \sigma_t^{\mathrm{G}}+\varepsilon }, \qquad \mu_t^{\mathrm{G}} = \frac{1}{n} \sum_{j=1}^{n} r_{t,j}^{\mathrm{G}}, \qquad \sigma_t^{\mathrm{G}} = \operatorname{std}_{j} \left( r_{t,j}^{\mathrm{G}} \right)\]这个 global reward 能保留“前面写的 memory 对后面有没有用”的长程信号,但它仍然存在比较不公平的问题。于是 local branch 会抽一些 session,从相同的中间 memory state 重新 rollout。
具体来说,每个 session 以概率 $p_{\mathrm{local}}$ 被选中:
\[b_t\sim\operatorname{Bernoulli}(p_{\mathrm{local}}), \qquad \mathcal{B} = \{t\mid b_t=1\}\]对每个被选中的 session $t$,先选一条 anchor rollout $i_0$,取它在 session $t$ 之前的 memory state \(\mathcal{M}_{t-1}^{(i_0)}\) 。然后只从这个相同起点出发,对 session $t$ 做 $m$ 次 local rerollout。第 $j$ 次 rerollout 结束后的 memory 记为 \(\mathcal{M}_{t}^{(i_0,j)}\) ,local reward 是:
\[r_{t,j}^{\mathrm{L}} = R \left( \mathcal{M}_{t}^{(i_0,j)}, \mathcal{Q}_t, t \right), \qquad j=1,\ldots,m\]local advantage 也只在这 $m$ 条从同一个 anchor state 出发的 rerollout 内标准化:
\[\hat{A}_{t,j}^{\mathrm{L}} = \frac{ r_{t,j}^{\mathrm{L}}-\mu_t^{\mathrm{L}} }{ \sigma_t^{\mathrm{L}}+\varepsilon }, \qquad \mu_t^{\mathrm{L}} = \frac{1}{m} \sum_{j=1}^{m} r_{t,j}^{\mathrm{L}}, \qquad \sigma_t^{\mathrm{L}} = \operatorname{std}_{j} \left( r_{t,j}^{\mathrm{L}} \right)\]这就是 LoGo-GRPO 里 “local” 的含义:比较对象共享同一个 $\mathcal{M}_{t-1}^{(i_0)}$,所以 reward 差异更接近来自当前 session 的 extractor / manager 行为,受更早 memory 污染的影响更小。
最后的训练目标把 global rollout 和 local rerollout 里的 generation step 放在一起。论文这里写成 actor loss,因此是要最小化的 $\mathcal{L}(\theta)$。对每个 step $u$,使用前面定义的 $\rho_u$ 和 $\bar{A}_u$,先定义 dual-clipped surrogate:
\[\ell_u = \begin{cases} \min \left( -c\bar{A}_u,\, \max \left( -\rho_u\bar{A}_u,\, -\operatorname{clip}(\rho_u,1-\epsilon,1+\epsilon)\bar{A}_u \right) \right), & \bar{A}_u<0, \\[4pt] \max \left( -\rho_u\bar{A}_u,\, -\operatorname{clip}(\rho_u,1-\epsilon,1+\epsilon)\bar{A}_u \right), & \bar{A}_u\ge 0. \end{cases}\]其中 $c>1$ 是 dual-clipping 常数。直觉上,positive advantage 的 step 会被鼓励,negative advantage 的 step 会被压低;dual clipping 额外限制负优势样本的影响,避免低 reward 样本把更新方向拉得过猛。
把所有 valid generation step 记为 $\mathcal{K}_{\mathrm{step}}$,最终 loss 是:
\[\mathcal{L}(\theta) = \frac{1}{|\mathcal{K}_{\mathrm{step}}|} \sum_{u\in\mathcal{K}_{\mathrm{step}}} \ell_u - \beta_{\mathrm{ent}} \overline{H}_{\mathrm{token}} + \beta_{\mathrm{kl}} \overline{D}_{\mathrm{KL,token}}\]\(\overline{H}_{\mathrm{token}}\) 是平均 token entropy,鼓励探索; \(\overline{D}_{\mathrm{KL,token}}\) 是平均 token-level KL,用来约束当前策略和参考策略的距离。
总结
- Memory-R1:奠定了用 GRPO/PPO 优化记忆写入与记忆利用的基本范式。
- Mem-α:细化奖励,用 QA 正确性、格式、压缩和内容质量共同训练。
- DeltaMem:奖励转向“操作后的 memory state 是否接近目标状态”,用 soft state-level F1 评价。
- MemAgent:把长上下文处理转成固定长度 token memory 的反复 overwrite,并用最终答案 reward 通过 Multi-Conv DAPO 训练中间 memory 压缩行为。
- Memory-R2:针对多 session 记忆训练更公平地归因每个 session 的记忆操作。
Reference
- Memory-R1: Enhancing Large Language Model Agents to Manage and Utilize Memories via Reinforcement Learning.
- Mem-α: Learning Memory Construction via Reinforcement Learning.
- DeltaMem: Towards Agentic Memory Management via Reinforcement Learning.
- MemAgent: Reshaping Long-Context LLM with Multi-Conv RL-based Memory Agent.
- Memory-R2: Fair Credit Assignment for Long-Horizon Memory-Augmented LLM Agents.