AI Agent实战:Spring AI Alibaba短时记忆系统,赋予对话连续性
让Java开发者像写Spring Boot一样开发AI应用——第二阶段第三篇
前两篇,我们让Agent学会了“动手”——从单个工具到多工具协同,Agent已经能调用外部API、查询天气、推荐景点。
但还有一个致命问题:Agent记不住。
你刚告诉它“我叫张三”,下一轮对话它就问“你叫什么名字?”;你刚说完“我在杭州”,它转头就问“你在哪个城市?”
这就像一个患有严重失忆症的实习生——能力很强,但每次对话都要从头认识你。
今天,我们给Agent装上“大脑皮层”——短时记忆系统。
📌 本文是第二阶段“核心能力实战篇”的第三篇。前两篇我们解决了“动手”问题,今天解决“记忆”问题——让Agent从“一次性对话”走向“持续对话”。
在LLM的底层原理中,模型本身是无状态(Stateless)的。每一次API调用对模型来说都是全新的开始,它并不知道你3秒前问了什么。
课堂演示:无状态对话的问题
所谓的“多轮对话”,本质上是在每次请求时,将历史消息列表连同当前用户输入一起打包发送给模型:
💡 大模型就像一个“健忘的天才”——你问什么他都能答,但你刚说完他就忘了。所谓的“多轮对话”,全靠应用程序在背后帮他把历史消息重新塞回去。
在Spring AI Alibaba中,记忆体系分为三个层次:
💡 今天聚焦短时记忆——它是实现多轮对话连贯性的基础。长时记忆和用户画像将在后续课程中专门讲解。
三者关系示意图:
在使用之前,先区分两个容易混淆的概念:
💡 ChatMemory是“模型正在用的上下文”,ChatHistory是“完整的聊天记录归档” 。两者是不同的概念——前者用于推理,后者用于审计或分析。
短时记忆面临的核心矛盾:
对话越长,上下文越大
上下文越大,越可能撑爆模型的上下文窗口
Token越多,调用成本越高
解决方案:滑动窗口(Message Window)
MessageWindowChatMemory维护一个最大指定大小的消息窗口。当消息数量超过最大值时,会删除较旧的消息,同时保留系统消息。
窗口大小的权衡:
在Spring AI Alibaba中,短时记忆有两种核心实现:
MemorySaver是会话级缓存,它的粒度是threadId,不是userId。
MemorySaver的特点:
💡 MemorySaver就像白板上的笔记——写上去快、看得清楚,但一擦就没了。
RedisSaver将Agent状态持久化到Redis中:
RedisSaver的优势:
实现原理:
threadId是会话的唯一标识符,用于实现对话状态的隔离和持久化。
threadId的两大作用:
作为多轮对话上下文管理器的键(key)
实现不同会话的状态隔离
💡 threadId就像聊天窗口的ID——每个聊天窗口都有自己的threadId,不同窗口的对话互不干扰。
关键理解:threadId的粒度是会话,不是用户。同一个用户可以拥有多个threadId(多个会话),不同用户也可以拥有各自的threadId。
使用threadId的关键要点:
threadId用于关联同一对话的上下文
无需每次执行都生成新的threadId(否则无法保留多轮对话状态)
核心原则:不同threadId的对话互不干扰。
测试验证:
Step 1:添加依赖
Step 2:配置RedisSaver
测试持久化:
💡 课堂演示:在课堂上演示“重启服务后记忆仍然存在”——让学员亲眼见证RedisSaver的持久化能力。
⚠️ 生产环境绝对不要用MemorySaver——服务重启、滚动更新都会导致用户对话历史丢失,用户体验极差。
任务:实现一个支持多用户、多会话的聊天Agent
要求:
基于RedisSaver实现对话记忆的持久化
支持多用户(不同userId)的会话隔离
支持同一用户的多个会话(通过不同的threadId)
实现以下API:
POST /chat :发送消息(需传入userId和sessionId)
GET /history :查看某个会话的历史
DELETE /clear :清除某个会话
验收标准:
大模型是无状态的——每次API调用都是全新的开始,需要应用程序管理对话历史
记忆体系分三层——短时记忆(今天)、长时记忆(后续)、用户画像(后续)
两种实现方式——MemorySaver(内存,适合开发)和RedisSaver(Redis,适合生产)
threadId是会话的身份证——不同threadId的对话互不干扰,实现多会话隔离
滑动窗口控制成本——默认保留最近20条消息,可根据场景调整
生产环境用RedisSaver——服务重启不丢数据,多实例共享状态
📌 本文是第二阶段“核心能力实战篇”的第三篇。前两篇我们让Agent学会了“动手”,今天让Agent学会了“记忆”——从“一次性对话”走向“持续对话”。下一篇,我们将进入长时记忆与RAG(检索增强生成),让Agent能够访问私有知识库,回答专属问题。
有任何问题,欢迎在评论区留言交流!
作者:Java老兵搞AI,专注Java生态下的AI应用开发
如果觉得有用,点个「在看」支持一下吧,下期见!