如果说 Profile 决定 Agent「像谁」,那 Memory 决定 Agent「知道什么」。一个没有记忆的 Agent 是金鱼——每轮从零开始,连上一句说了什么都忘了。Memory 模块的任务,就是给 LLM 这个「无状态的函数」外挂一层状态,让它在主循环的每一轮里都能读到该读的、写下该写的。
回到第 1.2 节的核心循环「感知-规划-行动-观察」,Memory 出现在其中三个环节:
| 循环环节 | Memory 的角色 |
|---|---|
| 感知 | 读:把历史状态、用户偏好、相关经验加载进来 |
| 观察 | 写:把本轮的行动结果、新发现的事实存进去 |
| 规划 | 用:作为规划的输入上下文(与 Profile 一起) |
注意一个关键点:Memory 既是「输入」也是「输出」。每一轮循环,Memory 先被读取(提供上下文),再被写入(沉淀本轮观察)。这个「读-用-写」的闭环,是 Agent 能跨轮次积累信息的根本机制。
💡 Memory 与上下文窗口的关系:很多人把「上下文窗口」当记忆,这是误解。上下文窗口只是 LLM 单次调用能「看见」的文本长度,本身不持久化——调用结束就消失。Memory 才是持久化的存储;上下文窗口只是 Memory 中「短期记忆」的载体。两者的关系是「Memory 是仓库,上下文窗口是工作台」。
Memory 分两层,功能边界清晰:
┌──────────────────────────────────────────────────┐ │ 短期记忆 (Short-Term / Working Memory) │ │ ────────────────────────────────────── │ │ 内容: 当前对话、最近 N 步观察与行动 │ │ 载体: LLM 上下文窗口 │ │ 容量: Token 有限(几K~几百K) │ │ 速度: 极快(已在上下文里) │ │ 持久性: 调用结束即消失 │ │ 作用: 支撑当前任务的即时推理 │ └──────────────────────────────────────────────────┘ ↑ 溢出/检索 ┌──────────────────────────────────────────────────┐ │ 长期记忆 (Long-Term Memory) │ │ ────────────────────────────────────── │ │ 内容: 历史对话、用户偏好、事实知识、过往经验 │ │ 载体: 向量数据库 / 知识图谱 / 文档库 │ │ 容量: 近似无限 │ │ 速度: 慢(需检索) │ │ 持久性: 跨会话持久 │ │ 作用: 跨任务/跨会话的经验积累 │ └──────────────────────────────────────────────────┘
| 维度 | 短期记忆 | 长期记忆 |
|---|---|---|
| 载体 | LLM 上下文窗口 | 向量库/知识库 |
| 容量 | Token 有限 | 近似无限 |
| 速度 | 极快 | 慢(需检索) |
| 持久性 | 单次会话 | 跨会话 |
| 写入方式 | 自动(拼接进 Prompt) | 显式(Embedding 后存库) |
| 读取方式 | LLM 直接看 | 检索后拼进 Prompt |
| 典型用途 | 当前任务的多步推理 | 用户偏好、历史经验、领域知识 |
⚠️ 一个常被忽略的事实:短期记忆不是「免费」的。上下文越长,LLM 推理越慢、成本越高,且注意力会被稀释(这正是 2.1 节 Profile 漂移的成因之一)。把所有历史都塞进短期记忆,既贵又损害质量。优秀的 Memory 设计,核心是「该留在短期的不外迁,该外迁的及时外迁」。
把 Memory 在一轮循环里的动作展开,可以看到 5 个关键操作:
5 个操作的职责:
| 操作 | 内容 | 频率 |
|---|---|---|
| ① 读短期 | 加载当前对话与最近 N 步 | 每轮必做 |
| ② 检索长期 | 从向量库查相关历史 | 按需(任务涉及历史时) |
| ③ 规划 | 把 Profile + 短期 + 检索结果一起送进 LLM | 每轮必做 |
| ⑤a 写短期 | 把本轮观察拼入上下文 | 每轮必做 |
| ⑤b 写长期 | 把关键观察持久化到向量库 | 按策略(不是每轮都写) |
💡 关键设计点:⑤b 不是每轮都做。把每一步观察都写进长期记忆,会让向量库膨胀且充满噪声。生产实践通常只在「任务里程碑、用户偏好变化、关键事实更新」时才触发长期写入。写什么、何时写,是 Memory 设计的核心策略问题——第 5.4 节会专门讨论。
无论短期还是长期,Memory 里存的内容可以按「信息类型」进一步分类:
| 类型 | 例子 | 存哪里 | 生命周期 |
|---|---|---|---|
| 对话历史 | 用户说的、Agent 回的 | 短期为主,摘要后入长期 | 短期按窗口截断 |
| 任务状态 | 「已完成步骤 1, 当前在步骤 2」 | 短期 | 任务结束即弃 |
| 工具观察 | API 返回的 JSON、搜索结果 | 短期(关键摘要入长期) | 按需保留 |
| 用户偏好 | 「用户喜欢简洁回答」「用户时区是 UTC+8」 | 长期 | 永久(可更新) |
| 事实知识 | 「公司 A 的财报已发布」 | 长期 | 有时效性 |
| 经验反思 | 「上次类似任务失败的原因是 X」 | 长期 | 永久(可累积) |
这六类内容对应《具身智能技术原理》第 4.3 节提到的「工作记忆、情节记忆、语义记忆、程序记忆」四层架构——本教程聚焦软件 Agent,简化为「短期 + 长期两层 + 六类内容」的实用模型。第 5 章会进一步讨论每类内容的写入与检索策略。
⚠️ 不要把所有信息都当成同一种记忆。对话历史和用户偏好的生命周期、检索方式、更新策略完全不同。把它们混在一个存储里管理,会让 Memory 系统既慢又乱。好的 Memory 设计会按内容类型分库分表。
把 Memory 模块抽象出来,它要回答三个工程问题——这三个问题贯穿第 5 章的所有讨论:
不是所有观察都值得记。写得太少,Agent 失去经验;写得太多,记忆库膨胀且充满噪声。
| 写入策略 | 做法 | 适用 |
|---|---|---|
| 全量写入 | 每步观察都存 | 短期记忆(自动) |
| 摘要写入 | 每 K 步压缩成摘要再存 | 长期记忆的对话归档 |
| 事件写入 | 只在关键事件(任务里程碑、错误)时存 | 经验反思 |
| 偏好写入 | 检测到用户偏好变化时存 | 用户画像 |
记忆库再大,LLM 一次只能看有限的内容。检索的目标是「把当前最相关的少数记忆送进上下文」。
| 检索维度 | 含义 | 例子 |
|---|---|---|
| 相似度 | 与当前任务的语义相似 | 「过去类似任务的执行记录」 |
| 时效性 | 多近发生的 | 「最近 24 小时的对话」 |
| 重要性 | 对未来决策的价值 | 「用户的长期偏好」 |
| 频次 | 被引用的次数 | 「高频被问的事实」 |
这四个维度的加权组合,构成了 Generative Agents(斯坦福小镇)等工作中经典的「相似度 × 时效性 × 重要性」检索评分公式。第 5.4 节会展开。
记忆无限增长会让检索变慢、成本变高、噪声变多。主动遗忘是 Memory 系统的健康指标。
| 遗忘策略 | 做法 |
|---|---|
| TTL 过期 | 给每条记忆设生存期,到期自动删 |
| 衰减权重 | 长期未被检索的记忆,重要性递减 |
| 容量上限 | 满额后淘汰最低分的记忆 |
| 矛盾消解 | 新旧冲突时,以新覆旧 |
| 显式归档 | 冷数据迁移到归档库,不再参与日常检索 |
💡 遗忘不是缺陷,是特性。人类大脑的遗忘机制是认知效率的关键;Agent 也一样——一个什么都记的系统,反而比一个懂得遗忘的系统决策更差。第 5.4 节会详细讨论遗忘的设计。
不同复杂度的 Agent 采用不同的 Memory 架构。这里给三种典型形态,从简到繁:
只有上下文窗口,无长期记忆。每轮把历史拼接进 Prompt。
短期记忆管当前任务,长期记忆用向量数据库 + RAG 检索。
在架构二基础上,把长期记忆再细分为「对话归档、用户画像、事实知识、经验反思」多个子库,各自检索策略。
⚠️ 架构选型建议:不要一上来就上架构三。先用架构一验证任务可行性,用架构二覆盖 80% 的生产场景,只在确有长程需求时才升级到架构三。过度工程化是 Memory 设计最常见的坑——很多团队上了架构三,结果发现 90% 的检索都走短期记忆,长期记忆库基本闲置。
Memory 不是孤岛,它与另外三个模块都有耦合点,理解这些耦合对设计 Agent 至关重要:
| 耦合对象 | 耦合点 | 设计含义 |
|---|---|---|
| Profile | Profile 决定「关注什么」→ 影响检索与写入 | 财务助手的 Memory 只关心财报数据,不存闲聊 |
| Planning | Planning 决定「需要什么信息」→ 影响检索查询 | 规划出"需要历史股价"→ 触发对应检索 |
| Action | Action 产生观察 → 写入 Memory | Action 的输出格式决定 Memory 的写入格式 |
最关键的耦合是 Memory ↔ Planning:Memory 提供「已知什么」,Planning 决定「还要查什么」。一个成熟的 Agent,Planning 模块应当能主动发起检索请求——「我需要用户的历史订单数据」——而不是被动地等 Memory 喂什么就用什么。这种「主动检索」是高级 Agent 的标志,第 5 章 RAG 部分会展开。
最后列出 Memory 设计的常见反模式:
| 反模式 | 表现 | 后果 | 正确做法 |
|---|---|---|---|
| 把上下文窗口当万能记忆 | 不用长期记忆,全塞 Prompt | 贵+慢+稀释 | 区分短期/长期 |
| 全量写入长期 | 每步观察都存 | 记忆库膨胀 | 写入策略分级 |
| 只写不删 | 永不遗忘 | 检索变慢、噪声多 | 主动遗忘机制 |
| 单一检索维度 | 只按相似度 | 漏掉时效/重要性 | 多维加权评分 |
| 不分类型混存 | 对话/偏好/事实一个库 | 管理混乱 | 按内容类型分库 |
| 过度工程化 | 一开始就上多层架构 | 维护成本高 | 按需升级 |
下一节《2.3 Planning 规划模块》将讨论任务建模、规划空间与策略路由——即「面对不同任务,怎么在 CoT/ReAct/ToT/任务分解之间选」。具体算法留待第 3-4 章。