package com.xly.config; import dev.langchain4j.data.message.ChatMessage; import dev.langchain4j.data.message.ChatMessageDeserializer; import dev.langchain4j.data.message.ChatMessageSerializer; import dev.langchain4j.store.memory.chat.ChatMemoryStore; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Component; import java.time.Duration; import java.util.ArrayList; import java.util.List; /** * Redis 持久化的 ChatMemoryStore —— 会话记忆按 conversationId 存到 Redis,重启/换实例不丢, * 也让「重登录后接回上一次会话」成立(会话状态按稳定身份+conversationId 存,而非按 token)。 * *

键:{@code chat:mem:{conversationId}};值:LangChain4j 序列化后的消息 JSON。30 天 TTL。 */ @Component public class RedisChatMemoryStore implements ChatMemoryStore { private static final String PREFIX = "chat:mem:"; private static final Duration TTL = Duration.ofDays(30); private final StringRedisTemplate redis; public RedisChatMemoryStore(StringRedisTemplate redis) { this.redis = redis; } @Override public List getMessages(Object memoryId) { String json = redis.opsForValue().get(PREFIX + memoryId); if (json == null || json.isBlank()) { return new ArrayList<>(); } return ChatMessageDeserializer.messagesFromJson(json); } @Override public void updateMessages(Object memoryId, List messages) { redis.opsForValue().set(PREFIX + memoryId, ChatMessageSerializer.messagesToJson(messages), TTL); } @Override public void deleteMessages(Object memoryId) { redis.delete(PREFIX + memoryId); } }