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

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

@[toc]


记忆缓存是聊天系统中的一个重要组件,用于存储和管理对话的上下文信息。它的主要作用是让AI助手能够"记住"之前的对话内容,从而提供连贯和个性化的回复。

我们随便打开一个大模型对话聊天就明白了。

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

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

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

LangChain4j + 记忆缓存实战操作

  1. 创建对应项目的 module 模块内容:
  2. 导入相关的 pom.xml 的依赖,这里我们采用流式输出的方式,导入langchain4j-open-ai + langchain4j + langchain4j-reactor 这三件必须存在,这里我们不指定版本,而是通过继承的 pom.xml 当中获取。_
xml 复制代码
<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--langchain4j-open-ai + langchain4j + langchain4j-reactor-->
        <dependency>
            <groupId>dev.langchain4j</groupId>
            <artifactId>langchain4j-open-ai</artifactId>
        </dependency>
        <dependency>
            <groupId>dev.langchain4j</groupId>
            <artifactId>langchain4j</artifactId>
        </dependency>
        <dependency>
            <groupId>dev.langchain4j</groupId>
            <artifactId>langchain4j-reactor</artifactId>
        </dependency>
        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!--hutool-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.22</version>
        </dependency>
  1. 配置 applcation.yaml / properties 配置文件,其中指明我们的输出响应的编码格式,因为如果不指定的话,存在返回的中文,就是乱码了。
properties 复制代码
server.port=9006

spring.application.name=langchain4j-06chat-memory

# 设置响应的字符编码,避免流式返回输出乱码
server.servlet.encoding.charset=utf-8
server.servlet.encoding.enabled=true
server.servlet.encoding.force=true
  1. 编写操作大模型的 Chan**Assistant 接口类**。

注意:需要加上@MemoryId 和 @UserMesage 两个注解
这个很好理解,你想让大模型记录到你的对话历史信息。你自然就一定要提供UserId用户ID,以及用户的历史记录信息了

java 复制代码
package com.rainbowsea.langchain4j06chatmemory.service;

import dev.langchain4j.service.MemoryId;
import dev.langchain4j.service.UserMessage;

/**
 */
public interface ChatMemoryAssistant
{

    /**
     * 聊天带记忆缓存功能
     *
     * @param userId  用户 ID
     * @param prompt 消息
     * @return {@link String }
     */
    String chatWithChatMemory(@MemoryId Long userId, @UserMessage String prompt);
}
  1. 编写大模型三件套(大模型 key,大模型 name,大模型 url) 三件套的大模型配置类。

注意:这里我们要记忆缓存的话,就需要用到我们的通义千问的长对话大模型了。

java 复制代码
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.memory.chat.TokenWindowChatMemory;
import dev.langchain4j.model.TokenCountEstimator;
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.model.openai.OpenAiTokenCountEstimator;
import dev.langchain4j.service.AiServices;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.rainbowsea.langchain4j06chatmemory.service.ChatMemoryAssistant;

/**
 * @Description: 知识出处,https://docs.langchain4j.dev/tutorials/chat-memory/#eviction-policy
 */
@Configuration
public class LLMConfig
{
    @Bean
    public ChatModel chatModel()
    {
        return OpenAiChatModel.builder()
                    .apiKey(System.getenv("aliQwen_api"))  //你自己配置到系统变量当中的值
                    .modelName("qwen-long")
                    .baseUrl("https://dashscope.aliyuncs.com/compatible-mode/v1")
                .build();
    }



    /**
    * @Description: 按照MessageWindowChatMemory
     *知识出处,https://docs.langchain4j.dev/tutorials/chat-memory/#eviction-policy
    */
    @Bean(name = "chatMessageWindowChatMemory")
    public ChatMemoryAssistant chatMessageWindowChatMemory(ChatModel chatModel)
    {

        return AiServices.builder(ChatMemoryAssistant.class)
                .chatModel(chatModel)
                //按照memoryId对应创建了一个chatMemory
                .chatMemoryProvider(memoryId -> MessageWindowChatMemory.withMaxMessages(100))
                .build();
    }

}

为了保证知识内容上的完整性,这里我也附上通过 token 数记录历史对话的代码

java 复制代码
package com.rainbowsea.langchain4j06chatmemory.config;

import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.memory.chat.TokenWindowChatMemory;
import dev.langchain4j.model.TokenCountEstimator;
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.model.openai.OpenAiTokenCountEstimator;
import dev.langchain4j.service.AiServices;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.rainbowsea.langchain4j06chatmemory.service.ChatMemoryAssistant;

/**
 * @Description: 知识出处,https://docs.langchain4j.dev/tutorials/chat-memory/#eviction-policy
 */
@Configuration
public class LLMConfig
{
    @Bean
    public ChatModel chatModel()
    {
        return OpenAiChatModel.builder()
                    .apiKey(System.getenv("aliQwen_api"))  //你自己配置到系统变量当中的值
                    .modelName("qwen-long")
                    .baseUrl("https://dashscope.aliyuncs.com/compatible-mode/v1")
                .build();
    }




    /**
    * @Description: 按照 TokenWindowChatMemory,
     * 知识出处,https://docs.langchain4j.dev/tutorials/chat-memory/#eviction-policy
    */
    @Bean(name = "chatTokenWindowChatMemory")
    public ChatMemoryAssistant chatTokenWindowChatMemory(ChatModel chatModel)
    {
        //1 TokenCountEstimator默认的token分词器,需要结合Tokenizer计算ChatMessage的token数量
        TokenCountEstimator openAiTokenCountEstimator = new OpenAiTokenCountEstimator("gpt-4");

        return AiServices.builder(ChatMemoryAssistant.class)
                .chatModel(chatModel)
                .chatMemoryProvider(memoryId -> TokenWindowChatMemory.withMaxTokens(1000,openAiTokenCountEstimator))
                .build();
    }
}
  1. 编写聊天记忆缓存调用的 cutroller

运行测试:

为了保证知识内容上的完整性,这里我也附上通过 token 数记录历史对话的代码

java 复制代码
package com.rainbowsea.langchain4j06chatmemory.controller;

import cn.hutool.core.date.DateUtil;
import com.rainbowsea.langchain4j06chatmemory.service.ChatMemoryAssistant;
import dev.langchain4j.data.message.AiMessage;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.model.chat.response.ChatResponse;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Arrays;

/**
 * @auther zzyybs@126.com
 * @Date 2025-05-30 19:16
 * @Description: TODO
 */
@RestController
@Slf4j
public class ChatMemoryController
{

    @Resource(name = "chatTokenWindowChatMemory")
    private ChatMemoryAssistant chatTokenWindowChatMemory;


    /**
     * @Description: TokenWindowChatMemory实现聊天功能
     * @Auther: zzyybs@126.com
     */
    @GetMapping(value = "/chatmemory/test3")
    public String chatTokenWindowChatMemory()
    {
        chatTokenWindowChatMemory.chatWithChatMemory(1L, "你好!我的名字是mysql");
        String answer01 = chatTokenWindowChatMemory.chatWithChatMemory(1L, "我的名字是什么");
        System.out.println("answer01返回结果:"+answer01);

        chatTokenWindowChatMemory.chatWithChatMemory(3L, "你好!我的名字是oracle");
        String answer02 = chatTokenWindowChatMemory.chatWithChatMemory(3L, "我的名字是什么");
        System.out.println("answer02返回结果:"+answer02);

        return "chatTokenWindowChatMemory success : "
                + DateUtil.now()+"<br> \n\n answer01: "+answer01+"<br> \n\n answer02: "+answer02;
    }
}

最后:

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

相关推荐
大强同学35 分钟前
对比 VS Code:Zed 编辑器编码体验全面解析
人工智能·windows·编辑器·ai编程
熊猫钓鱼>_>35 分钟前
从“流程固化“到“意图驱动“:大模型调智能体调Skill架构深度解析
ai·架构·大模型·llm·agent·skill·openclaw
前进的李工1 小时前
LangChain使用AI工具赋能:解锁大语言模型无限潜力
开发语言·人工智能·语言模型·langchain·大模型
小村儿2 小时前
连载04-最重要的Skill---一起吃透 Claude Code,告别 AI coding 迷茫
前端·后端·ai编程
北冥有羽Victoria3 小时前
OpenCLI 操作网页 从0到1完整实操指南
vscode·爬虫·python·github·api·ai编程·opencli
杨艺韬4 小时前
为什么需要理解 LangChain
langchain·agent
坤岭4 小时前
大模型“入侵”广告推荐
人工智能·langchain·推荐算法
Thomas.Sir4 小时前
GitHub Copilot从入门到精通【从基础补全到智能代理,解锁AI编程全技能】
github·copilot·ai编程
加瓦点灯4 小时前
Vibe Coding 最佳实践:人控架构,AI执行
ai编程
Baihai_IDP5 小时前
微软多模态推理模型 Phi-4-reasoning-vision 训练经验分享
人工智能·面试·llm