基于MySQL的AI对话持久化简单实现——AI 超级智能体—— 3 - AI 应用开发

依赖

xml
复制代码
<dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-spring-boot3-starter</artifactId> <version>3.5.12</version> </dependency> <dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> </dependency>

数据表

sql
复制代码
DROP TABLE IF EXISTS `chat_message`; CREATE TABLE IF NOT EXISTS `chat_message` ( `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID', `conversation_id` varchar(64) NOT NULL COMMENT '会话ID', `message_type` varchar(20) NOT NULL COMMENT '消息类型', `content` text NOT NULL COMMENT '消息内容', `metadata` text NOT NULL COMMENT '元数据', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', `is_delete` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否删除 0-未删除 1-已删除', PRIMARY KEY (`id`), INDEX `idx_conversation_id` (`conversation_id`) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COMMENT ='聊天消息表';

实体类 ChatMessage

java
复制代码
@Data @Builder @AllArgsConstructor @NoArgsConstructor @TableName(value = "`chat_message`", autoResultMap = true) public class ChatMessage implements Serializable { @Serial @TableField(exist = false) private static final long serialVersionUID = 1L; @TableId(value = "id", type = IdType.ASSIGN_ID) private Long id; /** * 会话ID */ @TableField("conversation_id") private String conversationId; /** * 消息类型 */ @TableField("message_type") private MessageType messageType; /** * 消息内容 */ @TableField("content") private String content; /** * 元数据 */ @TableField(value = "metadata", typeHandler = JacksonTypeHandler.class) private Map<String, Object> metadata; /** * 创建时间 */ @TableField(value = "`create_time`", fill = FieldFill.INSERT) private Date createTime; /** * 更新时间 */ @Version @TableField(value = "`update_time`", fill = FieldFill.INSERT_UPDATE) private Date updateTime; /** * 是否删除 0-未删除 1-已删除 */ @TableField("`is_delete`") @TableLogic private boolean isDelete; }

ChatMessage <=> Message 转换

java
复制代码
public class MessageConverter { /** * 将 Message 转换为 ChatMessage */ public static ChatMessage toChatMessage(Message message, String conversationId) { return ChatMessage.builder() .conversationId(conversationId) .messageType(message.getMessageType()) .content(message.getText()) .metadata(message.getMetadata()) .build(); } /** * 将 ChatMessage 转换为 Message */ public static Message toMessage(ChatMessage chatMessage) { MessageType messageType = chatMessage.getMessageType(); String text = chatMessage.getContent(); Map<String, Object> metadata = chatMessage.getMetadata(); return switch (messageType) { case USER -> new UserMessage(text); case ASSISTANT -> new AssistantMessage(text, metadata); case SYSTEM -> new SystemMessage(text); case TOOL -> new ToolResponseMessage(List.of(), metadata); }; } }

Mybatis-Plus 相关类

java
复制代码
@Mapper public interface ChatMessageMapper extends BaseMapper<ChatMessage> { } @Component public class ChatMessageRepository extends CrudRepository<ChatMessageMapper, ChatMessage> { }

核心 ChatMemory 实现

java
复制代码
@Component @RequiredArgsConstructor public class DatabaseChatMemory implements ChatMemory { private final ChatMessageRepository chatMessageRepository; @Override public void add(String conversationId, List<Message> messages) { List<ChatMessage> chatMessages = messages.stream() .map(message -> MessageConverter.toChatMessage(message, conversationId)) .collect(Collectors.toList()); chatMessageRepository.saveBatch(chatMessages, chatMessages.size()); } @Override public List<Message> get(String conversationId, int lastN) { LambdaQueryWrapper<ChatMessage> queryWrapper = new LambdaQueryWrapper<>(); // 查询最近的 lastN 条消息 queryWrapper.eq(ChatMessage::getConversationId, conversationId) .orderByDesc(ChatMessage::getCreateTime) .last(lastN > 0, "LIMIT " + lastN); List<ChatMessage> chatMessages = chatMessageRepository.list(queryWrapper); // 按照时间顺序返回 if (!chatMessages.isEmpty()) { Collections.reverse(chatMessages); } return chatMessages .stream() .map(MessageConverter::toMessage) .collect(Collectors.toList()); } @Override public void clear(String conversationId) { LambdaQueryWrapper<ChatMessage> queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(ChatMessage::getConversationId, conversationId); chatMessageRepository.remove(queryWrapper); } }

使用

注入 DatabaseChatMemory

java
复制代码
public EcApp(ChatModel dashscopeChatModel, DatabaseChatMemory databaseChatMemory) { String memoryPath = System.getProperty("user.dir") + "/tmp/chat-memory"; // ChatMemory chatMemory = new InMemoryChatMemory(); // ChatMemory chatMemory = new FileBasedChatMemory(memoryPath); chatClient = ChatClient.builder(dashscopeChatModel) .defaultSystem(SYSTEM_PROMPT) .defaultAdvisors( new MessageChatMemoryAdvisor(databaseChatMemory), new CustomLoggerAdvisor(), new ReReadingAdvisor() ) .build(); }
0个评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
下载 APP