当前位置: 首页 > wzjs >正文

北京网络网站建设公司桌面百度

北京网络网站建设公司,桌面百度,给你一个网站你怎么做的吗,网站建设合同标准范本文章目录 引言依赖引入没有会话记忆示例手动添加会话记忆示例langchain4j实现自动会话记忆全局会话记忆会话记忆隔离 总结 引言 会话记忆是每个大模型都具备的能力,那么他是怎么实现的呢?你是否思考过大模型是如何实现知晓之前的聊天内容的。这篇文章将…

文章目录

  • 引言
  • 依赖引入
  • 没有会话记忆示例
  • 手动添加会话记忆示例
  • langchain4j实现自动会话记忆
    • 全局会话记忆
    • 会话记忆隔离
  • 总结

引言

会话记忆是每个大模型都具备的能力,那么他是怎么实现的呢?你是否思考过大模型是如何实现知晓之前的聊天内容的。这篇文章将会由浅入深带你窥探大模型会话记忆的秘密!

依赖引入

本文涉及到的所有依赖统一放在这里

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>3.2.3</version></dependency><!-- 引入langchain4j依赖--><dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j</artifactId><version>${langchain4j.version}</version></dependency><!-- 引入OpenAI依赖。由于deepseek跟open ai共用一套标准所以deepseek也用这个依赖--><dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-open-ai</artifactId><version>${langchain4j.version}</version></dependency><!-- SpringBoot整合百炼/千问依赖 --><dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-community-dashscope-spring-boot-starter</artifactId></dependency><!-- spring webflux --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId></dependency>
</dependencies>

没有会话记忆示例

首先,请大家看下方代码,代码中与大模型进行了两次聊天,第一次告诉大模型我是谁,第二次问大模型我是谁。

public class DemoErrorTest {public static void main(String[] args) {OpenAiChatModel chatModel = OpenAiChatModel.builder().apiKey("demo").modelName("gpt-4o-mini").build();String result = chatModel.chat("我是Jayden。");System.out.println(result);String result2 = chatModel.chat("我是谁?");System.out.println(result2);}
}

输出如下:观察输出可以清晰看到,此时的大模型是没有记忆的

手动添加会话记忆示例

接下来将演示手动添加会话记忆的能力,这个demo其实在官网里也有提到,目的是让大家更了解原理,首先看代码,原理就是在下一次聊天的时候放入上一次聊天的对话与答案

public class DemoSuccessTest {public static void main(String[] args) {OpenAiChatModel chatModel = OpenAiChatModel.builder().apiKey("demo").modelName("gpt-4o-mini").build();UserMessage userMessage1 = UserMessage.userMessage("我是Jayden。");ChatResponse result1 = chatModel.chat(userMessage1);AiMessage response1 = result1.aiMessage();System.out.println(response1);UserMessage userMessage2 = UserMessage.userMessage("我是谁?");ChatResponse result2 = chatModel.chat(userMessage1,response1,userMessage2);AiMessage response2 = result2.aiMessage();System.out.println(response2);}
}

我们来看执行的结果,这次大模型通过上下文知道了我是谁。那么问题来了,如果一个会话有很多对话,那这个代码是不是有问题?解决问题的方式往下看。

langchain4j实现自动会话记忆

抛开langchain4j不谈,在web2的世界里,数据都是要存储的,无非就是怎么存的问题。在会话这种场景下很容易就想到K-V结构的存储,K是会话的id,V是对应的聊天列表。

接下来来看下langchain4j里实现上述原理是怎么做的

全局会话记忆

首先要定一个对话助手Assistant,然后在SpringBoot中实例化这个bean。

@Configuration
public class ChatMemoryAiConfig {/*** 对话助手*/public interface Assistant {String chat(String prompt);TokenStream streamChat(String prompt);}@Beanpublic Assistant assistant(ChatLanguageModel chatLanguageModel, StreamingChatLanguageModel streamingChatLanguageModel) {MessageWindowChatMemory chatMemory = MessageWindowChatMemory.withMaxMessages(33);// 原理是对话助手增加动态代理/*** 第一次:chat* ==》 对话内容存储到内存(ChatMemory)* ==》 取出来历史对话内容* ==》 放到当前对话内容中*/return AiServices.builder(Assistant.class).chatLanguageModel(chatLanguageModel).streamingChatLanguageModel(streamingChatLanguageModel).chatMemory(chatMemory).build();}
}

这里的关键代码是MessageWindowChatMemory chatMemory = MessageWindowChatMemory.withMaxMessages(33);这就是langchain4j提供的会话记忆的类,在通过AiServices构造Assistant时,将指定存储上下文的MessageWindowChatMemory设置到对话助手上即可实现会话记忆。参数里的33代表最多存储多少条会话内容。

我们来看下MessageWindowChatMemory源码,看看会话内容到底怎么存的?

public class MessageWindowChatMemory implements ChatMemory {private final Object id;private final Integer maxMessages;private final ChatMemoryStore store;// 省略。。。
}

可以看到会话记忆应该是存在ChatMemoryStore里的,我们打开源码查看,可以看到langchain4j是存在了内存里的,用了一个线程安全的Map,这与我们的猜想是一致的。

public class InMemoryChatMemoryStore implements ChatMemoryStore {private final Map<Object, List<ChatMessage>> messagesByMemoryId = new ConcurrentHashMap<>();// 省略。。。
}

定义好会话助手Bean后就可以通过接口来测试了,测试接口代码

@RestController
@RequestMapping("/chat/memory/ai")
public class ChatMemoryAIController {@Autowiredprivate ChatMemoryAiConfig.Assistant assistant;@RequestMapping("/chat")public String chat(@RequestBody String prompt) {return assistant.chat(prompt);}
}

大家可以通过这个接口进行测试,是带会话记忆的能力的。这里需要补充一点,Assistant是一个接口,那么为什么可以直接调用呢?这里实际是使用了动态代理。

会话记忆隔离

上一部分的会话意义我定位为全局的会话记忆,原因是所有人共用会话记忆。实际使用过DeepSeek等其他ai产品的都知道,会话记忆一般都是通过会话id来进行隔离的,所以才会有会话列表。为了解决这个问题,所以有会话隔离。

首先我们定义一个会话助手,这里需要注意的是@MemberId注解,这个注解名很容易理解,就是记忆id,他可以是任何具有唯一属性的字段,具体看业务。比如它可以是userId,也可以是会话id等等。

首先要定一个对话助手MemoryAssistant,然后在SpringBoot中实例化这个bean。

import com.jayden.ai.memory.store.ChatMemoryStorePersistent;
import dev.langchain4j.memory.chat.ChatMemoryProvider;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.chat.StreamingChatLanguageModel;
import dev.langchain4j.service.AiServices;
import dev.langchain4j.service.MemoryId;
import dev.langchain4j.service.TokenStream;
import dev.langchain4j.service.UserMessage;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class ChatMemoryAiConfig {public interface MemoryAssistant{String chat(@MemoryId Integer memoryId, @UserMessage String prompt);TokenStream streamChat(@MemoryId Integer memoryId, @UserMessage String prompt);}/*** 带有记忆的对话助手 多轮对话的内容是存在内存中的* @param chatLanguageModel* @param streamingChatLanguageModel* @return*/@Beanpublic MemoryAssistant memoryAssistant(ChatLanguageModel chatLanguageModel, StreamingChatLanguageModel streamingChatLanguageModel) {return AiServices.builder(MemoryAssistant.class).chatLanguageModel(chatLanguageModel).streamingChatLanguageModel(streamingChatLanguageModel).chatMemoryProvider(memoryId -> MessageWindowChatMemory.builder().maxMessages(33).id(memoryId).build()).build();}}

测试接口

import com.jayden.ai.memory.config.ChatMemoryAiConfig;
import dev.langchain4j.service.TokenStream;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;@RestController
@RequestMapping("/chat/memory/ai")
public class ChatMemoryAIController {@Autowiredprivate ChatMemoryAiConfig.MemoryAssistant memoryAssistant;@GetMapping("/memory/chat")public String memoryChat(@RequestParam("prompt") String prompt, @RequestParam("chatId") Integer chatId){return memoryAssistant.chat(chatId, prompt);}}

可以通过接口进行测试,可以发现会话之间实现了隔离。

总结

本文从基础案例一步步到会话隔离,深入浅出的介绍了会话记忆,但这里的会话记忆是存在内存的,内存的特点是断电即失,所以数据需要做持久化,如果觉得文章有帮助,可以三连走起来,专栏里有整套langchain4j的教程,欢迎关注!

http://www.dtcms.com/wzjs/28972.html

相关文章:

  • 郑州七彩网站建设公司 评论百度推广账户优化方案
  • 网站程序 制作国际新闻最新消息十条
  • 湖北省建设厅信息网站seo美式
  • 做传奇网站云服务器地域改选哪里最佳的资源搜索引擎
  • 上海网站建设流国内前10电商代运营公司
  • 沈阳网站优化建设网络整合营销方案
  • 商务网站建设目的百度快照优化
  • 哪些企业必须用网站东莞seo培训
  • 网站建设推荐书籍电子商务网站建设多少钱
  • wordpress带下载功能seo网络推广专员招聘
  • 做海报免费素材网站有哪些自动优化app
  • 共享互助医疗网站建设成人短期就业培训班
  • 网站如何做搜索引擎优化百度快速收录接口
  • 专业做图片制作网站线上宣传方案
  • 网站维护要多久时间深圳网站建设
  • 空间 建网站网站推广seo是什么
  • 海安做网站沈阳关键词优化报价
  • 杭州网站建设 博采网络有限公司免费文案素材网站
  • 手机网站建设是什么考研培训机构排名前十
  • 电子商务学校网站建设安卓优化大师老版本下载
  • 深圳网站设计知名乐云seo外包公司值得去吗
  • wordpress端口不生效seo推广软件品牌
  • 做网站的价新闻平台发布
  • 重庆专业网站建设公司哪家好网络营销是以什么为中心
  • 沈阳做网站培训友情链接如何交换
  • 怎样用dw做网站导航条口碑营销有哪些方式
  • 用asp做的网站有多少电子商务网站建设与维护
  • php网站开发源代码今天中国新闻
  • 夜间正能量网站入口免费下载全文搜索引擎有哪些
  • 江门网红打卡景点蓬江区网络seo优化