第1节 MiniChatGPT 导读与 Agent 记忆机制#
当你在使用 ChatGPT、文心一言、豆包等产品时,你可能有过这样的体验:上个月聊过的项目背景,今天它还能接住;你说过"回答简短一些",后续每次对话它都会自动遵守。但同样的,你也经历过它"突然失忆"——上一轮刚提过的内容,在新回话中一开就完全抛在脑后。
你有没有想过这是为什么?
本文作为《手把手带你从零构建MiniChatGPT》专题的开篇,会先回答一个问题:什么是 Agent 记忆系统以及一个完整的 Agent 记忆系统通常由哪几部分组成、各自承担什么角色。在理解清楚这一整体结构脉络好后,再进入短期记忆管理、长期记忆存储以及 MiniChatGPT 的具体实现过程。
最终从零搭建一个类似于 ChatGPT 的只能助手,如图1-2所示。
在进入正式内容前,先把整个专题的脉络过一遍。本系列一共 8 篇文章,按"概念基础 → 工程实现 → MiniChatGPT 实战" 三段式组织,如下表所示:
| 阶段 | 章节 | 主题 | 解决的问题 |
|---|---|---|---|
| 概念基础 | 第1节 | 记忆机制概览 | 为什么要、什么是、怎么分类 |
| 第2节 | 短期记忆管理 | 消息列表超长怎么办 | |
| 第3节 | 长期记忆管理与持久化 | 长期记忆怎么存、怎么分类 | |
| 工程实现 | 第5节 | pgvector 配置安装 | 长期记忆的向量索引怎么搭 |
| 第6节 | 长期记忆检索与遗忘 | 怎么找回、怎么清理 | |
| Mini ChatGPT 实战 | 第4节 | 从零实现 | 不依赖框架手工搭最小可用版 |
| 第7节 | LangGraph 实现 | 用 PostgresSaver + PostgresStore 重构 | |
| 第8节 | create_agent 实现 | 用 LangChain 智能体一行搭建 |
这里推荐两条阅读路径:
-
想理解原理:1 → 2 → 3 → 5 → 6 → 7(按顺序阅读,跳过 4 也能看懂工程细节);
-
想直接看实战:4 → 7 → 8(三部曲对照读,理解"手动 → 框架 → 直接调用智能体"的演进逻辑)。
下面开始进入正文。
1. Agent 中的记忆机制#
对于我们上面提到的,“它怎么会记得"和"它怎么突然又忘了"的背后,其实就是 Agent 记忆机制在默默工作,而这也是整个 ChatGPT 的核心所在。
总的来说,记忆机制要解决的核心问题,是让 Agent 在"跨对话"和"长周期"两个维度上都能延续状态:
-
跨对话:今天聊过的项目背景,明早重新打开对话窗口还能继续;
-
长周期:用户三个月前表达过的偏好(如"回答请简短一些"“主要用 Python”),后续每次回答都能自动遵循。
1.1 从大模型聊天对话说起#
记忆机制是一个让 Agent 能够记住历史交互信息的系统。具体来说,我们希望它能够做到三件事情:① 记住之前的对话内容;② 从用户的反馈中学习;③ 根据用户的偏好调整自身的行为。虽然这三件事听起来好像很简单也很自然,但对于一个实用的 AI Agent 来说却至关重要。
试想一下,如果每次对话结束以后,Agent 对之前发生的事情都一无所知,无论用户告诉过它什么偏好、纠正过它什么错误,下一次对话都只会从头开始滔滔不绝,那这样的体验用户显然是不可接受的。当然,如果是涉及到处理复杂、多轮交互任务时,更是会变得让人抓狂,而这就是 Agent 记忆机制所要解决的问题。
同时,根据记忆的作用范围不同还可以分为两种类型:短期记忆和长期记忆。
接下来,第1.2节 和 第1.3节会分别展开这两种记忆的核心概念。
1.2 会话上下文与 Checkpointer#
短期记忆(Short-term Memory),也被称之为线程作用域记忆(Thread-scoped Memory),它的作用范围仅限定在一次会话(Session)之内, 直白说就是"一次会话内的上下文”。当你你打开一个 ChatGPT 对话窗口时,从第一句到最后一句发生的所有消息,都是短期记忆管的事——它让 Agent 在这次对话里知道"刚才聊到哪儿了"。
在 LangGraph 里管短期记忆主要靠两个东西:State 和 Checkpointer。每次 Agent 执行一步,LangGraph 都会从 Checkpointer 把最新的 State 读出来作为输入,跑完再把新 State 写回去。所以对话中途中断也没关系,下次连上从断点处继续就行,之前的上下文也不会丢失。
不过短期记忆有个绕不开的坎:消息列表会越聊越长,长到超过模型上下文窗口就直接报错。怎么处理这个"无限增长"的消息列表,也是短期记忆的工程核心。本系列「第2节 短期记忆管理:上下文窗口与消息维护」会专门聊这个问题,包括删除、修剪、总结 3 种常用招数。
1.3 跨会话存储与 Namespace 设计#
尽管短期记忆可以记住当前会话中的细节,但是它有个明显的短板:那就是会话一关就清零。当下次再开新窗口时,Agent 不会记得你说过啥——你上周告诉它"主要用 Python",这次它还是会问你用什么语言。
长期记忆(Long-term Memory)的出现是为了解决短期记忆不能处理跨会话信息保留的问题。在长期记忆里,它存的是"用户级"的信息:你的身份、偏好、项目背景、技术栈等。这些数据不属于任何一次具体对话,天然就能跨会话复用。打个比方:短期记忆像"这次会议的笔记本",记完就合上;长期记忆像"公司的客户档案",随时能翻。
从图1-3可以看出,短期记忆实质上就是在当前会话中将之前的所有的上下文信息都输入到LLM中来生成本轮的回答;而长期记忆则是将不会时间、不同会话中的上下文输入到LLM中来生成本轮的回答。
在 LangGraph 中,长期记忆靠 Store 实现,每个用户的记忆放在独立的 Namespace 下。比如用户 A 的偏好放在 (user_a, preferences) 这个命名空间里,下次任何会话来查都能拿到。
当然,存进去只是第一步。怎么高效检索、怎么避免记忆库无限膨胀、怎么让 Agent 在回答时精准调到对的记忆——这些是工程上的硬骨头。后面第3节 长期记忆管理与持久化、第5节 pgvector 配置安装、第6节 长期记忆检索与遗忘三节会逐步展开。
1.4 ChatGPT 如何持久化用户偏好#
举两个你大概率体验过的例子:
-
你第 1 次跟 ChatGPT 说"以后回答简短一些",下次打开新对话它真的就简短了——这就是长期记忆在起作用。
-
你跟 ChatGPT 提过你的职业、城市、家里有几只猫,下次它聊起这些话题你会觉得"哎它怎么知道"——这些也是长期记忆。
如图1-4所示是 ChatGPT 后台给你这个用户保存的"记忆库"内容。你会发现里面既有你明确说过"帮我记住这个"的内容,也有从历史聊天里自动抽出来的关键信息。两者的区别是:前者永远不会忘,后者会随着时间慢慢被覆盖。所以偶尔你会感到"哎它怎么把我那只猫忘了"——其实不是它忘了,是那条记忆被新信息挤掉了。
这就解释了"为什么和 ChatGPT 聊得越久,它越懂你",这背后并不是什么神秘魔法,而是长期记忆在持续沉淀和调用。
如下所示是短期记忆与长期记忆的对比结果:
| 维度 | 短期记忆 | 长期记忆 |
|---|---|---|
| 作用范围 | 单次会话(Session / Thread) | 跨会话,按用户或命名空间隔离 |
| LangGraph 实现 | State + Checkpointer | Store(如 PostgresStore) |
| 典型后端 | 内存 / PostgreSQL | PostgreSQL + pgvector |
| 检索方式 | 线性遍历当前消息列表 | 按命名空间查找 + 向量语义检索 |
| 数据形态 | Message 对象列表(带 role 字段) | 自由结构(通常为 dict,含文本与元信息) |
| 失效时机 | 会话结束或超时清理 | 默认不失效,靠遗忘策略主动清理 |
| 典型数据量 | 单会话内几十~几百条消息 | 单用户几十~几千条记忆条目 |
| 主要工程关注点 | 上下文窗口、压缩、总结 | 检索准确性、容量上限、过期与遗忘 |
一句话总结,短期记忆用于支持单次会话内的多轮对话,而长期记忆则用于跨会话持久化存储用户或应用级别的数据。
1.5 小结#
整节聊下来其实就两件事:
-
为什么:Agent 默认是"金鱼脑"——只记得上一轮。要让助手真正可用,记忆机制跑不掉。
-
是什么:分两类——短期记忆(Checkpointer 管)和长期记忆(Store 管)。
在下一节 「Agent 短期记忆管理实战:上下文窗口限制、消息列表维护与压缩修剪策略详解」 内容中,我们将会介绍当短期记忆的消息列表越聊越长,超出上下文窗口时该怎么办的处理方法。
引用#
[1] https://docs.langchain.com/oss/python/langgraph/add-memory