前三节讲了短期、长期、RAG 三块「硬件」。但记忆系统真正难的是「软件」——什么时候该检索、检索回来怎么用、新信息怎么更新、旧信息什么时候该忘。这一节讨论记忆的全生命周期管理,并连接 Generative Agents(斯坦福小镇)这一经典工作。
一条记忆从「诞生」到「消亡」,经历四个阶段:
| 阶段 | 关键问题 |
|---|---|
| 写入 | 写什么、什么时候写(5.2 节) |
| 存储 | 存哪里、怎么索引(5.2 节) |
| 检索 | 什么时候检索、检索多少(5.3 节 + 本节) |
| 更新/遗忘 | 何时改、何时忘(本节) |
本节聚焦后两个易被忽视的环节——检索时机与遗忘机制。
第 5.3 节讨论了「怎么检索」,本节讨论「什么时候检索」。这是个被低估的问题——查太频繁浪费成本,查太少错失关键信息。
| 模式 | 触发 | 适用 |
|---|---|---|
| 每轮必检 | 每次用户输入都查 | 知识问答型 Agent |
| 按需检索 | LLM 判断「需要时」才查 | ReAct 类 Agent |
| 事件触发 | 特定事件(如换话题)触发 | 长对话助手 |
最简单——每次用户输入都把记忆查一遍,把 Top-K 拼进 Prompt。
让 LLM 自己判断「这个问题需要查记忆吗」。这是更智能的模式,也是 ReAct 类 Agent 的核心。
用户: "我之前提过的那个项目进展如何?" LLM Thought: 用户提到了「之前的项目」,我需要检索历史记忆。 LLM Action: recall_memory("用户的项目") Observation: 找到 3 条相关记忆...
💡 主动检索是成熟 Agent 的标志:它不再被动地「每次都查」,而是根据当前任务主动判断「需要什么信息、去哪里查」。这与第 2.2 节强调的「Memory↔Planning 主动耦合」一脉相承。
某些事件(如「换话题」「新会话开始」「检测到用户身份」)触发检索。
| 触发事件 | 检索内容 |
|---|---|
| 新会话开始 | 用户画像、长期偏好 |
| 换话题 | 新话题相关历史 |
| 用户身份确认 | 该用户的专属记忆 |
| 时间推进 | 时效性记忆(如「上次提到的会议是今天」) |
讲到记忆检索,绕不开 Generative Agents(斯坦福小镇,Park et al. 2023)。这个工作让 25 个 LLM 角色在一个虚拟小镇里生活、记忆、反思、社交,是 Agent 记忆架构的里程碑。
| 机制 | 内容 |
|---|---|
| 记忆流(Memory Stream) | 按时间顺序记录所有观察的长期记忆 |
| 检索(Retrieval) | 三因子加权检索 |
| 反思(Reflection) | 定期从记忆里归纳出高阶结论 |
Generative Agents 提出了经典的记忆检索评分公式——每条记忆的「该被检索分数」由三个因子相乘:
| 因子 | 含义 | 计算 |
|---|---|---|
| Recency(时效性) | 多近发生的 | 指数衰减(最近的最高) |
| Relevance(相关性) | 与当前查询多相关 | Embedding 相似度 |
| Importance(重要性) | 对 Agent 多重要 | LLM 打分(1-10) |
<svg viewBox="0 0 720 280" xmlns="http://www.w3.org/2000/svg"> <rect x="40" y="100" width="140" height="80" fill="#dbeafe" stroke="#2563eb" rx="6"/> <text x="110" y="130" font-size="13" fill="#1e3a8a" text-anchor="middle" font-weight="bold">Recency</text> <text x="110" y="150" font-size="11" fill="#1e3a8a" text-anchor="middle">时效性</text> <text x="110" y="170" font-size="10" fill="#1e3a8a" text-anchor="middle">指数衰减</text> <text x="200" y="145" font-size="20" fill="#475569" text-anchor="middle">×</text> <rect x="240" y="100" width="140" height="80" fill="#fef9c3" stroke="#ca8a04" rx="6"/> <text x="310" y="130" font-size="13" fill="#713f12" text-anchor="middle" font-weight="bold">Relevance</text> <text x="310" y="150" font-size="11" fill="#713f12" text-anchor="middle">相关性</text> <text x="310" y="170" font-size="10" fill="#713f12" text-anchor="middle">Embedding 相似度</text> <text x="400" y="145" font-size="20" fill="#475569" text-anchor="middle">×</text> <rect x="440" y="100" width="140" height="80" fill="#fce7f3" stroke="#db2777" rx="6"/> <text x="510" y="130" font-size="13" fill="#831843" text-anchor="middle" font-weight="bold">Importance</text> <text x="510" y="150" font-size="11" fill="#831843" text-anchor="middle">重要性</text> <text x="510" y="170" font-size="10" fill="#831843" text-anchor="middle">LLM 打分</text> <text x="610" y="145" font-size="20" fill="#475569" text-anchor="middle">=</text> <rect x="630" y="100" width="70" height="80" fill="#dcfce7" stroke="#16a34a" rx="6"/> <text x="665" y="135" font-size="12" fill="#14532d" text-anchor="middle" font-weight="bold">检索</text> <text x="665" y="155" font-size="12" fill="#14532d" text-anchor="middle" font-weight="bold">分数</text> <text x="360" y="40" font-size="14" fill="#475569" text-anchor="middle" font-weight="bold">Generative Agents 三因子检索公式</text> </svg>
三个因子都重要,但权重不同:
| 场景 | 偏重哪个因子 |
|---|---|
| 实时问答 | Relevance(相关最重要) |
| 个人助手(用户偏好) | Importance(重要的事不忘) |
| 任务跟踪 | Recency(最新进展) |
| 长期关系 | Importance + Recency 平衡 |
💡 三因子公式的深刻意义:它把「该想什么」量化为一个可计算的分数。人类回忆往事,其实也在隐式做类似的事——最近的事记得清(Recency)、相关的事想得起(Relevance)、重要的事忘不掉(Importance)。Generative Agents 用一个公式把人类记忆规律显式化了。
光有记忆还不够。一个 Agent 会积累成千上万条记忆,如果不归纳,会陷入「细节海洋」看不到大局。**反思(Reflection)**就是定期从大量低阶记忆里归纳出高阶结论。
低阶记忆(过去几天): - 用户问了项目 A 的进度 - 用户问了项目 A 的预算 - 用户问了项目 A 的人员 - 用户问了项目 A 的风险 反思触发: 「这 100 条记忆里,有什么反复出现的主题?」 反思结论: "用户对项目 A 高度关注,可能项目 A 是用户当前最重要的事。" (作为高阶记忆存回)
这条反思是比单条记忆更高阶的知识——它不是事实,而是从事实里抽象出的判断。
| 维度 | Generative Agents 反思 | Reflexion(第 4.3 节) |
|---|---|---|
| 触发 | 定期(N 条/小时) | 任务失败后 |
| 对象 | 大量历史记忆 | 单次任务经验 |
| 目的 | 归纳高阶知识 | 避免重复犯错 |
两者思想相通——都是「从经验里学」——但侧重不同:Generative Agents 反思是为了「理解大局」,Reflexion 反思是为了「改进行为」。
记忆不是只读的,它会更新。更新有两类:增量与修订。
新信息追加,旧信息保留。
旧: 用户在 UTC+8 新: 用户提到即将搬到纽约 更新后: - 用户当前 UTC+8 - 计划搬迁: 纽约 (UTC-5)
新信息让旧信息失效,直接覆盖。
旧: 用户在 UTC+8 新: 用户已搬到纽约 更新后: - 用户当前 UTC-5 (纽约) (旧的 UTC+8 标记为历史)
| 更新类型 | 处理 | 例子 |
|---|---|---|
| 增量 | 都保留 | 兴趣增加 |
| 修订 | 新覆旧 | 位置变化 |
| 版本 | 保留历史版本 | 重要决策 |
| 失效标记 | 旧标记 invalid | 过期事件 |
⚠️ 更新的核心难题是判断「该增量还是修订」。判错会让记忆矛盾。生产实践通常用「默认修订、关键变更保留版本」的策略。
记忆无限增长会让检索变慢、成本变高、噪声变多。主动遗忘是记忆系统的健康指标——这与人脑一样。
| 策略 | 做法 | 触发 |
|---|---|---|
| TTL 过期 | 给每条记忆设生存期 | 时间到自动删 |
| 重要性衰减 | 长期未检索的记忆,Importance 递减 | 分数低于阈值时归档 |
| 容量上限 | 满额淘汰最低分 | LLM 容量管理 |
| 矛盾消解 | 新旧冲突时以新覆旧 | 检测到冲突 |
| 显式归档 | 冷数据迁到归档库 | 长期未访问 |
Importance 衰减常用指数衰减:
其中 \Delta t 是距上次检索的时间,\lambda 是衰减率。\lambda 越大遗忘越快。
刚写入: Importance = 1.0 1 天未访问: Importance = 0.7 1 周未访问: Importance = 0.3 1 月未访问: Importance = 0.05 → 归档
💡 遗忘是特性,不是缺陷:人类大脑靠遗忘保持认知效率。Agent 也一样——一个什么都记的系统,反而比一个懂得遗忘的系统决策更差。优秀的记忆系统应当像人类大脑一样「记得重要的、忘掉琐碎的」。
把短期记忆、长期记忆、反思、遗忘合在一起,构成一个完整的层级模型:
| 层 | 内容 | 类比人类 |
|---|---|---|
| 工作记忆 | 当前上下文 | 短时记忆 |
| 情节记忆 | 事件历史 | 个人经历 |
| 语义记忆 | 事实与知识 | 知识储备 |
| 反思记忆 | 高阶结论 | 经验智慧 |
| 程序记忆 | 技能与流程 | 运动技能 |
这个五层结构与《具身智能技术原理》第 4.3 节的四层记忆架构相通——本教程聚焦软件 Agent,多了「反思记忆」这一层(Generative Agents 的贡献)。
| 反模式 | 表现 | 后果 | 正确做法 |
|---|---|---|---|
| 只写不删 | 永不遗忘 | 库膨胀、检索慢 | 主动遗忘 |
| 每轮都全检 | 不分场景全检索 | 浪费+干扰 | 按需/事件触发 |
| 不反思 | 只有低阶记忆 | 看不到大局 | 定期反思归纳 |
| 更新不判类型 | 一刀切覆盖/保留 | 矛盾或冗余 | 增量/修订/版本分类 |
| 不分层 | 工作台与档案柜混 | 短期被污染 | 短期/长期/反思分层 |
| 不考虑重要性 | 所有记忆同等权 | 重要事被淹没 | Importance 加权 |
本章纵向深化了 Memory 模块:从短期记忆的压缩(5.1),到长期记忆的向量库(5.2),到 RAG 的检索增强(5.3),再到记忆的检索更新与遗忘(5.4)。读者现在应当能:
下一章(第 6 章)将转向 Action 模块——让 Agent 真正长出「手脚」,去调用工具、运行代码、操作外部世界。这是 Agent 从「能想」到「能做」的最后一公里。