```html 记忆系统六类型:缓冲窗口Token摘要长期语义 记忆系统六类型:缓冲窗口Token摘要长期语义
为什么同一个AI助手,上一轮刚聊过的事,下一轮就忘得一干二净?答案不在模型本身——每次调用都是全新的,模型什么都不记得,是应用层必须把之前的消息重新发过去。
要让AI变成Agent,光有模型不够。Agent更像一个编排器:模型、外部工具的动作、再加上记忆,三样拼在一起。记忆存的就是"我之前问过什么、它答了什么"这一组问答。麻烦在于,对话不能无限往里塞,存多少、留多久,得有个说法。
围绕这个限制,记忆被拆成了几种类型,逐个看。
1. 缓冲记忆:全存,但会一直长
每一轮对话都完整保留,可以放在内存(RAM)里,也可以落到SQLite3、Postgres这类持久化存储。每次调用都把整段历史发给模型。新开一个对话,会有一个不同的标识符。
问题出在"整段"上:历史越长,消耗的token越多,上下文上限也会被顶到。输出照样能拿到,代价是成本和容量。代码里用InMemorySaver()把对话存进RAM,能存多少取决于RAM本身。
2. 窗口记忆:只留头尾
只保留固定数量的消息,比如第一条加上最后N条。Langchain里有个中间件机制,请求要先穿过它才能到模型,在中间件里可以配置成删掉中间消息、只留首尾。
这种方案适合"最近的对话比早前的更重要"的场景,代价是中间那段被彻底丢掉。
3. Token记忆:按预算裁剪
思路和窗口记忆接近,只是把"条数"换成"token数",比如设成2000个token,超过就不再存,旧数据被移除。token的定义因模型和框架而异。
裁剪有个细节:按字数硬切可能把一个词从中间截断,剩下半个词没有意义。所以要从句子开头取起,这件事由trim_messages()函数处理。超出预算的部分会完全丢失,这是它的短板。
4. 摘要记忆:用便宜模型换事实留存
假设记忆里只能放4轮对话,最早的两轮马上要被挤掉。那就提前把这段压成一份摘要存着,数据删了,摘要还在。摘要可以交给便宜的模型来生成,控制成本,具体由SummarizationMiddleware()完成。
5. 长期记忆:Agent自己决定存什么
存什么、存在哪,由Agent自己判断。它跨的是同一个用户的多次对话,而不是单次会话。
6. 语义记忆:按意思检索
把整段对话压成一个点,思路类似RAG,存进向量数据库。检索时按语义相似度找长期事实,需要embedding模型支持。
两个容易混淆的概念
Checkpointer负责每轮结束后保存对话,InMemorySaver是内存版,SqliteSaver或数据库版可以持久化;thread_id相当于对话的档案号,同一个id接着聊,换新id就是重新开始。Store和checkpointer不是一回事:checkpointer管一次对话,Store管跨对话的用户长期事实。
记忆工具里的user_id来自应用自身的上下文,不是模型生成的,这样用户之间读不到彼此的记忆。
回到开头那个问题:模型不需要自带记忆,记忆是应用层的事。选哪种方案,取决于你更怕丢事实,还是更怕烧token。
热门跟贴