本课目标
- 理解 LLM 的无状态本质和记忆的实现原理
- 掌握 ChatMemory + MessageChatMemoryAdvisor 的使用
- 选对存储后端:内存 vs 数据库
你跟模型聊了三轮,第四轮它突然不记得你前面说过什么了。这不是 bug——LLM 天生就是金鱼记忆。每一次 API 调用都是独立的新对话,所谓的"记忆"是应用层帮你把历史消息重新塞回去。听起来简单,但选择"塞哪些"和"怎么塞",是对话质量的分水岭。
核心内容
记忆 = 把历史消息拼回去
LLM 每次调用是无状态的。ChatMemory 做的事:存储对话历史,每次新请求时通过 Advisor 把历史消息拼到请求里。从模型视角看,每次都在读"完整的对话记录"——只是这个记录的长度由你控制。
MessageWindowChatMemory:滑动窗口
保留最近 N 条消息,旧的丢弃。简单直接,也是大多数场景的起点。代价:20 条消息的窗口意味着每轮请求都要把这 20 条全部重发——token 成本线性增长。
JdbcChatMemoryRepository:持久化记忆
用户明天回来还能接着聊?存数据库。Spring AI 提供 JDBC 实现,也可以自己接 Redis。持久化的关键不是"能存",是"存什么"——存全量消息会越存越大,存摘要需要定期整理。
工程决策:不要无脑存全量。用户问"帮我查一下今天的天气"这种一次性对话不需要记一辈子。按对话类型、时效性分层管理记忆。
动手练习
先跑一个 MessageWindowChatMemory(窗口 10 条),在第 11 轮问模型"我们第一轮聊了什么"。再改成 JdbcChatMemoryRepository,感受差异。