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

【Springboot+LangChain4j】实现多轮对话,即记忆对话功能

前置条件:已完成Springboot项目集成LangChain4j 可以参考上篇内容:【Springboot+LangChain4j】Springboot项目集成LangChain4j(下)-CSDN博客

1.问题描述

在实现了调用Ollama接口实现对话功能后,发现每次对话都是一个新的对话环境,不能针对一个问题多轮的询问下去。

在langchain4j中,其实有提供ChatMemory的类,来实现多轮对话功能。

2.新建配置类

建一个配置类ChatConfig

@Configuration
public class ChatConfig {public interface Assistant {String chat(String message);TokenStream stream(String message);}@Beanpublic Assistant assistant(ChatModel chatModel,StreamingChatModel streamingChatModel) {ChatMemory chatMemory = MessageWindowChatMemory.withMaxMessages(20);return AiServices.builder(Assistant.class).chatModel(chatModel).streamingChatModel(streamingChatModel).chatMemory(chatMemory).build();}

代码解释:

public interface Assistant {String chat(String message);TokenStream stream(String message);
}

定义了一个AI助手接口,LangChain4j 会基于这个接口生成实现类,一个非流式,一个流式。

@Bean
public Assistant assistant(ChatModel chatModel,StreamingChatModel streamingChatModel) {ChatMemory chatMemory = MessageWindowChatMemory.withMaxMessages(20);return AiServices.builder(Assistant.class).chatModel(chatModel).streamingChatModel(streamingChatModel).chatMemory(chatMemory).build();
}

ChatMemory:聊天上下文记忆,创建一个聊天记忆对象,记住最近的 20 条消息,消息数是可以根据自己需求改的

return:构建Assistant实例

  • AiServices.builder(...):LangChain4j 提供的构造工具,用于生成 Assistant 实现。

  • .chatModel(...):设置用于普通对话的模型。

  • .streamingChatModel(...):设置用于流式对话的模型。

  • .chatMemory(...):指定对话记忆方式。

  • .build():生成最终的实现类并返回。

3.接口修改

在接口实现类中,注入这个实例

@Autowired
ChatConfig.Assistant assistant;

非流式的实现方法直接这么改就可以用

@GetMapping("/ai/generate_memory")
public String generateMemory(@RequestParam String text) {return assistant.chat(text);
}

流式就这么写就可以

@GetMapping(value = "/ai/generateStream_memory", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> generateStreamMemory(@RequestParam String text) {return Flux.create(sink -> {TokenStream tokenStream = assistant.stream(text);tokenStream.onPartialResponse(sink::next) // 每接收到一个 token,就推送到前端.onCompleteResponse(response -> sink.complete()) // 完成流.onError(sink::error) // 异常处理.start(); // 最后一定要调用 start() 启动流式响应});
}

http://www.xdnf.cn/news/9349.html

相关文章:

  • v4.0 论文投稿-Latex论文投稿注意事项
  • 基于Alibaba Cloud Linux + 宝塔面板安装 LibreOffice 全攻略流程
  • 怎么实现pid隔离
  • 海信IP810N-72UB0贵州联通原机分区备份包
  • mysql 合集
  • TLE9893-2QKW62S新建Keil MDK工程
  • cursor使用mcp
  • 智能门禁的项目
  • 用 Python 打造你的专属虚拟试衣间!——AI+AR 如何改变时尚体验
  • 关于CSDN和Github的操作
  • vtk管线
  • 递归:JavaScript中的强大工具
  • Java 继承(上)
  • 使用Auto-Coder对js文件进行审计并修复漏洞 1.5版本
  • leetcode 53. 最大子数组和
  • How API Gateways handle raw TCP packets
  • Python解压多种格式压缩包
  • 【git】 pull + rebase 或 pull + merge什么区别?
  • Java 继承(下)
  • LVS负载均衡群集技术深度解析
  • 三天掌握PyTorch精髓:从感知机到ResNet的快速进阶方法论
  • 《计算机组成原理》第 2 章 - 计算机的发展及应用​
  • 【Seata分布式事务源码分析】
  • 用python制作一个五子棋游戏
  • 【大模型微调】魔搭社区GPU进行LLaMA-Factory微调大模型自我认知
  • COMSOL三维梯度多孔结构流体流动模拟
  • eda学习前传又名电赛Day01
  • 2025年渗透测试面试题总结-匿名[实习]安全技术研究员(题目+回答)
  • Cesium 透明渐变墙 解决方案
  • 【C/C++】环形缓冲区:高效数据流转核心