logo

记忆系统设计 (Memory Systems)

很多 Agent Demo 一开始都挺聪明,聊到第 6 轮以后就开始“失忆”。上一句刚说完的约束忘了,用户偏好记不住,前面已经查过的资料又查一遍。问题通常不在模型本身,而在记忆系统没设计好。

如果把 Agent 当成一个长期协作的助手,记忆不是可选项,而是核心能力。没有记忆,Agent 更像一次性问答机器人;有了记忆,它才开始像一个真的做过事的搭档。

[PROMPT_LAB_BANNER]


1. 先把“记忆”分清楚

在 Agent 系统里,常见的记忆大概可以分成三层。这个划分不是学术定义,而是工程上比较好落地:

类型对应实现典型作用持续时间
感官记忆当前输入、上传文件、截图、网页内容暂存这一轮刚拿到的原始材料秒级到分钟级
短期记忆Context Window、会话状态、摘要维持当前任务连续性一次会话内
长期记忆Vector DB、关系表、Graph DB、用户 Profile记住跨会话知识、偏好、历史决策天级到永久

一个很常见的误区是,把所有东西都塞进长期记忆。其实没必要。像“用户刚刚上传了一张报错截图”这种信息,过了当前排错场景就没什么价值;但“用户偏好 TypeScript、项目统一用 pnpm、代码注释写英文”这种约束,就值得留下来。


2. 短期记忆:别迷信超长上下文

现在很多模型上下文都很长,看起来像是“那我全部塞进去就好了”。实际做起来通常会踩三个坑:

  1. 成本会很快失控,特别是多 Agent 协作时。
  2. 模型响应会变慢,工具调用前的思考也会拖长。
  3. 中间信息最容易被忽略,也就是常说的 Lost in the Middle

所以短期记忆的重点不是“越多越好”,而是“把当前任务真正需要的内容留下来”。

策略 A:滑动窗口

最简单的做法,就是只保留最近的 N 轮对话或最近的若干 token。

  • 好处是实现简单,成本稳定,出了问题也容易调试。
  • 问题是早期但关键的约束很容易掉出去,比如“这个仓库必须兼容 Node 18”或者“用户不想改数据库 schema”。

这种方案适合:

  • 一次性问答
  • 任务很短的客服类流程
  • 对历史依赖不强的工具型 Agent

策略 B:会话摘要

更实用的方式,是在对话变长以后自动生成一段工作摘要,把已经确认的目标、限制和中间结论压缩下来。

比如真实项目里,一段摘要可能长这样:

当前任务是修复支付页白屏;仓库用 Next.js 14;问题只在 production 复现;用户已经确认不是后端接口超时;不要动埋点逻辑,优先排查 hydration mismatch。

这样的摘要比原始 20 轮对话更有价值,因为它保留了“任务状态”,而不是保留所有聊天痕迹。

策略 C:任务状态单独存

如果 Agent 不只是聊天,而是在跑一个多步骤任务,建议把任务状态从对话里剥离出来,单独存成结构化对象,比如:

{
  "goal": "修复生产环境白屏问题",
  "constraints": [
    "不要修改数据库结构",
    "必须兼容 Node 18"
  ],
  "completed_steps": [
    "已确认本地无法复现",
    "已检查接口响应正常"
  ],
  "next_step": "排查 hydration mismatch"
}

这比单纯依赖聊天记录稳很多。尤其是多 Agent 场景,状态对象可以直接共享,不需要每个 Agent 重新“读懂”一遍上下文。


3. 长期记忆:什么时候该上 RAG

当 Agent 需要记住跨会话的信息时,就该考虑长期记忆了。常见场景包括:

  • 公司内部知识库
  • 历史项目决策
  • 用户长期偏好
  • 上次任务已经验证过的解决方案

这时候最常见的方案还是 RAG。

基础 RAG 流程

一个标准流程通常包括这几步:

  1. Chunking:把文档切成可检索的小块。
  2. Embedding:把文本转成向量。
  3. Storage:存进向量数据库,例如 Pinecone、Weaviate、ChromaDB。
  4. Retrieval:用户提问时检索相关内容,再注入模型上下文。

这个流程大家都知道,但真正影响效果的往往不是“有没有 RAG”,而是下面这些细节:

  • chunk 切得太大,召回准但上下文浪费严重
  • chunk 切得太碎,关键词命中高但语义断裂
  • 文档更新后没重建索引,导致 Agent 读到过期知识
  • 检索回来的内容没做去重和排序,模型拿到一堆重复片段

混合检索通常比纯向量更靠谱

只用向量检索,经常会在专有名词、错误码、配置项上翻车。

例如用户搜的是 TS2304use serverClaude Code hooks 这种词,关键词匹配通常比纯语义相似更直接。所以更稳的做法一般是:

向量检索 + 关键词检索 + rerank

工程上不用一开始就做得很重,但如果你发现 Agent 总是“差一点才找到对的文档”,优先看检索链路,而不是先怪模型。


4. 有些记忆不该存成向量

不是所有信息都适合走 RAG。

像用户资料、权限、偏好、固定约束,这类信息通常需要精确读写。你不希望用户明明说过“回复请用中文”,结果下一轮因为向量召回不稳定,Agent 又切回英文。

这类信息更适合做成结构化记忆,比如用户 Profile:

{
  "user_id": "123",
  "preferences": {
    "language": "zh-CN",
    "coding_style": "TypeScript",
    "theme": "Dark"
  },
  "facts": [
    "住在墨尔本",
    "有一只叫旺财的狗"
  ]
}

然后在关键节点显式更新,而不是等模型自己“猜”。

一个实用原则是:

  • 模糊知识,用检索
  • 明确事实,用结构化存储
  • 当前任务状态,用会话状态或任务对象

这样拆开以后,系统会稳定很多。


5. 记忆不是只会增长,还要会清理

很多团队做到后面会发现,真正难的不是“记住”,而是“记得太多”。

如果什么都存,最后会出现几个问题:

  • 噪音越来越多,召回质量下降
  • 过期信息和新信息冲突
  • 用户偶然提过一次的话被系统当成长期偏好

所以长期记忆需要定期整理。常见做法包括:

  • 重要性评分:低价值信息不入库
  • 时间衰减:很久没命中的内容逐步降权
  • 冲突解决:新事实出现时,替换或标记旧事实
  • 记忆合并:把重复碎片整理成更高层的总结

举个例子,用户一周内说过三次“最近都在看 RAG 和 Agent”,那它可能值得提升为长期兴趣;但如果只是一次随口提到“今晚要买牛奶”,真的没必要永远记住。


6. 实际落地时,我更建议这样选型

如果你现在正准备做 Agent,不用一开始就上最复杂的记忆架构。可以按复杂度逐步加:

轻量版

  • 最近几轮对话
  • 一段自动摘要
  • 少量结构化用户偏好

适合单 Agent、任务较短的产品。

进阶版

  • 会话摘要
  • RAG 知识库
  • 用户 Profile
  • 任务状态对象

适合已经有明确工作流的 AI 助手、代码助手或内部知识问答系统。

重度版

  • 混合检索
  • 多层记忆存储
  • 记忆评分与清理机制
  • 多 Agent 共享状态

这类设计更适合复杂代理系统,但维护成本也明显更高。


小结

一个能长期协作的 Agent,核心不只是“模型更强”,而是它有没有把该记住的东西记住,把不该背着走的噪音丢掉。

如果只记一句话,我会选这个:

短期记忆解决连贯性,长期记忆解决可复用性,结构化记忆解决确定性。

这三件事分不清,Agent 很容易看起来什么都知道,实际一做事就开始忘。分清以后,很多“模型不稳定”的问题,最后都会变成普通的系统设计问题。

AI Agent 开发实战手册
AI Engineer

AI Agent 开发实战手册

从 0 到 1 掌握 AI Agent 开发:涵盖自主计划、工具调用、MCP 协议与多智能体编排实战。

AI Agent 开发实战手册记忆系统设计

记忆系统设计 (Memory Systems)

很多 Agent Demo 一开始都挺聪明,聊到第 6 轮以后就开始“失忆”。上一句刚说完的约束忘了,用户偏好记不住,前面已经查过的资料又查一遍。问题通常不在模型本身,而在记忆系统没设计好。

如果把 Agent 当成一个长期协作的助手,记忆不是可选项,而是核心能力。没有记忆,Agent 更像一次性问答机器人;有了记忆,它才开始像一个真的做过事的搭档。

Prompt Lab

把这章的知识,直接变成实战能力

进入交互式实验室,用真实任务练 Prompt,10 分钟快速上手。

进入 Prompt Lab →

#1. 先把“记忆”分清楚

在 Agent 系统里,常见的记忆大概可以分成三层。这个划分不是学术定义,而是工程上比较好落地:

类型对应实现典型作用持续时间
感官记忆当前输入、上传文件、截图、网页内容暂存这一轮刚拿到的原始材料秒级到分钟级
短期记忆Context Window、会话状态、摘要维持当前任务连续性一次会话内
长期记忆Vector DB、关系表、Graph DB、用户 Profile记住跨会话知识、偏好、历史决策天级到永久

一个很常见的误区是,把所有东西都塞进长期记忆。其实没必要。像“用户刚刚上传了一张报错截图”这种信息,过了当前排错场景就没什么价值;但“用户偏好 TypeScript、项目统一用 pnpm、代码注释写英文”这种约束,就值得留下来。


#2. 短期记忆:别迷信超长上下文

现在很多模型上下文都很长,看起来像是“那我全部塞进去就好了”。实际做起来通常会踩三个坑:

  1. 成本会很快失控,特别是多 Agent 协作时。
  2. 模型响应会变慢,工具调用前的思考也会拖长。
  3. 中间信息最容易被忽略,也就是常说的 Lost in the Middle

所以短期记忆的重点不是“越多越好”,而是“把当前任务真正需要的内容留下来”。

#策略 A:滑动窗口

最简单的做法,就是只保留最近的 N 轮对话或最近的若干 token。

  • 好处是实现简单,成本稳定,出了问题也容易调试。
  • 问题是早期但关键的约束很容易掉出去,比如“这个仓库必须兼容 Node 18”或者“用户不想改数据库 schema”。

这种方案适合:

  • 一次性问答
  • 任务很短的客服类流程
  • 对历史依赖不强的工具型 Agent

#策略 B:会话摘要

更实用的方式,是在对话变长以后自动生成一段工作摘要,把已经确认的目标、限制和中间结论压缩下来。

比如真实项目里,一段摘要可能长这样:

当前任务是修复支付页白屏;仓库用 Next.js 14;问题只在 production 复现;用户已经确认不是后端接口超时;不要动埋点逻辑,优先排查 hydration mismatch。

这样的摘要比原始 20 轮对话更有价值,因为它保留了“任务状态”,而不是保留所有聊天痕迹。

#策略 C:任务状态单独存

如果 Agent 不只是聊天,而是在跑一个多步骤任务,建议把任务状态从对话里剥离出来,单独存成结构化对象,比如:

json
{ "goal": "修复生产环境白屏问题", "constraints": [ "不要修改数据库结构", "必须兼容 Node 18" ], "completed_steps": [ "已确认本地无法复现", "已检查接口响应正常" ], "next_step": "排查 hydration mismatch" }

这比单纯依赖聊天记录稳很多。尤其是多 Agent 场景,状态对象可以直接共享,不需要每个 Agent 重新“读懂”一遍上下文。


#3. 长期记忆:什么时候该上 RAG

当 Agent 需要记住跨会话的信息时,就该考虑长期记忆了。常见场景包括:

  • 公司内部知识库
  • 历史项目决策
  • 用户长期偏好
  • 上次任务已经验证过的解决方案

这时候最常见的方案还是 RAG。

#基础 RAG 流程

一个标准流程通常包括这几步:

  1. Chunking:把文档切成可检索的小块。
  2. Embedding:把文本转成向量。
  3. Storage:存进向量数据库,例如 Pinecone、Weaviate、ChromaDB。
  4. Retrieval:用户提问时检索相关内容,再注入模型上下文。

这个流程大家都知道,但真正影响效果的往往不是“有没有 RAG”,而是下面这些细节:

  • chunk 切得太大,召回准但上下文浪费严重
  • chunk 切得太碎,关键词命中高但语义断裂
  • 文档更新后没重建索引,导致 Agent 读到过期知识
  • 检索回来的内容没做去重和排序,模型拿到一堆重复片段

#混合检索通常比纯向量更靠谱

只用向量检索,经常会在专有名词、错误码、配置项上翻车。

例如用户搜的是 TS2304use serverClaude Code hooks 这种词,关键词匹配通常比纯语义相似更直接。所以更稳的做法一般是:

向量检索 + 关键词检索 + rerank

工程上不用一开始就做得很重,但如果你发现 Agent 总是“差一点才找到对的文档”,优先看检索链路,而不是先怪模型。


#4. 有些记忆不该存成向量

不是所有信息都适合走 RAG。

像用户资料、权限、偏好、固定约束,这类信息通常需要精确读写。你不希望用户明明说过“回复请用中文”,结果下一轮因为向量召回不稳定,Agent 又切回英文。

这类信息更适合做成结构化记忆,比如用户 Profile:

json
{ "user_id": "123", "preferences": { "language": "zh-CN", "coding_style": "TypeScript", "theme": "Dark" }, "facts": [ "住在墨尔本", "有一只叫旺财的狗" ] }

然后在关键节点显式更新,而不是等模型自己“猜”。

一个实用原则是:

  • 模糊知识,用检索
  • 明确事实,用结构化存储
  • 当前任务状态,用会话状态或任务对象

这样拆开以后,系统会稳定很多。


#5. 记忆不是只会增长,还要会清理

很多团队做到后面会发现,真正难的不是“记住”,而是“记得太多”。

如果什么都存,最后会出现几个问题:

  • 噪音越来越多,召回质量下降
  • 过期信息和新信息冲突
  • 用户偶然提过一次的话被系统当成长期偏好

所以长期记忆需要定期整理。常见做法包括:

  • 重要性评分:低价值信息不入库
  • 时间衰减:很久没命中的内容逐步降权
  • 冲突解决:新事实出现时,替换或标记旧事实
  • 记忆合并:把重复碎片整理成更高层的总结

举个例子,用户一周内说过三次“最近都在看 RAG 和 Agent”,那它可能值得提升为长期兴趣;但如果只是一次随口提到“今晚要买牛奶”,真的没必要永远记住。


#6. 实际落地时,我更建议这样选型

如果你现在正准备做 Agent,不用一开始就上最复杂的记忆架构。可以按复杂度逐步加:

#轻量版

  • 最近几轮对话
  • 一段自动摘要
  • 少量结构化用户偏好

适合单 Agent、任务较短的产品。

#进阶版

  • 会话摘要
  • RAG 知识库
  • 用户 Profile
  • 任务状态对象

适合已经有明确工作流的 AI 助手、代码助手或内部知识问答系统。

#重度版

  • 混合检索
  • 多层记忆存储
  • 记忆评分与清理机制
  • 多 Agent 共享状态

这类设计更适合复杂代理系统,但维护成本也明显更高。


#小结

一个能长期协作的 Agent,核心不只是“模型更强”,而是它有没有把该记住的东西记住,把不该背着走的噪音丢掉。

如果只记一句话,我会选这个:

短期记忆解决连贯性,长期记忆解决可复用性,结构化记忆解决确定性。

这三件事分不清,Agent 很容易看起来什么都知道,实际一做事就开始忘。分清以后,很多“模型不稳定”的问题,最后都会变成普通的系统设计问题。

常见问题

开发 AI Agent 需要掌握哪些编程语言?
首选 Python 或 TypeScript。Python 是 AI 生态的基石,而 TypeScript 在开发 MCP Server 和网页端交互时效率极高。借助 Cursor 等 AI 原生编辑器,编程门槛已大幅降低。
MCP 协议目前支持哪些模型?
MCP 是开放协议,目前对 Claude 3.5 系列支持最完美。通过 MCP Proxy,GPT-4o 和 Gemini 也可以间接访问 MCP Server 数据源。
AI Agent 会导致程序员失业吗?
不会,但会改变程序员的工作内容。未来的开发者将从“写代码”转向“管理 Agent 团队”,重点在于系统架构设计、复杂逻辑校验和 Agent 的提示词优化。