大语言模型有一个很容易被忽略的问题:
它本身并没有真正意义上的长期记忆。
你和模型聊了很多轮,看起来它好像“记得”前面发生过什么,但很多时候,这并不是因为模型真的把这些事情存进了脑子里。
更准确地说,它只是因为:
前面的对话还在当前上下文里。
比如:
用户:我叫小明。
模型:你好,小明。
用户:我叫什么?
模型能回答“小明”,是因为前面的聊天记录还被一起发送给模型。
如果把前面的上下文删掉,只给它:
用户:我叫什么?
它通常就不知道了。
所以如果我们希望 Agent 可以跨任务、跨会话,甚至几天、几个月后还记得重要信息,就需要引入一个独立的系统:
Memory。
什么是 Memory
在 Agent 中,Memory 可以理解成:
将过去的信息保存下来,并在未来需要时重新取回。
最简单的流程是:
过去的信息
↓
Memory Store
↓
保存
↓
未来任务
↓
Retrieve Memory
↓
加入 Context
↓
LLM
所以 Memory 并不是模型参数的一部分。
它通常是模型外部的一个系统。
你可以把大模型理解成“大脑”,而 Memory 更像是:
- 笔记本
- 日志
- 数据库
- 用户档案
- 历史经验库
模型需要的时候,再去查询这些内容。
为什么 Agent 需要 Memory
普通 Chatbot 可以不需要复杂的 Memory。
因为它的任务通常只是:
用户提问
↓
模型回答
但是 Agent 往往需要执行持续时间更长的任务。
比如一个个人助理 Agent:
用户:我以后订酒店尽量选离地铁近的。
两个月后:
用户:帮我规划一下上海旅行。
如果 Agent 有 Memory,它就可以记得:
用户偏好:
住宿优先靠近地铁
然后规划酒店时自动考虑这个条件。
再比如一个 Coding Agent。
第一次修 Bug 时,它发现:
这个项目使用 pnpm
不能使用 npm install
如果下一次又进入这个项目,它可以直接读取之前保存的 Memory,而不是重新踩一次坑。
所以 Memory 的价值在于:
让 Agent 可以积累状态、偏好和经验。
Memory 和 Context 有什么区别
这是 Agent 中非常容易混淆的概念。
Context 是:
当前这一次模型调用时,真正放进 Prompt 里的内容。
例如:
System Prompt
Conversation History
Tool Results
Retrieved Documents
Memory
User Query
这些内容最终一起进入模型。
而 Memory 是:
存储在模型上下文之外的信息。
所以两者的关系更像:
Memory Store
↓
Retrieve
↓
Context
↓
LLM
Memory 不等于 Context。
更准确地说:
Memory 是信息存储机制,Context 是模型当前能够看到的信息。
Memory 只有被取出来以后,才真正进入模型的 Context。
为什么不能直接把所有聊天记录都塞进去
既然模型可以直接读取历史聊天,那为什么还需要 Memory?
因为随着对话越来越长:
第 1 轮
第 2 轮
第 3 轮
...
第 5000 轮
你不可能永远把所有历史记录都发送给模型。
主要有几个问题。
第一是:
Context Window 有限制。
即使现在的大模型上下文已经很长,也不代表应该把所有东西全部塞进去。
第二是:
成本。
每一次调用都重复发送几万甚至几十万 Token,会非常浪费。
第三是:
噪声。
上下文越长,不一定效果越好。
大量无关信息可能反而影响模型判断。
所以真正的 Agent Memory 要解决的问题不是:
怎么保存全部内容。
而是:
什么东西值得记住,什么时候应该取出来。
这两个问题分别叫:
Memory Write
和:
Memory Retrieval。
Memory Write:什么应该被记住
并不是用户说的每一句话都应该存进 Memory。
例如:
用户:哈哈
这通常没必要长期保存。
又比如:
用户:我今天中午吃了牛肉面。
对于一个编程 Agent 来说,这基本没有价值。
所以 Memory 系统通常需要一个判断:
New Information
↓
Important?
↓
Yes → Store
No → Ignore
例如:
用户:以后代码示例默认使用 TypeScript。
这很可能值得保存。
因为它代表一个长期偏好。
再比如:
用户:这个项目的数据库是 PostgreSQL。
对于项目 Agent 来说,也值得保存。
因此一个简单的 Memory Write 流程可能是:
Conversation
↓
Memory Extractor
↓
判断重要信息
↓
Structured Memory
↓
Database
例如原始对话:
我比较喜欢 React,不太想用 Vue。
Memory Extractor 可能保存成:
{
"type": "preference",
"key": "frontend_framework",
"value": "React preferred over Vue"
}
这样比直接把整段聊天保存下来更加容易管理。
Memory Retrieval:什么时候应该回忆
存下来只是第一步。
更困难的问题其实是:
什么时候把 Memory 重新取出来。
假设 Memory 中有:
用户喜欢 React
用户住在深圳
用户喜欢喝咖啡
用户的项目使用 PostgreSQL
用户偏好简洁回答
现在用户问:
帮我设计一下这个 Web 项目的前端架构。
这时候真正相关的 Memory 可能只有:
用户喜欢 React
而:
用户喜欢喝咖啡
完全没必要放进去。
所以 Memory Retrieval 本质上也是一个检索问题。
可以是:
User Query
↓
Embedding
↓
Search Memory
↓
Top K Relevant Memories
↓
Context
例如:
Query:
Web 前端架构
Memory A:
用户偏好 React
Similarity = 0.88
Memory B:
用户喜欢咖啡
Similarity = 0.07
最终只取 Memory A。
所以从技术上看:
Memory Retrieval 和 RAG 非常像。
Memory 和 RAG 有什么区别
两者的实现可能很像,甚至都可能使用:
Embedding
+
Vector Database
但它们解决的问题不同。
RAG 通常在检索:
外部知识。
例如:
- 公司文档
- Wiki
- 产品手册
- 网页
- 数据库
而 Memory 通常在检索:
Agent 自己过去积累的信息。
例如:
- 用户偏好
- 历史任务
- 过去的决定
- 之前遇到的问题
- Agent 的执行经验
可以简单理解为:
RAG:
“世界上有什么知识?”
Memory:
“我们之前发生过什么?”
当然,工程实现上两者可能共享同一套检索基础设施。
Memory 的常见分类
Agent Memory 并不是只有一种。
比较常见的分类包括:
- Short-Term Memory
- Long-Term Memory
- Episodic Memory
- Semantic Memory
- Procedural Memory
它们的作用不同。
Short-Term Memory
Short-Term Memory,短期记忆。
最常见的形式就是:
Conversation History。
例如:
User: 帮我分析这个 Bug。
Assistant: 把错误日志发给我。
User: Error: connection refused
模型必须记得前面的:
帮我分析这个 Bug
否则第二句话单独看就不知道上下文。
因此短期 Memory 通常存在:
Context Window
里面。
可以理解成模型的“工作记忆”。
Long-Term Memory
Long-Term Memory,长期记忆。
它需要跨会话存在。
例如:
用户习惯:
默认使用 Python 3.12
项目配置:
包管理器使用 uv
偏好:
回答尽量简洁
这些信息可能几个月后仍然有用。
所以通常会保存在外部存储中,比如:
SQL Database
Vector Database
Key-Value Store
Document Store
未来根据需要重新加载。
Episodic Memory
Episodic Memory 可以翻译成:
情景记忆。
它记录的是:
过去发生过什么。
例如:
2026-09-01
用户让我部署一个 API。
第一次使用 Docker 部署失败。
原因是端口被占用。
最终修改端口后成功。
这就是一段 Episode。
以后如果遇到类似问题,Agent 可以回忆:
之前遇到过端口冲突。
所以 Episodic Memory 更像:
经历。
Semantic Memory
Semantic Memory,语义记忆。
它保存的不是某一次具体经历,而是:
从经历中提炼出来的事实。
例如 Episodic Memory 是:
上次部署时 pnpm-lock.yaml 导致 npm install 依赖冲突。
经过总结以后,Semantic Memory 可能变成:
该项目必须使用 pnpm。
这就是一个稳定的事实。
因此:
Episodic Memory
↓
总结
↓
Semantic Memory
可以理解成:
经历逐渐变成知识。
Procedural Memory
Procedural Memory 可以理解为:
流程记忆。
它记录的是:
某件事情应该怎么做。
例如 Agent 学到:
部署当前项目时:
1. pnpm install
2. pnpm build
3. docker compose up -d
4. 检查 /health
以后再部署时,不需要重新规划整个流程。
这就很像人的:
技能记忆。
例如人不会每次骑自行车之前,都重新思考“怎么保持平衡”。
Agent 也可以把成功流程沉淀成 Procedural Memory。
Memory Consolidation
随着 Agent 长期运行,Memory 会越来越多。
例如:
Memory 1
Memory 2
Memory 3
...
Memory 100000
如果无限增长,就会出现很多问题:
- 重复
- 冲突
- 过期
- 检索困难
- 成本增加
所以成熟的 Memory 系统通常还需要:
Memory Consolidation。
也就是记忆整理。
例如:
用户喜欢 React
用户项目主要使用 React
用户倾向 React 而不是 Vue
三个 Memory 可以合并成:
用户前端开发偏好 React。
这就是 Consolidation。
Memory Update
Memory 并不是一旦写入就永远不变。
比如以前:
用户喜欢 Vue。
后来用户说:
以后主要用 React。
如果系统只是不断追加:
Memory 1: 喜欢 Vue
Memory 2: 喜欢 React
模型以后就不知道该相信哪个。
因此 Memory 系统需要:
Insert
Update
Delete
Merge
而不是只有:
Append
一个更合理的逻辑是:
New Memory
↓
Search Existing Memory
↓
冲突吗?
↓
更新旧 Memory
例如:
frontend_preference = Vue
更新为:
frontend_preference = React
Memory Decay
有些记忆随着时间推移会越来越不重要。
比如:
用户今天下午三点有会议。
当天非常重要。
一个月以后基本没有价值。
所以一些 Memory 系统会设计:
Decay,衰减机制。
例如每条 Memory 都有:
Importance
Recency
Frequency
检索分数可以设计成:
Score =
Semantic Similarity
+ Importance
+ Recency
+ Frequency
也就是说:
- 越相关
- 越重要
- 越新
- 越常被使用
的 Memory 越容易被取出来。
这比单纯做向量搜索更合理。
Memory Scoring
假设现在有三条 Memory:
A:用户默认使用 TypeScript
B:用户三个月前喝过拿铁
C:当前项目使用 React
用户问:
帮我写一个前端组件。
系统可以计算:
A:
Similarity = 0.82
Importance = 0.8
B:
Similarity = 0.04
Importance = 0.1
C:
Similarity = 0.91
Importance = 0.9
最终检索:
A + C
而不是 B。
这就是为什么一个好的 Memory 系统往往不是:
Vector Search
这么简单。
Memory 的一个完整流程
一个比较完整的 Agent Memory 系统可以设计成:
User Message
↓
LLM / Memory Extractor
↓
判断是否值得保存
↓
Memory Store
↓
Deduplication
↓
Conflict Resolution
↓
Consolidation
当新的任务到来时:
User Query
↓
Memory Query
↓
Semantic Search
↓
Metadata Filter
↓
Memory Ranking
↓
Top K Memory
↓
Context
↓
LLM
任务执行完以后:
Result
↓
Reflection
↓
提取经验
↓
写入 Memory
这样就形成了一个真正的记忆循环:
Experience
→ Store
→ Retrieve
→ Act
→ Reflect
→ Update
Memory 和 Agent Loop
Memory 在 Agent Loop 中非常重要。
一个 Agent 的循环可能是:
Observe
↓
Retrieve Memory
↓
Reason
↓
Act
↓
Observe Result
↓
Update Memory
↓
Repeat
这里 Memory 让 Agent 不需要每一轮都从零开始。
例如 Agent 调用了某个 API:
API 返回 429
它可以记录:
当前 API 已触发 Rate Limit
下一次调用前等待
下一轮 Reasoning 时就可以利用这条信息。
所以 Memory 不只是“记住用户名字”。
它还可以维护:
Agent 自身的执行状态。
Working Memory
在复杂 Agent 中,还有一个很重要的概念:
Working Memory。
它保存的是:
当前任务执行过程中暂时需要的信息。
比如 Agent 正在做一个调研任务:
目标:
对比 A、B、C 三家公司
执行过程中可能产生:
A 公司数据:已找到
B 公司数据:缺少营收
C 公司数据:已找到
这些信息并不一定值得长期保存。
但是在当前任务结束之前必须保留。
所以:
Working Memory
通常生命周期等于:
一个 Task / Session
任务结束后可以删除。
Memory 不应该什么都记
这是 Memory 系统里非常重要的一点。
如果什么都保存:
用户说过的每句话
每次 Tool Call
每个 Token
每个中间状态
最后 Memory 会变成一个巨大的垃圾场。
于是 Retrieval 质量反而下降。
真正好的 Memory 系统应该具备:
Selective Memory。
也就是只记:
- 对未来有价值的信息
- 稳定偏好
- 重要事实
- 关键决策
- 成功经验
- 失败经验
- 长期状态
而不是所有内容。
Memory 的核心难点
很多人第一次做 Agent Memory,会以为最大的难点是:
用什么数据库。
其实数据库反而不是最难的问题。
Memory 真正困难的是:
该不该记
Memory Write Policy。
怎么表示
存原始文本还是结构化数据?
例如:
用户喜欢 React
还是:
{
"type": "preference",
"framework": "React"
}
什么时候取
Memory Retrieval。
取哪几条
Memory Ranking。
出现冲突怎么办
Conflict Resolution。
过期怎么办
Memory Decay。
太多怎么办
Consolidation。
所以一个真正成熟的 Memory 系统,本质上其实是在做:
信息生命周期管理。
一个最简单的 Memory 实现
如果自己实现一个 Demo,可以从非常简单的结构开始:
Conversation
↓
LLM Extract Memory
↓
Embedding
↓
Vector DB
例如用户说:
以后写前端默认使用 React。
模型提取:
Preference:
Frontend framework = React
然后做 Embedding 存进 Vector Database。
下一次用户问:
帮我做一个后台管理页面。
先对 Query 做 Embedding:
后台管理页面
↓
Vector Search
检索到:
Frontend framework = React
然后构造 Prompt:
用户偏好:
默认使用 React。
任务:
帮我设计后台管理页面。
最后交给 LLM。
这已经是一个最基础的 Long-Term Memory 系统。
更成熟的 Memory 系统
如果继续往下做,可以逐步加入:
Memory Extraction
↓
Structured Memory
↓
Embedding
↓
Semantic Search
↓
Metadata Filter
↓
Importance Score
↓
Recency Score
↓
Deduplication
↓
Conflict Resolution
↓
Consolidation
↓
Decay
再进一步,还可以加入:
Reflection
让 Agent 主动总结经验。
例如一次任务结束以后:
Task Result
↓
Reflection
模型总结:
这次失败的主要原因是 API 返回格式发生变化。
以后调用该 API 时应该先验证 Schema。
然后将这个经验保存。
这样 Agent 就不仅仅是在:
记忆。
而是在:
学习。
Memory 的本质
理解 Agent Memory 最简单的一句话是:
Memory 就是让 Agent 可以把过去的信息带到未来。
但真正的 Memory 系统并不是简单保存聊天记录。
完整的问题是:
什么值得记
↓
怎么存
↓
存多久
↓
什么时候取
↓
取哪一些
↓
发生冲突怎么办
↓
什么时候删除
所以可以把 Memory 的完整生命周期压缩成:
Write
→ Store
→ Retrieve
→ Use
→ Update
→ Forget
如果再和 Agent Loop 放在一起:
Observe
↓
Retrieve Memory
↓
Reason
↓
Act
↓
Reflect
↓
Write Memory
↓
Next Loop
这时候 Agent 才真正从一个:
每次都重新开始的模型
逐渐变成一个:
可以积累经验的系统。