? ? ? ? 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
?