spring ai 使用mysql管理会话实现会话记忆
在Spring AI中通过MySQL实现会话记忆管理,主要涉及ChatMemory接口的配置和JdbcChatMemoryRepository的集成。以下是完整实现步骤及关键要点:
一、核心实现原理
Spring AI通过ChatMemory接口管理对话历史,结合JdbcChatMemoryRepository实现MySQL持久化存储。其核心流程包括:
- 会话ID标识:通过唯一ID区分不同对话会话。
- 消息存储:将用户输入和模型回复按时间顺序存入数据库。
- 上下文检索:后续请求时自动加载历史消息作为上下文。
二、实现步骤
1. 添加依赖
在pom.xml中引入MySQL驱动和Spring AI会话存储模块:
<dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-model-chat-memory-repository-jdbc</artifactId>
</dependency>
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version>
</dependency>
2. 配置数据源
在application.properties中设置MySQL连接及初始化参数:
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/chat_memory_db?useSSL=false&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=123456# 启用MySQL会话存储
spring.ai.chat.memory.repository.jdbc.initialize-schema=always
spring.ai.chat.memory.repository.jdbc.schema=classpath:schema-mysql.sql
- schema-mysql.sql需包含会话表结构(自动生成或手动创建)。
3. 自定义ChatMemory(可选)
若需扩展存储逻辑(如消息加密、格式转换),可自定义实现:
@Component
@RequiredArgsConstructor
public class CustomJdbcChatMemory implements ChatMemory {private final JdbcTemplate jdbcTemplate;@Overridepublic void add(String conversationId, List<Message> messages) {// 自定义存储逻辑(如消息加密)jdbcTemplate.update("INSERT INTO chat_messages (...) VALUES (?)", messages);}@Overridepublic List<Message> get(String conversationId) {// 自定义查询逻辑(如解密、格式转换)return jdbcTemplate.query("SELECT * FROM chat_messages WHERE conversation_id=?", messages);}
}
4. 配置ChatClient
在Bean中注入JdbcChatMemoryRepository并绑定到ChatClient:
@Configuration
public class ChatConfig {@Beanpublic ChatMemory chatMemory(DataSource dataSource) {return JdbcChatMemoryRepository.builder().dataSource(dataSource).maxMessages(50) // 自定义最大消息数.build();}@Beanpublic ChatClient chatClient(ChatMemory chatMemory) {return ChatClient.builder(openAiChatModel()).defaultAdvisors(MessageChatMemoryAdvisor.builder(chatMemory).build()).build();}
}
5. 控制器实现
通过会话ID管理对话上下文:
@RestController
@RequestMapping("/chat")
public class ChatController {private final ChatClient chatClient;public ChatController(ChatClient chatClient) {this.chatClient = chatClient;}@GetMapping("/memory")public String chat(@RequestParam String userInput, @RequestParam String conversationId) {return chatClient.prompt().user(userInput).advisors(a -> a.param(ChatMemory.CONVERSATION_ID, conversationId)).call().content();}
}
三、数据库表结构示例
自动生成的SPRING_AI_CHAT_MEMORY表结构:
CREATE TABLE `spring_ai_chat_memory` (`id` BIGINT AUTO_INCREMENT PRIMARY KEY,`conversation_id` VARCHAR(36) NOT NULL,`content` TEXT NOT NULL,`type` ENUM('USER', 'ASSISTANT', 'SYSTEM') NOT NULL,`timestamp` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
- conversation_id:会话唯一标识
- type:消息类型(用户/助手/系统)
- content:消息内容。
四、测试与验证
-
首次请求:
GET /chat/memory?userInput=你好&conversationId=001返回模型初始回复,并存储到数据库。
-
后续请求:
GET /chat/memory?userInput=请解释名字含义&conversationId=001模型将结合历史消息生成连贯回复。
-
数据库验证:
查询SPRING_AI_CHAT_MEMORY表,确认消息按时间顺序存储。
五、高级配置
-
消息窗口控制:
通过maxMessages参数限制存储的消息数量,避免内存溢出:spring.ai.chat.memory.repository.jdbc.max-messages=100 -
分布式会话:
结合Redis实现分布式会话ID生成,确保跨服务会话一致性。 -
性能优化:
- 使用批量插入提升写入效率。
- 添加索引加速
conversation_id查询。
六、常见问题
-
依赖冲突:
确保spring-ai-starter-model-chat-memory-repository-jdbc版本与Spring Boot兼容。 -
表结构不匹配:
检查schema-mysql.sql是否与数据库版本兼容,或手动创建表结构。 -
消息丢失:
确认initialize-schema=always配置生效,避免数据库初始化失败。
通过上述步骤,可快速实现基于MySQL的Spring AI会话记忆管理,适用于需要长期保存对话历史的场景(如客服系统、个性化助手)。
