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

相关推荐
超人在良家-阿启6 小时前
LangChain 之 DashScopeEmbeddings下的 embed_query和embed_documents的区别
langchain
长安城没有风7 小时前
从入门到精通【Redis】理解Redis事务
数据库·redis·缓存
gsfl13 小时前
Redis 持久化机制
数据库·redis·缓存
z晨晨14 小时前
互联网大厂Java求职面试实战:Spring Boot与微服务场景深度解析
java·spring boot·redis·微服务·kafka·spring security·电商
野犬寒鸦15 小时前
从零起步学习Redis || 第五章:利用Redis构造分布式全局唯一ID
java·服务器·数据库·redis·分布式·后端·缓存
许泽宇的技术分享17 小时前
重塑Excel的智慧边界:ExcelAgentTemplate架构深度解析与LLM集成最佳实践
langchain·excel插件开发
何故染尘優18 小时前
Redis 如何配置 Key 的过期时间?它的实现原理?
数据库·redis·缓存
野生技术架构师1 天前
聊聊五种 Redis 部署模式
数据库·redis·缓存
C++chaofan1 天前
项目中为AI添加对话记忆
java·数据结构·人工智能·redis·缓存·个人开发·caffeine
野熊佩骑1 天前
一文读懂Redis之数据持久化
linux·运维·数据库·redis·缓存·中间件·centos