Agent 记忆系统
没有记忆的 Agent 每次都「失忆」,无法积累经验、维持长期个性化。记忆系统是 Agent 从「单次任务」走向「长期助理」的关键,也是 Agent 面试的进阶考点——能讲清「写入策略」和「记忆冲突」的人很少。
为什么 Agent 需要记忆?
LLM 本身无状态——每次调用只看得到当前上下文,关掉就忘。但真实助理需要:记住用户偏好与历史(个性化)、在长任务中跨步骤保持状态、从过往成败中积累经验。上下文窗口是有限且昂贵的「工作记忆」,装不下也不该装下所有历史 → 需要外部记忆系统。
记忆的分类
| 类型 | 对应人类 | 内容示例 | 典型实现 |
|---|---|---|---|
| 短期记忆 | 工作记忆 | 当前对话/任务状态 | 上下文窗口本身 |
| 情景记忆(Episodic) | 经历 | 「5 月 3 日用户退过一次货」 | 带时间戳的事件库 |
| 语义记忆(Semantic) | 知识 | 「用户是后端工程师,偏好简洁回答」 | 事实条目(向量库/结构化存储) |
| 程序记忆(Procedural) | 技能 | 「部署流程先跑测试再发布」 | system prompt 规则、技能文件、工具 |
区分情景与语义是面试高频点:情景是「发生过的具体事」(原始、带时间),语义是「提炼出的稳定结论」。好的记忆系统会从情景中蒸馏语义(多次「用户要求简短」→ 固化成「偏好简洁」)。
记忆系统的完整工作流
对话/经历 ──► ① 写入:抽取该记的信息 ──► 长期存储(向量库/DB/文件)
│
新一轮交互 ──► ② 检索:按当前需要召回相关记忆 ─┘
──► ③ 注入:拼进上下文(上下文工程)
──► ④ 更新/遗忘:合并、修正、淘汰① 写入:最难也最重要的一步
写什么:稳定偏好、关键事实、任务结论、明确纠错(「别再用 mermaid」)——而不是对话原文。 何时写:会话结束时批量总结(便宜,可能丢中途信息)vs 实时判断写入(及时,贵)vs 用户显式触发(「记住这个」)。 怎么写:用 LLM 抽取成原子化条目(一条记忆一个事实),附元数据(时间、来源、置信度)——原子化是后续检索与更新的前提。
② 检索与 ③ 注入
本质是 RAG:记忆条目向量化,按当前 query 相似度 + 时间近因 + 重要性加权召回(生成式 Agent 经典的三因子打分)。注入时放进 system prompt 或专门的记忆区块,注意控制条数防止挤占上下文(见 上下文工程)。
④ 更新与遗忘:防止记忆库腐烂
- 冲突解决:新信息与旧记忆矛盾时(用户「我换工作了」),要更新而非并存——否则检索会同时召回矛盾条目,污染上下文。策略:写入前先检索相似记忆,LLM 判断是新增/更新/删除(Mem0 的核心机制)。
- 合并去重:周期性把相似条目合并。
- 衰减淘汰:按「最后引用时间 × 重要性」打分,长期未用的低权重记忆归档——无限膨胀的记忆库 = 检索噪声放大器。
主流实现方案
| 方案 | 思路 | 代表 |
|---|---|---|
| 向量库记忆 | 条目 Embedding + 相似度检索 | 最通用的自建方案 |
| 记忆框架 | 抽取/更新/冲突解决开箱即用 | Mem0、Letta(原 MemGPT)、Zep |
| 文件型记忆 | 记忆写成人类可读的 markdown 文件,模型用工具读写 | Claude Code 的 CLAUDE.md/memory 目录、各类 Agent 的笔记文件 |
| 知识图谱记忆 | 实体-关系建模,支持多跳关联 | Zep/Graphiti 等 |
MemGPT 思想(高频考点):把 LLM 类比操作系统——上下文窗口是「内存」,外部存储是「磁盘」,模型自主调用记忆工具在两者间换入换出(分页),在有限窗口下管理无限信息。
文件型记忆为什么流行:人类可读可改(用户能直接审计和纠正记忆)、天然支持版本控制、模型用现成的读写工具就能操作,不需要专门基础设施——工程上「足够简单」常胜过「架构优雅」。
短期记忆(上下文内)的管理
窗口装不下全部历史时:全量缓冲(很快超窗)→ 滑动窗口(丢早期信息)→ 摘要压缩(旧对话压成摘要)→ 混合(近期原文 + 远期摘要 + 关键事实置顶)。注意摘要是有损的,关键约束(如用户明确的禁止事项)要单独固化,不能依赖摘要保留。
记忆 vs RAG:一道辨析题
| RAG 知识库 | Agent 记忆 | |
|---|---|---|
| 内容 | 外部文档/知识(静态为主) | 交互中产生的个体信息(动态) |
| 写入方 | 离线管道导入 | Agent 自己边用边写 |
| 关键难点 | 检索质量 | 写入策略与一致性维护 |
| 共同点 | 都靠「向量化 + 检索 + 注入」 | 同左 |
高频追问
Q:Agent 的短期记忆和长期记忆有什么区别? 短期 = 当前上下文窗口(会话结束即失效,受窗口大小限制);长期 = 外部持久存储(跨会话,理论无限但需检索)。设计上的关键是两者间的「换入换出」策略。
Q:长期记忆本质上是什么技术?和 RAG 的区别? 检索侧本质就是 RAG(向量化 + 相似度召回 + 注入)。区别在写入侧:记忆需要 Agent 自己抽取、判断新增/更新/删除、解决冲突、衰减淘汰——RAG 知识库通常没有这套动态维护机制。
Q:记忆为什么不能把对话原文全存? 存储爆炸、检索噪声大、矛盾信息并存。正确做法:LLM 抽取成原子化事实条目 + 元数据,写入前先查重判断增/改/删,定期合并淘汰。
Q:记忆冲突怎么处理? 写入前检索相似旧记忆,让 LLM 对比判断:互补则都留、矛盾则新覆盖旧(或标注时效)、重复则合并。没有冲突解决的记忆系统用得越久越不可信——这是 Mem0 等框架的核心卖点。
Q:MemGPT 的核心思想? LLM 当操作系统:上下文是内存、外部存储是磁盘,模型通过自主调用记忆读写工具做「分页调度」,突破窗口限制。它把记忆管理从「外挂管道」变成「模型自主行为」。
Q:怎么评估一个记忆系统好不好? 召回质量(该想起来的想起来了吗)、一致性(矛盾信息是否被正确更新)、个性化效果(多轮后回答是否贴合用户)、成本(写入与检索的额外调用)。公开基准如 LOCOMO(长程对话记忆)可参考,业务上用多会话模拟测试。