本章介绍2种常见的会话记忆方式jdbc和redis两种记忆方式选择一种去使用就好。一、JDBC的方式1.1 使用的Spring Ai Alibaba的依赖引入到pom.xml文件中!-- JDBC 聊天记忆存储依赖 -- dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-starter-model-chat-memory-repository-jdbc/artifactId /dependency1.2 application.properties添加JDBC的配置# 数据库配置 spring.datasource.driver-class-name: com.mysql.cj.jdbc.Driver spring.datasource.url: jdbc:mysql://localhost:3306/saa_demo?useUnicodetrueserverTimezoneAsia/ShanghaiuseSSLfalse spring.datasource.username: root spring.datasource.password: root1.3 MemoryConfig.javaimport org.springframework.ai.chat.memory.ChatMemory; import org.springframework.ai.chat.memory.MessageWindowChatMemory; import org.springframework.ai.chat.memory.repository.jdbc.JdbcChatMemoryRepository; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; Configuration public class MemoryConfig { /** * 使用mysql的时候再开启并把注解放开 */ Bean public ChatMemory chatMemory(JdbcChatMemoryRepository repository) { // 设置窗口大小为5即每次只取最近5条记录给LLM return MessageWindowChatMemory.builder() .chatMemoryRepository(repository) .maxMessages(5) // 默认保存20条会话记录 .build(); } }1.4 LLMConfig.java这里使用的是ChatClient的方式。1.3已经配置了ChatMemory所以可以直接引入import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatModel; import jakarta.annotation.Resource; import org.springframework.ai.chat.client.ChatClient; import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor; import org.springframework.ai.chat.memory.ChatMemory; import org.springframework.ai.deepseek.DeepSeekChatModel; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; Configuration public class LLMConfig { Autowired private DashScopeChatModel dashScopeChatModel; Autowired private DeepSeekChatModel deepSeekChatModel; Bean public ChatClient dashScopeClient(ChatMemory chatMemory) { return ChatClient.builder(dashScopeChatModel) .defaultAdvisors(MessageChatMemoryAdvisor.builder(chatMemory).build()) // 挂载记忆组件 .build(); } Bean public ChatClient deepSeekClient(ChatMemory chatMemory) { return ChatClient.builder(deepSeekChatModel) .defaultAdvisors(MessageChatMemoryAdvisor.builder(chatMemory).build()) // 挂载记忆组件 .build(); } }1.5 创建ClientMemoryController.java调用方法直接看三、验证结果二、redis的方式2.1 使用的Spring Ai Alibaba的依赖引入到pom.xml文件中!-- Redis 聊天记忆存储依赖 -- dependency groupIdcom.alibaba.cloud.ai/groupId artifactIdspring-ai-alibaba-starter-memory-redis/artifactId /dependency2.2 application.properties添加redis的配置# redis配置 spring.ai.memory.redis.host127.0.0.1 spring.ai.memory.redis.port6379 spring.ai.memory.redis.password spring.ai.memory.redis.database12.3 RedisMemoryConfig.javaSpring Ai Alibaba实现redis的会话记忆有3种方式。这里列出了常用的两种配置方式一种是用jedis一种是用redission。database可不填写默认是0。import com.alibaba.cloud.ai.memory.redis.JedisRedisChatMemoryRepository; import com.alibaba.cloud.ai.memory.redis.RedissonRedisChatMemoryRepository; import org.springframework.ai.chat.memory.ChatMemory; import org.springframework.ai.chat.memory.MessageWindowChatMemory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; Configuration public class RedisMemoryConfig { Bean public ChatMemory redissonChatMemory() { // 配置redisson的chatMemory // RedissonRedisChatMemoryRepository repository RedissonRedisChatMemoryRepository.builder().database(3).build(); // 配置jedis的chatMemory JedisRedisChatMemoryRepository repository JedisRedisChatMemoryRepository.builder().database(1).build(); return MessageWindowChatMemory.builder() .chatMemoryRepository(repository) .maxMessages(5) .build(); } }三、验证结果ClientMemoryController.javaimport jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.springframework.ai.chat.client.ChatClient; import org.springframework.ai.chat.memory.ChatMemory; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import reactor.core.publisher.Flux; /** * 聊天内容记录 * 引入spring AI Alibaba */ RestController RequestMapping(/memory) Slf4j public class ClientMemoryController { Resource private ChatClient dashScopeClient; /** * 测试接口 * param msg * return */ GetMapping(/test) public String test(RequestParam(value msg, defaultValue ClientMemoryController--测试接口) String msg) { return 返回内容 msg; } /** * http://localhost:8080/memory/chat1?userId1msg用简短的语言介绍下自己 */ GetMapping(/chat1) public FluxString chat1(RequestParam(value msg, defaultValue 你是谁) String msg, RequestParam(value userId) String userId) { FluxString content dashScopeClient.prompt().user(msg) .advisors(a- a.param(ChatMemory.CONVERSATION_ID, userId)) .stream() .content(); return content; } }四、结果截图4.1 JDBC截图4.2 redis截图Spring Ai Alibaba配置的redis默认存储前缀是spring_ai_alibaba_chat_memory冒号后面的2是调用请求时的userId的值。个人观点关于会话记忆这块目前接触最多的就是基于内存JDBCredis。后期企业使用的话应该是JDBC和redis会是用的比较多的。刚开始接触的时候的就奇怪为什么不能把所有的会话记录都保存在从记录中最近的几条记录发送给大模型。但是目前所有的实现都是保存最近几条记录。如果要实现保存所有的会话记录可以通过实现org.springframework.ai.chat.client.advisor.api.BaseAdvisor这个接口然后调用before和after这两个方法去获取用户发送的消息和大模型返回的结果来保存到另外的表中。