Files
2026-07-10 18:01:44 +08:00

12 KiB
Raw Permalink Blame History

压缩讲义:Agent 怎样从历史中学习

1. Memory 不是仓库,而是受限状态

最朴素的 Agent memory 是保存聊天记录,然后按相似度找回来。这个模型隐含了两个假设:过去可以被完整保存;只要找到相关文本,模型就能做出更好的动作。最近一年的工作反复证明,这两个假设都不够。

更有用的形式化来自 POMDP:Agent 看不到完整世界状态,只能用历史构造一个内部状态。设历史为 h、当前问题为 q、memory 编码器为 g,实际决策只能依赖:

m = g(h, q)
a = policy(m, q)

因此 memory 的目标不是重建全部过去,而是让 m 成为当前决策的充分状态。这个视角立刻解释了三个现象:

  • 两段语义相似的历史,可能要求完全不同的行动,因此不能合并。
  • 两段描述完全不同的历史,如果对当前问题导向同一个最优行动,可以安全压缩。
  • memory 质量最终要用决策损失衡量,不能只用召回率或摘要相似度衡量。

DeMem 把这个直觉写成 decision rate-distortion。对历史 h 采取动作 a 的损失是:

Delta_q(h, a) = best_value(h, q) - value(h, q, a)

如果一组历史存在一个共同动作,使每段历史的损失都不超过容忍值 epsilon,它们才可以共享一个 memory state。这给出了一个非常实用的遗忘原则:

可以忘记描述差异,但不能忘记会改变决策的差异。

2. 为什么长上下文不是答案,但必须作为 baseline

长上下文保留原始信息,避免了过早摘要和 schema 丢失,所以它经常比复杂 memory 系统更强。EvoMemBench 在统一协议下比较 15 种方法,得到三个重要结果:

  1. 长上下文 baseline 仍然很有竞争力。
  2. memory 在当前上下文不足、任务更难时才更稳定地产生价值。
  3. 没有一种 memory 形态能同时支配所有任务。

这不意味着只要扩大窗口即可。上下文越长,推理成本和延迟越高,干扰也越严重;而跨 session 的持久状态、可删除性、来源治理和经验学习也不是上下文窗口本身能解决的。

正确结论是:长上下文是 memory 实验必须击败的控制组,而不是必须淘汰的旧方案。

3. 相似度为什么经常失效

向量检索回答的是“什么文本看起来像当前问题”,Agent 真正需要的却可能是:

  • 哪个动作导致了当前状态?
  • 哪条约束仍然有效?
  • 上次失败发生在哪个分支?
  • 哪段经验对未来成功有长期贡献?

这些关系分别是因果、时间、控制流和价值关系,不能被单一语义距离稳定表达。

AutoMEM 的诊断研究 给出了两个具体失效层:

  • 表示失败:索引 schema 根本没有保存 step id、动作或未来问题需要的谓词,之后再强的检索器也找不回来。
  • 检索失败:原始存储里仍有答案,但一次被动路由没有把细节交给回答模型,也没有第二次补证据的机会。

它还给出了“什么时候索引值得做”的两个条件:schema 必须能表达问题所需关系;大量问题必须确实需要跨记录聚合。否则,保留原始文本并让 Agent 用 grep/read 主动查找,可能更通用。

所以结构化不是越多越好。结构化是在写入时对未来问题下注,而主动检索是在查询时再决定需要什么结构。

4. 四类 memory,解决四类失败

4.1 事实与主题文档

适合用户偏好、人物关系、项目事实和跨 session 知识更新。关键不是把每句话切成孤立向量,而是把相关证据维护成可以修订的主题单元。

Infini Memory 使用 topic documents:新观察先进入缓冲区,再周期性巩固到主题文档;读取时由 Agent 迭代搜索、查看局部行和补充证据。在 MemoryAgentBench 上,其 agentic variant 报告 64.7% overall;维护结构固定时,agentic retrieval 相比 summary+BM25 增加 3.3 点,而移除 split/merge 使 LongMemEval 减少 6.7 点。

这里的启发不是“文件一定胜过数据库”,而是 memory 需要可维护的语义单元、原始证据链接和多步检查能力。

4.2 当前执行状态

长程工具任务的主要问题常常不是忘记一个事实,而是丢失当前控制状态:已经完成哪些子目标、哪些路径失败、哪些动作改变了后续约束。

MAGE 用两层树表示执行状态:底层保存 action-observation,顶层在子目标边界压缩;当前状态来自 root-to-current path。四个操作形成闭环:

  • Grow:追加新的动作与观察。
  • Compress:在边界把完成片段压缩为子目标状态。
  • Maintain:在摘要成为可信状态前检查遗漏和执行错误。
  • Revise:回到错误边界,从新分支继续,隔离错误轨迹。

这个结构解决的是控制流连续性,而不是文本相似性。论文在 MemoryArena 报告相对 baseline 平均提高 7.8 到 20.4 个百分点,同时比长上下文减少 55.1% token。

4.3 稳定规则与技能

如果同一种错误反复发生,把旧案例再次塞进上下文可能不如直接改变 Agent 的行为规则。

Compiled Memory 的 Atlas 把经过验证的经验写成 system prompt 中的子规则:memory 是 distillation,读取是 instruction rewriting。其 CUAD 实验报告 token F1 增加 8.7 个百分点,HotpotQA joint F1 增加 3.16 个百分点;同一份从 GPT-4o 错误编译的 prompt 在 Claude Sonnet 4.5 上仍增加 2.31 个百分点。

但这个结果有重要限制:演化 prompt 从约 960 增至 1570 token,论文没有完成等长度通用内容控制;而训练信号没有覆盖的目标不会自然改善。这说明程序记忆适合稳定、重复、可验证的任务规则,不适合不断变化的事实。

4.4 有价值的经验链

一次成功可能依赖更早的记忆,而那条记忆又帮助生成了后续记忆。只奖励最后一次被直接检索的记录,会错误分配信用。

MemQ 记录 memory provenance DAG,并把 TD error 沿祖先链反向传播:

delta(m) = reward + gamma * Q(new_memory) - Q(m)
credit(ancestor) += alpha * (gamma * lambda)^depth * delta(m)

它在多步任务上的提升大于单步任务,说明“结构距离”可以比单纯时间距离更适合经验归因。不过它假设 memory 单调增长,尚未解决巩固和删除,维护 DAG 也会持续增加成本。

5. 写入比读取更危险

检索错了一次通常影响一个回答;持久 memory 写错一次,可能在未来反复被召回,成为系统状态污染。

TrustMem 把 memory update 视为可审计 transition,动作空间是 WRITE / REVISE / PRUNE。verifier 从三个维度检查每次更新:

  • coverage:新输入中的重要信息是否保留。
  • preservation:原有有效信息是否被无依据删除或扭曲。
  • faithfulness:新写内容是否有当前输入或旧状态支持。

这比只看最终问答正确率更合理,因为正确答案也可能掩盖中间产生的危险状态。论文报告,相比各错误类型的最强 baseline,遗漏、破坏和幻觉分别减少 40.1%、79.1% 和 50.0%。

但“内容真实”仍不等于“有权支持行动”。外部网页中的恶意指令即使被准确保存,也不应在未来授权转账。MemLineage 因此把来源签名、派生 DAG 和敏感动作 gate 结合起来:一条行动理由如果沿派生链来自不可信源,就不能直接执行。

它的确定性机制隔离实验中,三类攻击的 ASR 均降为零,但这个结果来自自定义 cross-session harnessheadline 评估没有覆盖完整自适应攻击,且作者明确假设模型权重和推理路径可信。它支持“来源链必须进入执行策略”这个方向,但不能被读成 memory 安全已解决。

6. Memory controller 才是核心能力

写入什么、怎样组织、什么时候读取、如何补证据和何时遗忘,本质上都是控制策略。当前出现了三种控制方式:

控制方式 优点 代价
固定规则 可预测、可调试、成本低 难适应任务与状态变化
LLM 工具调用 灵活,可按问题主动查找 多轮调用昂贵,受模型能力影响
训练控制器 能从结果优化策略 训练和 credit assignment 复杂,容易过拟合 benchmark

HORMA 提供了一个值得保留的分工:高能力模型负责异步 memory organization,轻量模型学习低延迟 retrieval。论文中,Qwen 3.5 4B retriever 仅在 LoCoMo 训练,却能迁移到 ALFWorld 和 LongMemEval;但弱模型如果一开始就把 memory 组织坏了,更强的 retriever 也补不回来。

这正好说明我们自己的模型分工原则:小模型适合局部、可验证、低风险操作;跨论文压缩、结构设计和关键判断需要强模型或人工研究编辑承担。

7. 怎样证明 memory 值得存在

Memory 论文最容易犯的错误,是只比较成功率,不计算 memory 模块自己消耗的 token、延迟和额外调用。

在线 memory/skill 的预算研究 把相同预算交给 vanilla actor 增加观察和行动步数。在 WebArena 的三个域、三个模型上,budget-matched vanilla baseline 的平均成功率都高于三个在线 augmentation 方法,并且通常 token 更少;在 WorkArena-L1 上也保持竞争力。

这项结果不能推广到所有 memory:它研究的是在线模块,离线编译后被大量复用的技能需要另一种摊销方式。但它给出了必须遵守的评测卫生:

  1. 报告所有模块的 token 和延迟,不只报告主 Agent。
  2. 与长上下文和 budget-matched vanilla actor 比较。
  3. 多次运行并报告方差。
  4. 分开评估写入、组织、读取、回答和动作执行的错误。
  5. 测试更新、冲突、遗忘、污染和跨任务泛化,不只测静态 recall。

8. 综合结论:一个可工作的参考架构

对需要长期运行、可学习、可审计的 Agent,可以从下面的最小架构开始:

flowchart TB
    E["Immutable event log"] --> V["Transition verifier"]
    V --> B["Current buffer"]
    B --> T["Topic documents"]
    B --> X["Execution-state tree"]
    T --> K["Compiled rules / skills"]
    X --> K
    Q["Current task"] --> C["Memory controller"]
    T --> C
    X --> C
    K --> C
    C --> D["Minimal sufficient context"]
    D --> A["Agent action"]
    A --> O["Outcome and feedback"]
    O --> L["Credit and consolidation"]
    L --> V
    P["Provenance / time / principal / policy"] --> V
    P --> C
    P --> A

这不是要求第一天实现全部层。它给出的是责任边界:

  • 原始日志负责可恢复和审计。
  • topic documents 负责可维护事实。
  • execution tree 负责长任务状态。
  • compiled rules 负责稳定行为改变。
  • controller 负责按任务选择最小充分上下文。
  • verifier 与 provenance 负责阻止错误和不可信状态永久化。
  • outcome loop 负责让 memory 从使用结果中学习。

最终设计原则可以压成一句话:

先判断未来决策需要保留什么区别,再选择存储结构;先用公平 baseline 证明价值,再让 memory 获得长期权限。