LangChain4j 开发Java Agent智能体- 会话记忆

LangChain4j 开发Java Agent智能体- 会话记忆 大家好我是Java1234_小锋老师最近更新《2027版本 LangChain4j 开发Java Agent 智能体 视频教程》专辑感谢大家支持。本课程主要介绍和讲解 LangChain4j 简介阿里云百炼大模型平台接入Ollama简介以及安装和使用HelloWorld 实现日志配置集成SpringBootAi Service 使用对话与提示词工程(Prompt)结构化输出会话记忆工具调用(Function Calling)嵌入模型 与向量数据库RAG(检索增强生成)MCP(模型上下文协议)多模态支持视频教程课件源码打包下载链接https://pan.baidu.com/s/1o-zRfndo1HHrS_uFroOiCw?pwd1234提取码0000LangChain4j 开发Java Agent智能体- 会话记忆LangChain4j 提供了强大的会话记忆Chat Memory功能用于解决大模型“无状态”的问题能让你的 AI 应用在多轮对话中保持上下文连贯性。我们测试下前面的代码先问下一个 我是小锋。继续再问一个 我是谁 大模型已经不知道我是谁了说明大模型默认是没有记忆功能的。 会话记忆的核心机制Memory vs. History:ChatMemory是 LangChain4j 提供的核心机制它管理与送入模型的上下文。与记录完整对话的History不同ChatMemory会利用算法如驱逐旧消息、摘要、注入信息等来“记忆”部分信息以适应模型的上下文限制、控制调用成本和降低响应延迟。 内置的ChatMemory实现LangChain4j 提供了两种开箱即用的ChatMemory实现你也可以通过实现ChatMemory接口来扩展。MessageWindowChatMemory作为滑动窗口保留最近 N 条消息简单易懂非常适合快速原型开发和轮次不多的对话场景。TokenWindowChatMemory同样是滑动窗口但以 Token 数为限制指标。它能更精细地控制发送给模型的上下文长度尤其在 Token 敏感场景但会完全驱逐超过限制的消息。 会话隔离MemoryId注解默认情况下ChatMemory是所有用户/会话共享的会导致“记忆串线”。MemoryId注解提供了优雅的解决方案。在 AI Service 接口方法中标注该注解LangChain4j 会自动为每个 memoryId 创建并维护一个独立的ChatMemory实例。先看一个简单会话实例首先AssistantConfig里定义ChatMemoryProviderBeanpublicChatMemoryProvidermemoryChatMemoryProvider(){returnmemoryId-MessageWindowChatMemory.builder().id(memoryId)// 记忆id 会话隔离用.maxMessages(20)// 窗口大小可按需调整.build();}再新建一个Assistant4ServiceAIService里要配置 chatMemoryProviderpackagecom.java1234.service;importdev.langchain4j.service.MemoryId;importdev.langchain4j.service.UserMessage;importdev.langchain4j.service.spring.AiService;importdev.langchain4j.service.spring.AiServiceWiringMode;importreactor.core.publisher.Flux;AiService(wiringModeAiServiceWiringMode.EXPLICIT,// 手动指定接入模型 手动装配streamingChatModelopenAiStreamingChatModel,// 配置模型chatMemoryProvidermemoryChatMemoryProvider// 会话记忆)publicinterfaceAssistant4Service{/** * 会话记忆 * param memoryId 会话id * param question 提问 * return */FluxStringchat(MemoryIdStringmemoryId,UserMessageStringquestion);}最后MyChatController里注入Assistant4Service以及实现chat6AutowiredprivateAssistant4Serviceassistant4Service;RequestMapping(value/chat6,producestext/html;charsetutf-8)publicFluxStringchat6(StringmemoryId,Stringquestion){returnassistant4Service.chat(memoryId,question);}再测试下先提问我是小锋。记得浏览器地址栏带上memoryId再次提问我是谁大模型已经记住我是小锋了。本质上是第二次向大模型发送提问请求的时候已经把历史提问和回答都一并作为提示词请求大模型了。再学习一个会话持久化实例做会话持久化可以存db或者redis我们一般企业级开发用的是redis。我们windows跑redis的话一般都是跑docker里的windows平台建议大家去安装一个Docker Desktop比较方便。https://www.docker.com/products/docker-desktop/接下来 直接 运行 安装运行镜像命令docker run -d --name redis-stack -p 6379:6379 -p 8001:8001 -v d:/redis-data:/data redis/redis-stack:latest6379端口映射的是redis-stack服务8001端口映射的是可视化服务。首先第一步pom.xml里加下redis依赖dependencygroupIddev.langchain4j/groupIdartifactIdlangchain4j-community-redis-spring-boot-starter/artifactIdversion1.15.0-beta25/version/dependency接着第二步application.yml里配置redis连接配置langchain4j:community:redis:enabled:false# 关闭 Redis 向量库自动配置仅保留手动配置的会话记忆redis:host:localhostport:6379password:# 无密码留空ttl-seconds:3600# 每个会话 key 过期时间演示用 1 小时接着第三步新建redis会话配置类RedisChatMemoryConfigpackagecom.java1234.config;importdev.langchain4j.community.store.memory.chat.redis.RedisChatMemoryStore;importorg.springframework.boot.context.properties.ConfigurationProperties;importorg.springframework.boot.context.properties.EnableConfigurationProperties;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;ConfigurationConfigurationProperties(prefixlangchain4j.redis)EnableConfigurationProperties(RedisChatMemoryConfig.class)publicclassRedisChatMemoryConfig{privateStringhost;privateintport;privateStringpassword;privatelongttlSeconds;BeanpublicRedisChatMemoryStoreredisChatMemoryStore(){varbuilderRedisChatMemoryStore.builder().host(host).port(port).ttl(ttlSeconds);if(password!null!password.isBlank()){builder.password(password);// Redis 6 ACL 可再加 .user(default)}returnbuilder.build();}publicStringgetHost(){returnhost;}publicvoidsetHost(Stringhost){this.hosthost;}publicintgetPort(){returnport;}publicvoidsetPort(intport){this.portport;}publicStringgetPassword(){returnpassword;}publicvoidsetPassword(Stringpassword){this.passwordpassword;}publiclonggetTtlSeconds(){returnttlSeconds;}publicvoidsetTtlSeconds(longttlSeconds){this.ttlSecondsttlSeconds;}}最后修改AssistantConfig设置下chatMemoryStoreBeanpublicChatMemoryProvidermemoryChatMemoryProvider(RedisChatMemoryStoreredisChatMemoryStore){returnmemoryId-MessageWindowChatMemory.builder().id(memoryId)// 记忆id 会话隔离用.chatMemoryStore(redisChatMemoryStore)// redis会话存储.maxMessages(20)// 窗口大小可按需调整.build();}我们继续测试先跟大模型说我是小锋redis客户端里我们看下已经存储了会话信息。我们再次向大模型提问我是谁redis客户端里我们刷新看下也进行了更新