langchain4j集成QWen、Redis聊天记忆持久化
langchain4j实现聊天记忆默认是基于进程内存的方式,InMemoryChatMemoryStore是具体的实现了,是将聊天记录到一个map中,如果用户大的话,会造成内存溢出以及数据安全问题。位了解决这个问题 langchain4提供了ChatMemoryStore接口,让开发者可以灵活的选择存储策略,常用的可以使用mysql、redis、mongodb等,本文以redis为例,集成百炼平台通义千问实现大模型聊天记忆持久化。
一、引入依赖
具体详情可参考官网
https://docs.langchain4j.dev/integrations/language-models/dashscope
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-data-redis', version: '3.4.0'// langchain4j AiService整合spring bootimplementation group: 'dev.langchain4j', name: 'langchain4j-spring-boot-starter', version: '1.0.0-beta4'// langchain4j整合千问dashscopeimplementation group: 'dev.langchain4j', name: 'langchain4j-community-dashscope-spring-boot-starter', version: '1.0.0-beta4'
yaml配置
langchain4j:## https://docs.langchain4j.dev/integrations/language-models/dashscopecommunity:dashscope:chat-model:api-key: 百炼平台申请model-name: qwen-plusspring:data:redis:host: server200port: 6379database: 3
二、持久化配置
官网参考地址https://docs.langchain4j.dev/tutorials/chat-memory/
@Configuration
public class ChatMemoryConf {/*** 聊天记录持久化存储到redis中* @param redisTemplate* @return*/public ChatMemoryStore chatMemoryStore(RedisTemplate<String,String> redisTemplate){return new ChatMemoryStore(){@Overridepublic List<ChatMessage> getMessages(Object memoryId) {String value = redisTemplate.opsForValue().get("chat:" + memoryId.toString());if(value == null || value.isEmpty()){return List.of();}return ChatMessageDeserializer.messagesFromJson(value);}@Overridepublic void updateMessages(Object memoryId, List<ChatMessage> list) {String messages = ChatMessageSerializer.messagesToJson(list);redisTemplate.opsForValue().set("chat:" + memoryId.toString(), messages);}@Overridepublic void deleteMessages(Object memoryId) {redisTemplate.delete("chat:" + memoryId.toString());}};}@Beanpublic ChatMemoryProvider chatMemoryProvider(RedisTemplate<String,String> redisTemplate){return memoryId -> MessageWindowChatMemory.builder().maxMessages(10).id(memoryId).chatMemoryStore(chatMemoryStore(redisTemplate)).build();}}
三、创建AiService代理
AiService的具体功能,可以看官网(https://docs.langchain4j.dev/tutorials/ai-services),上面有很详细的解释和示例
@AiService
public interface DashScopeAssistant {@SystemMessage("Answer using slang")String chat(@MemoryId String chatId, @UserMessage String userMessage);}
@Service
public class DashScopeChatMemoryService {private final static Logger LOGGER = LoggerFactory.getLogger(DashScopeChatMemoryService.class);private final DashScopeAssistant dashScopeAssistant;@Autowiredpublic DashScopeChatMemoryService(QwenChatModel qwenChatModel,ChatMemoryProvider chatMemoryProvider) {dashScopeAssistant = AiServices.builder(DashScopeAssistant.class).chatMemoryProvider(chatMemoryProvider).chatModel(qwenChatModel).build();}public String persistentChat(String chatId, String userMessage){String chat = dashScopeAssistant.chat(chatId, userMessage);LOGGER.info("persistent chat output : {}" ,chat);return chat;}
}
四、测试持久化
chatMemoryService.persistentChat("101", "我是赵光义");
chatMemoryService.persistentChat("101", "我是北宋的第二位皇帝,在高粱河被辽国打败了");
chatMemoryService.persistentChat("101", "你知道为为什么叫车神吗?");
通过断点观察,数据已经成功存入redis