langchain4j集成QWen、Redis聊天记忆持久化

langchain4j实现聊天记忆默认是基于进程内存的方式,InMemoryChatMemoryStore是具体的实现了,是将聊天记录到一个map中,如果用户大的话,会造成内存溢出以及数据安全问题。位了解决这个问题 langchain4提供了ChatMemoryStore接口,让开发者可以灵活的选择存储策略,常用的可以使用mysql、redis、mongodb等,本文以redis为例,集成百炼平台通义千问实现大模型聊天记忆持久化。

一、引入依赖

具体详情可参考官网

复制代码
https://docs.langchain4j.dev/integrations/language-models/dashscope
XML 复制代码
    implementation group: 'org.springframework.boot', name: 'spring-boot-starter-data-redis', version: '3.4.0'
    // langchain4j AiService整合spring boot
    implementation group: 'dev.langchain4j', name: 'langchain4j-spring-boot-starter', version: '1.0.0-beta4'
    // langchain4j整合千问dashscope
    implementation group: 'dev.langchain4j', name: 'langchain4j-community-dashscope-spring-boot-starter', version: '1.0.0-beta4'

yaml配置

bash 复制代码
langchain4j:
  ## https://docs.langchain4j.dev/integrations/language-models/dashscope
  community:
    dashscope:
      chat-model:
        api-key: 百炼平台申请
        model-name: qwen-plus


spring:
  data:
    redis:
      host: server200
      port: 6379
      database: 3

二、持久化配置

官网参考地址https://docs.langchain4j.dev/tutorials/chat-memory/

java 复制代码
@Configuration
public class ChatMemoryConf {

    /**
     * 聊天记录持久化存储到redis中
     * @param redisTemplate
     * @return
     */
    public ChatMemoryStore chatMemoryStore(RedisTemplate<String,String>  redisTemplate){
        return  new ChatMemoryStore(){
            @Override
            public 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);
            }

            @Override
            public void updateMessages(Object memoryId, List<ChatMessage> list) {
                String messages = ChatMessageSerializer.messagesToJson(list);
                redisTemplate.opsForValue().set("chat:" + memoryId.toString(), messages);
            }

            @Override
            public void deleteMessages(Object memoryId) {
                redisTemplate.delete("chat:" + memoryId.toString());
            }
        };
    }


    @Bean
    public 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),上面有很详细的解释和示例

java 复制代码
@AiService
public interface DashScopeAssistant {

    @SystemMessage("Answer using slang")
    String chat(@MemoryId String  chatId, @UserMessage  String userMessage);

}
java 复制代码
@Service
public class DashScopeChatMemoryService {

    private final static Logger LOGGER = LoggerFactory.getLogger(DashScopeChatMemoryService.class);

    private final DashScopeAssistant dashScopeAssistant;

    @Autowired
    public 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;
    }
}

四、测试持久化

java 复制代码
chatMemoryService.persistentChat("101", "我是赵光义");
chatMemoryService.persistentChat("101", "我是北宋的第二位皇帝,在高粱河被辽国打败了");
chatMemoryService.persistentChat("101", "你知道为为什么叫车神吗?");

通过断点观察,数据已经成功存入redis

相关推荐
deephub8 小时前
AI代理性能提升实战:LangChain+LangGraph内存管理与上下文优化完整指南
人工智能·深度学习·神经网络·langchain·大语言模型·rag
半新半旧8 小时前
python 整合使用 Redis
redis·python·bootstrap
daixin884810 小时前
什么是缓存雪崩?缓存击穿?缓存穿透?分别如何解决?什么是缓存预热?
java·开发语言·redis·缓存
daixin884812 小时前
Redis过期数据的删除策略是什么?有哪些?
数据库·redis·缓存
都叫我大帅哥13 小时前
LangChain分层记忆解决方案:完整案例
python·langchain
alex10013 小时前
AI Agent开发学习系列 - langchain之LCEL(5):如何创建一个Agent?
人工智能·python·语言模型·langchain·prompt·向量数据库·ai agent
幻灭行度15 小时前
通过redis_exporter监控redis cluster
数据库·redis·缓存
青Cheng序员石头17 小时前
Prompt Engineering vs Vibe Coding vs Context Engineering
langchain·llm·aigc
数据智能老司机17 小时前
构建由 LLM 驱动的 Neo4j 应用程序——使用 Neo4j 和 Haystack 实现强大搜索功能
langchain·llm·aigc
冷崖19 小时前
Redis缓存策略以及bigkey的学习(九)
redis·学习·缓存