找回密码
 立即注册
首页 业界区 安全 7. LangChain4j + 记忆缓存详细说明

7. LangChain4j + 记忆缓存详细说明

乱蚣 昨天 20:44
7. LangChain4j + 记忆缓存详细说明

@
目录

  • 7. LangChain4j + 记忆缓存详细说明

    • LangChain4j + 记忆缓存实战操作

  • 最后:


  • https://docs.langchain4j.dev/tutorials/chat-memory/
1.png

记忆缓存是聊天系统中的一个重要组件,用于存储和管理对话的上下文信息。它的主要作用是让AI助手能够"记住"之前的对话内容,从而提供连贯和个性化的回复。
我们随便打开一个大模型对话聊天就明白了。
2.png

简单的理解就是:一个让大模型可以记住我们上面一段历史内容上对它的提问,和索引需要的内容:
3.png

4.png

官方解释:LangChain4j提供了2种开箱即用的记忆缓存的实现方式如下:

  • 一种是:通过提问的条数,记忆几条提问记录信息。比如:记忆存储你提问的前 100 条的记录内容。推荐
  • 第二种:则是通过记忆存储你的 token 数目,这种方式不推荐,因为不同的大模型的 token 计算的方式不同。
5.png

6.png

LangChain4j + 记忆缓存实战操作


  • 创建对应项目的 module 模块内容:
  • 导入相关的 pom.xml 的依赖,这里我们采用流式输出的方式,导入langchain4j-open-ai + langchain4j + langchain4j-reactor 这三件必须存在,这里我们不指定版本,而是通过继承的 pom.xml 当中获取。_
  1. <dependency>
  2.             <groupId>org.springframework.boot</groupId>
  3.             spring-boot-starter-web</artifactId>
  4.         </dependency>
  5.         
  6.         <dependency>
  7.             <groupId>dev.langchain4j</groupId>
  8.             langchain4j-open-ai</artifactId>
  9.         </dependency>
  10.         <dependency>
  11.             <groupId>dev.langchain4j</groupId>
  12.             langchain4j</artifactId>
  13.         </dependency>
  14.         <dependency>
  15.             <groupId>dev.langchain4j</groupId>
  16.             langchain4j-reactor</artifactId>
  17.         </dependency>
  18.         
  19.         <dependency>
  20.             <groupId>org.projectlombok</groupId>
  21.             lombok</artifactId>
  22.             <optional>true</optional>
  23.         </dependency>
  24.         
  25.         <dependency>
  26.             <groupId>cn.hutool</groupId>
  27.             hutool-all</artifactId>
  28.             <version>5.8.22</version>
  29.         </dependency>
复制代码

  • 配置 applcation.yaml / properties 配置文件,其中指明我们的输出响应的编码格式,因为如果不指定的话,存在返回的中文,就是乱码了。
  1. server.port=9006
  2. spring.application.name=langchain4j-06chat-memory
  3. # 设置响应的字符编码,避免流式返回输出乱码
  4. server.servlet.encoding.charset=utf-8
  5. server.servlet.encoding.enabled=true
  6. server.servlet.encoding.force=true
复制代码
7.png


  • 编写操作大模型的 Chan****Assistant 接口类
8.png

注意:需要加上@MemoryId 和 @UserMesage 两个注解
这个很好理解,你想让大模型记录到你的对话历史信息。你自然就一定要提供UserId用户ID,以及用户的历史记录信息了
  1. package com.rainbowsea.langchain4j06chatmemory.service;
  2. import dev.langchain4j.service.MemoryId;
  3. import dev.langchain4j.service.UserMessage;
  4. /**
  5. */
  6. public interface ChatMemoryAssistant
  7. {
  8.     /**
  9.      * 聊天带记忆缓存功能
  10.      *
  11.      * @param userId  用户 ID
  12.      * @param prompt 消息
  13.      * @return {@link String }
  14.      */
  15.     String chatWithChatMemory(@MemoryId Long userId, @UserMessage String prompt);
  16. }
复制代码

  • 编写大模型三件套(大模型 key,大模型 name,大模型 url) 三件套的大模型配置类。
注意:这里我们要记忆缓存的话,就需要用到我们的通义千问的长对话大模型了。
9.png

10.png

11.png
  1. import dev.langchain4j.memory.chat.MessageWindowChatMemory;
  2. import dev.langchain4j.memory.chat.TokenWindowChatMemory;
  3. import dev.langchain4j.model.TokenCountEstimator;
  4. import dev.langchain4j.model.chat.ChatModel;
  5. import dev.langchain4j.model.openai.OpenAiChatModel;
  6. import dev.langchain4j.model.openai.OpenAiTokenCountEstimator;
  7. import dev.langchain4j.service.AiServices;
  8. import org.springframework.context.annotation.Bean;
  9. import org.springframework.context.annotation.Configuration;
  10. import com.rainbowsea.langchain4j06chatmemory.service.ChatMemoryAssistant;
  11. /**
  12. * @Description: 知识出处,https://docs.langchain4j.dev/tutorials/chat-memory/#eviction-policy
  13. */
  14. @Configuration
  15. public class LLMConfig
  16. {
  17.     @Bean
  18.     public ChatModel chatModel()
  19.     {
  20.         return OpenAiChatModel.builder()
  21.                     .apiKey(System.getenv("aliQwen_api"))  //你自己配置到系统变量当中的值
  22.                     .modelName("qwen-long")
  23.                     .baseUrl("https://dashscope.aliyuncs.com/compatible-mode/v1")
  24.                 .build();
  25.     }
  26.     /**
  27.     * @Description: 按照MessageWindowChatMemory
  28.      *知识出处,https://docs.langchain4j.dev/tutorials/chat-memory/#eviction-policy
  29.     */
  30.     @Bean(name = "chatMessageWindowChatMemory")
  31.     public ChatMemoryAssistant chatMessageWindowChatMemory(ChatModel chatModel)
  32.     {
  33.         return AiServices.builder(ChatMemoryAssistant.class)
  34.                 .chatModel(chatModel)
  35.                 //按照memoryId对应创建了一个chatMemory
  36.                 .chatMemoryProvider(memoryId -> MessageWindowChatMemory.withMaxMessages(100))
  37.                 .build();
  38.     }
  39. }
复制代码
为了保证知识内容上的完整性,这里我也附上通过 token 数记录历史对话的代码
12.png
  1. package com.rainbowsea.langchain4j06chatmemory.config;
  2. import dev.langchain4j.memory.chat.MessageWindowChatMemory;
  3. import dev.langchain4j.memory.chat.TokenWindowChatMemory;
  4. import dev.langchain4j.model.TokenCountEstimator;
  5. import dev.langchain4j.model.chat.ChatModel;
  6. import dev.langchain4j.model.openai.OpenAiChatModel;
  7. import dev.langchain4j.model.openai.OpenAiTokenCountEstimator;
  8. import dev.langchain4j.service.AiServices;
  9. import org.springframework.context.annotation.Bean;
  10. import org.springframework.context.annotation.Configuration;
  11. import com.rainbowsea.langchain4j06chatmemory.service.ChatMemoryAssistant;
  12. /**
  13. * @Description: 知识出处,https://docs.langchain4j.dev/tutorials/chat-memory/#eviction-policy
  14. */
  15. @Configuration
  16. public class LLMConfig
  17. {
  18.     @Bean
  19.     public ChatModel chatModel()
  20.     {
  21.         return OpenAiChatModel.builder()
  22.                     .apiKey(System.getenv("aliQwen_api"))  //你自己配置到系统变量当中的值
  23.                     .modelName("qwen-long")
  24.                     .baseUrl("https://dashscope.aliyuncs.com/compatible-mode/v1")
  25.                 .build();
  26.     }
  27.     /**
  28.     * @Description: 按照 TokenWindowChatMemory,
  29.      * 知识出处,https://docs.langchain4j.dev/tutorials/chat-memory/#eviction-policy
  30.     */
  31.     @Bean(name = "chatTokenWindowChatMemory")
  32.     public ChatMemoryAssistant chatTokenWindowChatMemory(ChatModel chatModel)
  33.     {
  34.         //1 TokenCountEstimator默认的token分词器,需要结合Tokenizer计算ChatMessage的token数量
  35.         TokenCountEstimator openAiTokenCountEstimator = new OpenAiTokenCountEstimator("gpt-4");
  36.         return AiServices.builder(ChatMemoryAssistant.class)
  37.                 .chatModel(chatModel)
  38.                 .chatMemoryProvider(memoryId -> TokenWindowChatMemory.withMaxTokens(1000,openAiTokenCountEstimator))
  39.                 .build();
  40.     }
  41. }
复制代码

  • 编写聊天记忆缓存调用的 cutroller
13.png

运行测试:
14.png

为了保证知识内容上的完整性,这里我也附上通过 token 数记录历史对话的代码
  1. package com.rainbowsea.langchain4j06chatmemory.controller;
  2. import cn.hutool.core.date.DateUtil;
  3. import com.rainbowsea.langchain4j06chatmemory.service.ChatMemoryAssistant;
  4. import dev.langchain4j.data.message.AiMessage;
  5. import dev.langchain4j.data.message.UserMessage;
  6. import dev.langchain4j.model.chat.response.ChatResponse;
  7. import jakarta.annotation.Resource;
  8. import lombok.extern.slf4j.Slf4j;
  9. import org.springframework.web.bind.annotation.GetMapping;
  10. import org.springframework.web.bind.annotation.RestController;
  11. import java.util.Arrays;
  12. /**
  13. * @auther zzyybs@126.com
  14. * @Date 2025-05-30 19:16
  15. * @Description: TODO
  16. */
  17. @RestController
  18. @Slf4j
  19. public class ChatMemoryController
  20. {
  21.     @Resource(name = "chatTokenWindowChatMemory")
  22.     private ChatMemoryAssistant chatTokenWindowChatMemory;
  23.     /**
  24.      * @Description: TokenWindowChatMemory实现聊天功能
  25.      * @Auther: zzyybs@126.com
  26.      */
  27.     @GetMapping(value = "/chatmemory/test3")
  28.     public String chatTokenWindowChatMemory()
  29.     {
  30.         chatTokenWindowChatMemory.chatWithChatMemory(1L, "你好!我的名字是mysql");
  31.         String answer01 = chatTokenWindowChatMemory.chatWithChatMemory(1L, "我的名字是什么");
  32.         System.out.println("answer01返回结果:"+answer01);
  33.         chatTokenWindowChatMemory.chatWithChatMemory(3L, "你好!我的名字是oracle");
  34.         String answer02 = chatTokenWindowChatMemory.chatWithChatMemory(3L, "我的名字是什么");
  35.         System.out.println("answer02返回结果:"+answer02);
  36.         return "chatTokenWindowChatMemory success : "
  37.                 + DateUtil.now()+"
  38. \n\n answer01: "+answer01+"
  39. \n\n answer02: "+answer02;
  40.     }
  41. }
复制代码
最后:

“在这个最后的篇章中,我要表达我对每一位读者的感激之情。你们的关注和回复是我创作的动力源泉,我从你们身上吸取了无尽的灵感与勇气。我会将你们的鼓励留在心底,继续在其他的领域奋斗。感谢你们,我们总会在某个时刻再次相遇。”
15.gif


来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册