0%

Agent Memory Survey

围绕 agent memory,做一些笔记和调研。

本博客分为 2 个部分。

我首先准备参考 Memory in the Age of AI Agents | alphaXiv,对 memory 的分类和发展进行总结和梳理。

然后,我想参考综述中的分类与解析,围绕 CC 的源码做一些对应关系的笔记。

【更新】第三部分:自己总结的一篇小综述

一、回顾综述

Memory in the Age of AI Agents 这篇综述对 memory 的发展历史进行了完整的分类。作者的框架缩写为“FFD”,memory 的形式(Form)、memory 的功能(Function)、memory 的动态(Dynamics)。

定义 memory

RAG、KV cache、context engineering 等名词概念很热门,但概念容易混淆。他们是 memory 的分类还是方法论?都不是。

Agent memory 是 agent 在环境中观察、行动时,检索、写入、更新记忆,使得记忆影响决策的机制。

KV cache、RWKV、Mamba 等对于 LLM 内部架构进行优化,是 LLM memory,在上下文序列长度增长时保持信息,处理的任务与 agent 任务关联度较少。

在 context engineering 中,人们通过 RL 让模型增强调用工具能力。MCP 这种协议让接工具这种具体任务翻译为 LLM 理解的上下文,并把 LLM 的输出翻译为工具的操作,同理,A2A 让 agent 找 agent,ANP 让 agent 上网互联,Agora 让很多 agent 高效沟通。

RAG 关注如何检索外部知识库。Agent memory 更强调 agent 在与环境交互中维护一个持续演化的记忆库。两者工程上可能重叠,也可能没有。Claude Code 就没有使用 RAG 进行记忆的搭建。

image-20260413190017148

Form:记忆的存储形式

Token 级记忆把 token 存起来,比如文本片段、对话记录。有 1D 的日志列表,有 2D 的图、树等单层结构,也有 3D 的多层图结构。

Parametric Memory 参数记忆分为内部和外部。内部参数记忆直接改 base model 的参数。外部参数记忆挂在 adapter、LoRA 上。

Latent Memory 潜在记忆以隐藏状态、latent token、KV-cache、连续向量表示记忆。

Function:为什么要记忆

事实记忆就是 agent 知道什么。有:用户事实记忆(身份等)、环境事实记忆(文件状态等)。经验记忆就是 agent 反思。例如把经验变为 skill。工作记忆就是 agent 当前的工作。单轮工作记忆关注如何把当前这一次输入压缩、重组、结构化,让 LLM 在有限窗口里高效推理。多轮工作记忆关注长时间交互里,怎么维护任务状态。

Dynamics

记忆形成考虑原始交互怎么变成记忆。记忆演化考虑记忆的整理、更新、遗忘。记忆检索考虑什么时候查记忆,如何查。

围绕综述,一些想法

综述中比较看重 RL。RL 能让模型理解其所在的环境、如何实行最佳的 memory 行为范式。

我联想到这篇博客 《AI Agent 之我见 | Zoee》 中的:

读源码的时候一直有个感觉:这些 Agent 的设计跟它们用的模型深度绑定。查了一些资料,发现这已经是行业里在讨论的话题了。

OpenAI 公开说过 codex-1 是 o3 “用强化学习在真实编码任务上训练” 出来的。GPT-5.2-Codex 进一步优化了 “long-horizon work through context compaction”——这说明模型训练时就在考虑 compact 场景。Anthropic 那边,Claude 是在 Claude Code harness 的循环里做的 post-training。

…………

他们发现 Opus 4.6 上来之后,直接把 sprint 分解模块删了——模型自己能做了。还发现模型在接近上下文极限时会 “context anxiety”——提前收尾、降低输出质量。他们的解法是做完整的上下文重置,不做 compact。

这就是 agent 在环境中的进化。因此,在设计 harness 时,需要考虑 agent 未来的能力。这就是最近 Anthropic 的 《Scaling Managed Agents: Decoupling the brain from the hands \ Anthropic》 中的meta harness 想法,其为未来更强的模型留下了能容纳未来的 harness 的平台。

Claude Code 是一种很优秀的 harness。但随着基座模型进步,里面的某些约束可能会被模型内化。Harness 也要随之改进。

二、Claude Code 的设计对应论文中的概念

Form

论文中提出的 Form,对于本地 Claude Code 主要是 Token-level Memory,Flat,1D。持久记忆全部存成 .md 文本文件。每个 .md 是一个语义 chunk,没有图结构。不过 MEMORY.md 里面是索引指针,因此也可以视为轻量的 2D 结构。

而对于发给 anthropic 的请求优化,属于 Latent Memory。Claude Code 的很多上下文设计中都在尽量利用 KV Cache,比如 runForkedAgent() 共享父进程的 prompt cache 前缀。

Function

论文中分为事实记忆、经验记忆、工作记忆。

事实记忆对应 Claude Code 的 4 种记忆类型:user feedback project reference。在 memoryTypes.ts 对每种类型有 “when to save” 指引。

经验记忆中,case-based 对应 extractMemories.ts 的子 agent 读取完整对话 transcript 并抽取记忆。

不过这个的 feature flag feature('EXTRACT_MEMORIES') 没开,Bun 没编译它,普通用户用不了。CC 也没有做经验记忆对应的 strategy-based 或 skill-based,不会自动把多个 case 抽象成通用规则或可执行脚本,除非用户显式要求。

总之基本没有经验记忆开启。

工作记忆对应 CC 的上下文窗口与动态注入机制,例如 compact 机制、任务系统 TaskCreate/Get/Update/List 等。

Dynamics

对于记忆形成,如果当前情况符合 “when to save”,CC 就用读写工具建立记忆 .md 文件。这是由 prompt 驱动的,LLM 自己选择做不做,不是自动流程。

对于记忆演化,CC 靠基座模型自己察觉并用读写工具修改。索引 MEMORY.md 也是靠模型自己维护一致性。CC 没有遗忘机制,上限为积累 200 个文件。

如图,基本靠 prompt 让模型自己决定什么时候维护。

image-20260413233516555

对于记忆检索,CC 无 RAG 无向量。CC 用 src\memdir\findRelevantMemories.tsfindRelevantMemories 函数检索。调用了 findRelevantMemories 之后,会准备调用 Sonnet 模型进行相关记忆挑选。先扫描记忆文件,去掉 alreadySurfaced 的文件,只保留新候选,把用户当前信息和所有记忆文件的 frontmatter 列表发给 Sonnet。让 LLM 强制输出 json_schema。校验防止模型返回无效值然后返回结果。

一言以蔽之,CC 用 LLM 检索。检索的依据是,各个 .md 记忆文件的 frontmatter。

我的想法

CC 的 harness 非常依赖基座的智慧。没有自动的机制,时机靠模型主动去进行执行。

这说明,模型在 harness 中进行了充分的 SFT、RL,使得不会在环境中做出不恰当的事。例如,如果让 CC 调用其他 LLM,其他 LLM 可能会对这些关于 memory 的 prompt 过度敏感或过分忽视,以至于这些 LLM 可能每次都更新很多 memory 或完全不在乎 memory。

总结

事实上,以上只提到了 CC 的 3 个 memory 机制:Auto Memory、逐轮注入、CLAUDE.md 加载。

CC 还有其他 memory 机制,但是没有启用,有些是 GrowthBook 默认关闭,有些是编译期 gate。这些我就不记录了。


三、Agent Memory Survey

Reference

  1. Memory in the Age of AI Agents | alphaXiv
  2. CC 源码