Java AI转型实战(四):给AI加上记忆,实现多轮对话
从“金鱼记忆”到“过目不忘”让AI记住你01 引子在上一篇实战三中我们已经成功实现了Spring Boot与大模型的第一次对话。但很快我就发现了一个问题每次对话都是独立的。我问“你叫什么名字”AI回答了。再问“你刚才说你叫什么”——AI一脸懵“你没有告诉我哦。”这就像你和一个金鱼记忆的人聊天每次都要重新自我介绍。显然这在真实的业务场景中是没法用的。所以这一篇的目标很明确让AI拥有记忆能力记住对话上下文。02 技术选型Spring AI 的 ChatMemorySpring AI 提供了完整的对话记忆方案核心组件有三个组件作用类比ChatMemory存储对话历史一个“记忆盒子”ChatMemoryRepository底层存储引擎内存/数据库“盒子”里具体的“抽屉”MessageChatMemoryAdvisor自动在每次请求前注入历史消息一个“自动提醒器”简单理解ChatMemory负责存ChatMemoryRepository负责怎么存MessageChatMemoryAdvisor负责每次聊天前把记忆翻出来给AI看。03 代码实现Step 1在pom.xml中添加依赖你的项目已经包含了spring-ai-alibaba-starter-dashscope它已经包含了多轮对话所需的模块不需要额外加依赖。只要确认版本是1.1.2.2即可。Step 2创建 ChatMemory 配置类在com.example.myai.config包下新建ChatMemoryConfig.java关键参数说明maxMessages(10)保留最近10条消息超出后自动丢弃最早的。设得太少记不住太久远的内容设得太多浪费Token。InMemoryChatMemoryRepository项目重启后记忆丢失适合开发测试。Step 3改造 Service 层修改AIService.java两个关键点defaultAdvisors(MessageChatMemoryAdvisor.builder(chatMemory).build())在构建ChatClient时全局注入记忆功能param(chat_memory_conversation_id, conversationId)指定当前会话ID同一ID共享记忆不同ID记忆隔离Step 4Controller 加一个参数修改AIController.javaconversationId参数设置了默认值default方便测试时不用每次都传。04 验证效果第一步告诉AI你的名字请求第二步考验AI的记忆请求✅ 验证通过AI成功记住了上一轮的信息。第三步换个会话ID请求✅ 不同会话之间记忆完全隔离。05 踩坑记录坑一MessageChatMemoryAdvisor 不能直接 new在旧版本的Spring AI中可以这样写java// ❌ 旧写法在新版本中已废弃 .defaultAdvisors(new MessageChatMemoryAdvisor(chatMemory))但在你的版本Spring AI 1.1.2中需要使用Builder模式java// ✅ 新写法 .defaultAdvisors(MessageChatMemoryAdvisor.builder(chatMemory).build())坑二CHAT_MEMORY_CONVERSATION_ID_KEY 常量名变化有些文档中写的是java// ❌ 可能找不到这个常量 .param(MessageChatMemoryAdvisor.CHAT_MEMORY_CONVERSATION_ID_KEY, conversationId)直接使用字符串字面量最稳定不需要依赖具体常量名java// ✅ 推荐直接使用字符串 .param(chat_memory_conversation_id, conversationId)坑三BOM 版本管理问题你之前踩过的坑如果你在dependencyManagement中通过 BOM 管理版本但 BOM 本身下载失败会导致版本解析失败Maven 报错。解决方案直接在dependencies中显式指定版本号。06 下期预告目前请求还是同步等待的。当AI在思考时浏览器页面一直在转圈好几秒后才一次性返回全部结果。这体验不够好。所以下一篇我计划引入SSE流式输出——让AI的回复一个字一个字地蹦出来实现类似ChatGPT的打字机效果用户不用盯着空白等好几秒。 我是超超不吵吵10年Java全栈正在转型AI应用开发。每周一篇实战笔记不贩卖焦虑只分享能落地的技术。全网同名欢迎关注。