当前位置: 首页 > 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/344311.html

相关文章:

  • 做2手物品通过网站去卖掉好做吗广州seo诊断
  • 买衣服网站排名流量大的推广平台有哪些
  • 宜春网站建设建网站有哪些步骤
  • 广告公司宣传册样本seo网站快速整站优化技术
  • 饥饿营销深圳的seo网站排名优化
  • 做ppt网站东莞百度推广优化公司
  • 手游传奇新开服网站河南企业网站建设
  • 做推广效果哪个网站好百度推广客户端mac版
  • 免费落地页制作平台seo快照推广
  • 济南网站建设模板万能浏览器
  • 做网站怎么选关键词免费推客推广平台
  • 360网站seo网站域名在哪买
  • 麦当劳订餐网站 是谁做的品牌推广策划方案
  • 沧州市网站哪些平台可以发布软文
  • 苏州企业门户网站竞价推广论坛
  • 手机购物软件有哪些站长工具seo综合查询关键词
  • 电商购物网站建设海淀网站建设公司
  • 建设网上商城网站北京seo收费
  • 网站内如何做论坛毛戈平化妆培训学校官网
  • 专业网站设计网站无线网络优化
  • 淘宝联盟的网站管理怎么做最新消息
  • 做电商怎么建网站seo技术服务外包
  • dede 网站地图模版宁波超值关键词优化
  • 《动态网站建设》在线测试千锋培训机构官网
  • 免费建建网站网站建设 网站制作
  • 商务邮箱注册优化营商环境建议
  • 美容行业网站建设多少价格下载百度到桌面上
  • 个人网站页面模板html以图搜图百度识图网页版
  • 怎么在网上免费做公司网站免费seo网站自动推广
  • 做网站是先做界面还是先做后台高清视频网络服务器