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

相关推荐
小小工匠1 小时前
性能优化 - 案例篇:数据一致性
redis·性能优化·数据一致性
多多*15 小时前
蓝桥杯国赛训练 day1
java·开发语言·数据库·redis·缓存·职场和发展·蓝桥杯
weixin_3077791315 小时前
使用Redis作为缓存优化ElasticSearch读写性能
redis·分布式·elasticsearch·缓存·架构
敲键盘的小夜猫16 小时前
LangChain核心之Runnable接口底层实现
langchain
疯狂的小强呀17 小时前
基于langchain的简单RAG的实现
python·langchain·rag检索增强
用户7112839284717 小时前
LangChain(三) LCEL
人工智能·langchain
清风~徐~来18 小时前
【Redis】set 类型
java·数据库·redis
书山有路勤为径~19 小时前
Docker 安装 Redis 容器
redis·docker·eureka
啾啾大学习19 小时前
LangChain快速筑基(带代码)P3-连续对话Memory
langchain
小小星球之旅19 小时前
redis缓存常见问题
数据库·redis·学习·缓存