Agent Memory:从消息历史到可治理的长期记忆
设想一个很普通的对话:用户上周说“咖啡”,这周又明确改成“茶”。下次它让 Agent 点饮料时,系统到底该带回哪一个值?
把两句话都塞进向量库,检索命中哪句并不可靠;只保留最新一句,又要能说明它来自哪里、什么时候改过。用户再要求删除时,索引、缓存和摘要里是否还有残留,才是更麻烦的部分。
所以,给 Agent 接一个向量数据库,不等于它已经有了可用的长期记忆。真正要设计的是写入资格、版本、读取条件和删除路径。
先记住这句话: Memory 的重点不是“存得多”,而是“这条信息为什么能在此刻被这个 Agent 使用”。
这一篇会先把四类数据拆开,再用本地实验复现“偏好更新后旧值不能继续出现”的最小闭环。
先把四种数据分开,别急着建向量库
Section titled “先把四种数据分开,别急着建向量库”先问一句:眼前这条信息是为了完成当前任务,还是要跨会话保留?答案不同,存放位置和治理方式也不同。
Message History 是对话历史记录用户和助手说过什么。它适合保持短期语境,不适合承担所有业务事实。历史会不断增长,也包含重复、试探、被纠正的信息。
Working State 是当前任务的结构化状态:目标、步骤、工具结果、待审批事项、预算和终态。它回答“这次任务进行到哪里”,通常应该有明确 Schema 和版本。
External Knowledge 是政策、文档、数据库和知识库。它们属于外部事实,通过 RAG 或工具读取,不一定要复制成 Agent 私有记忆。
Long-term Memory 是跨会话仍有价值的信息,例如用户偏好、已确认事实、过去经历和稳定工作方法。
四者的保留时间、权限和更新方式都不同。把它们统统存入一个向量库,后续很难治理。
Memory 的几种经典类型
Section titled “Memory 的几种经典类型”很多 Agent Memory 设计借用认知科学的分类。Semantic Memory 保存相对稳定的事实和概念,例如“用户偏好中文回复”“该项目使用 Python 3.9”。Episodic Memory 保存过去发生过的事件、尝试和结果,例如“上次部署因为数据库迁移失败,回滚到 v1.8”。Procedural Memory 保存怎样完成任务的规则和方法,例如检查清单、写作模板、工具使用说明。
现实系统还需要短期工作记忆,用于当前计划和中间结果。不同类型不一定使用不同数据库,但应有不同写入与检索策略。
Memory 的完整生命周期
Section titled “Memory 的完整生命周期”记忆从观察开始:从对话、工具和环境中产生候选信息。然后要判断它是否值得跨会话保存–临时情绪、未经确认的猜测和敏感信息不应默认进入长期记忆。
接下来是 Normalize:把自然语言转换为带主体、键、值、来源、时间和置信度的记录。新信息与旧信息冲突时,是覆盖、保留多个版本,还是等待确认?这个选择很关键。
Retrieve 是根据当前目标、用户和权限读取相关记忆。把记忆放入上下文时标明来源和时效,避免把低置信记录当成系统事实。
最后是 Correct and Delete:用户能够查看、纠正和删除;系统还要处理缓存、索引和下游副本。
最近的 Memory 综述也越来越多地按 write-manage-read 而非单一检索算法组织问题。[1]
看项目时,先看它替你管理哪一段生命周期
Section titled “看项目时,先看它替你管理哪一段生命周期”同样叫 Memory 的项目,处理的问题并不相同。有的专注从对话提炼记录,有的把 Agent 状态长期保存,有的重点维护时间变化的实体关系。先看它负责生命周期的哪一段,再谈是否适合自己的系统。
Generative Agents 用观察、反思和规划构建可持续行为:事件进入记忆流,系统按相关性、近期性和重要性检索,再生成更高层反思。[2]
MemGPT 则把有限上下文类比成操作系统内存,区分核心上下文和外部存储,让 Agent 主动在层级之间移动信息。[3]
这两条路线共同改变了一个认识:Memory 不是对话历史的附属功能,而是 Agent 架构中的主动管理模块。
后来 Letta 将 MemGPT 思想发展为有状态 Agent 平台,强调 Agent 身份、核心 Memory 和长期运行。[4]
几个热门项目分别在做什么
Section titled “几个热门项目分别在做什么”Mem0 是独立 Memory Layer:从交互中提取候选记忆,对已有记录执行新增、更新或删除,再按查询返回相关内容。它适合把 Memory 作为多个 Agent 或应用共享的服务。[5]

图 1:Mem0 代表独立通用 Memory Layer。Star 反映关注度,不代表记忆准确性已经解决。来源见文末。
看图时关注它把“提取、更新、检索”放在同一层服务里。这个边界适合共享,但不替应用决定哪些信息本来就不该写入。
Letta 是有状态 Agent:把核心状态与外部记忆放在 Agent 生命周期中心,适合长时间保持身份和任务连续性。这里的重点不是“多记一点”,而是让 Agent 的身份和可编辑状态有明确归属。

图 2:Letta 将“有状态 Agent”作为平台中心,页面快照核对于 2026-07-20。来源见文末。
它提醒我们:对某些应用,Memory 不只是检索结果,而是 Agent 自身状态的一部分。
LangMem 区分两种写入方式:交互中立即更新的 hot path,以及后台异步提取、合并和巩固。[6] 这种设计降低前台延迟,但引入后台一致性和延迟可见问题。
Graphiti 关注实体关系和事实随时间变化,适合客户、组织、设备等关系密集领域。[7] 图能表达“谁与谁有什么关系、这条关系何时有效”,代价是实体消歧和图数据库运维更复杂。

图 3:Graphiti 的项目定位是为 Agent 构建实时知识图谱。来源见文末。
Supermemory 将连接器、内容处理、Memory API 和上下文生成放进一个服务,强调跨来源和本地/云部署。[8] 它更接近 Context Infrastructure,不只是一张记忆表。
这些项目不是单一榜单里的替代品。它们选择的重点分别是记忆服务、有状态 Agent、后台巩固、时序关系和上下文引擎。
写入时要比检索更保守
Section titled “写入时要比检索更保守”RAG 检索错一次,最多让一次回答跑偏。长期记忆写错一次,可能在很多次会话里反复把错误当成事实。
这就是为什么写入前要比“相似度够不够高”多问几层。常见污染来源包括:模型把推测写成事实、用户临时选择被解释成长期偏好、攻击者诱导 Agent 保存恶意指令、旧事实覆盖新事实、两个租户的记录发生串扰、后台摘要丢失否定和条件。
因此,写入策略应比读取策略更保守。高风险记忆可以采用这些措施:只保存用户明确确认的信息、保留来源和原始事件引用、对推断标记置信度、冲突时保留版本不静默覆盖、敏感类型默认不写、定期检查过期记录。
读出来以后,也只把它当作建议
Section titled “读出来以后,也只把它当作建议”检索出相关记忆以后,系统还要决定怎样使用。
例如用户问:“帮我订一杯饮料。”Memory 返回:
{ "key": "drink", "value": "tea", "source": "conversation-2", "updated_at": "2026-07-20", "confidence": "confirmed"}应用可以把它作为偏好建议,但不应直接执行付款。当前请求、库存、过敏信息和用户确认仍然更重要。
Memory 是上下文的一部分,不拥有最终行动权限。它可以帮助 Agent 少问一遍,却不能替代当前请求、业务规则和确认步骤。
删除不是从向量索引删一条记录
Section titled “删除不是从向量索引删一条记录”一条记忆可能同时存在于主数据库、向量索引、缓存、图数据库、对话摘要、离线评测数据,以及备份和日志里。
用户要求删除时,系统需要知道数据血缘和保留政策。同步删除可能需要时间,但不能把“索引不可见”描述成“已经彻底删除”。
Memory 系统从第一天就应设计:查看、纠正、过期、删除和审计。
动手跑一次:偏好更新后,旧值不能继续出现
Section titled “动手跑一次:偏好更新后,旧值不能继续出现”先进入本讲目录,再运行:
python3 experiments/memory_lifecycle.pymemory_lifecycle.py 实现了一个很小的结构化 Memory Store。它没有做向量检索,故意把注意力放在更容易被跳过的更新和删除语义上。
第一次写入:
drink = coffee, version = 1用户后来改为喝茶:
drink = tea, version = 2读取返回 tea,并保留来源与版本。执行删除以后,当前读取返回 null。事件日志仍记录发生过 upsert 和 delete,但不保存已删除值。
完整结果见 experiment-result.json。运行后先核对两处:删除前的值是 tea 且版本为 2;删除后的当前读取是 null。
实验没有向量检索,仍然展示了 Memory 最重要的三个动作:更新、版本和删除。
读者可以继续增加:过期时间、租户隔离、冲突确认和索引同步状态。
怎样判断一个应用是否需要长期记忆
Section titled “怎样判断一个应用是否需要长期记忆”先问四个问题:信息跨会话后仍然有价值吗?每次重新询问的成本高吗?记错的损失有多大?用户能否查看、纠正和删除?
如果价值低、错误代价高、又无法治理,最好的 Memory 可能是不写。
典型适用场景包括长期助理、学习进度、客户关系、持续项目和设备历史。不适合默认长期保存的内容包括一次性敏感请求、未经确认的健康/财务推断、临时情绪和外部网页中的指令。
Memory 设计时要考虑清楚这些问题
Section titled “Memory 设计时要考虑清楚这些问题”关于写:谁触发写入?信息是否经用户确认?是否保存来源、时间和置信度?哪些敏感类型禁止写入?
关于管:冲突怎样处理?是否有版本和过期?多租户怎样隔离?后台巩固怎样避免覆盖新事实?
关于读:按当前目标和权限检索吗?是否区分偏好与硬约束?注入上下文时是否显示来源和时效?
关于删:用户能否查看和纠正?主存储、索引、缓存和下游是否同步?删除是否有可审计状态?
收尾:先把“会记住什么”说清楚
Section titled “收尾:先把“会记住什么”说清楚”真正好用的 Memory,不是让 Agent 把每句话都留住,而是让一条有价值的信息能够被追溯、被更新、被质疑,也能被删除。
向量数据库解决的是相似检索。Memory Engineering 还得回答:谁能写、写入的依据是什么、冲突怎样处理、谁能读,以及删除要同步到哪里。
在开始选框架前,不妨先拿一个真实业务字段做盘点:它是当前任务状态、外部知识,还是长期偏好?这个分类往往比“先接哪个数据库”更早决定系统是否可治理。
下一讲回到 Harness 的整体工程结构,讨论模型、代码、状态图和持久化运行时分别应该拥有多少控制权。
延伸阅读:按问题继续往下看
Section titled “延伸阅读:按问题继续往下看”- 想先建立完整视角:读 Memory for Autonomous LLM Agents,按 write、manage、read 的顺序看问题,而不是只看检索算法。
- 想理解“事件如何变成可回忆的经验”:读 Generative Agents 的记忆流、反思和规划设计。
- 想研究上下文与外部存储怎样切换:对照 MemGPT 和 Letta 的实践。
[1] Memory for Autonomous LLM Agents. https://arxiv.org/abs/2603.07670
[2] Park et al., Generative Agents. https://arxiv.org/abs/2304.03442
[3] Packer et al., MemGPT. https://arxiv.org/abs/2310.08560
[4] Letta. https://github.com/letta-ai/letta
[5] Mem0. https://github.com/mem0ai/mem0
[6] LangMem, Conceptual Guide. https://langchain-ai.github.io/langmem/concepts/conceptual_guide/
[7] Graphiti. https://github.com/getzep/graphiti
[8] Supermemory. https://github.com/supermemoryai/supermemory