LangChain4j 入门(二)

LangChain 整合 SpringBoot

下述代码均使用 阿里云百炼平台 提供的模型。

创建项目,引入依赖

  1. 通过 IDEA 创建 SpringBoot 项目,并引入 Spring Web 依赖,SpringBoot 推荐使用 3.x 版本。

    在这里插入图片描述
  2. 引入 LangChain4j 和 WebFlux 依赖
<!--阿里云 DashScope API(通义大模型)的 Spring Boot Starter 依赖-->
<dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-community-dashscope-spring-boot-starter</artifactId><version>1.0.0-beta2</version>
</dependency>
<!--LangChain4j 的核心库-->
<dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j</artifactId><version>1.0.0-beta2</version>
</dependency>
<!--Spring WebFlux 依赖-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

案例一 — 普通对话

该示例为整体返回,即等待模型回复完成后,一起进行返回。

  1. 配置 yaml
langchain4j:community:dashscope:chat-model:api-key: 个人 api-keymodel-name: qwen-max
  1. 创建 ChatController,并编写相关接口
@RestController
@RequestMapping("/chat")
public class ChatController {@Autowiredprivate ChatLanguageModel chatLanguageModel;@RequestMapping("/test1")public String test1(@RequestParam(defaultValue = "你好") String message) {String response = chatLanguageModel.chat(message);return response;}
}
  1. 测试接口响应

浏览器中访问:http://localhost:8080/chat/test1?message=你好,你是谁,如果有响应类似下述内容,则说明成功。
在这里插入图片描述

案例二 — 流式对话

上述示例用户体验并不好,本示例采用流式返回

  1. 配置 yaml
langchain4j:community:dashscope:streaming-chat-model:model-name: qwen-maxapi-key: 个人 api-key
  1. 编写相关接口
@Autowired
private StreamingChatLanguageModel streamingChatLanguageModel;// 指定 produces,否则会出现乱码情况
@RequestMapping(value = "/test2", produces = "text/stream;charset=UTF-8")
public Flux<String> test2(@RequestParam(defaultValue = "你好") String message) {Flux<String> flux = Flux.create(sink -> {streamingChatLanguageModel.chat(message, new StreamingChatResponseHandler() {@Overridepublic void onPartialResponse(String partialResponse) {sink.next(partialResponse);}@Overridepublic void onCompleteResponse(ChatResponse completeResponse) {sink.complete();}@Overridepublic void onError(Throwable error) {sink.error(error);}});});return flux;
}
  1. 测试接口响应

浏览器中访问:http://localhost:8080/chat/test2?message=你好,你是谁,如果有响应类似下述内容,则说明成功。

本案例与案例一的区别为输出方式不同,一种是整体输出,一种是流式输出。

在这里插入图片描述

案例三 — 图片生成

百炼平台提供500张图片的免费额度用于学习。
本案例采用同步的方式获取图片,也可以按照官方文档采用异步方式进行图片获取。

  1. 配置yaml
gen-img:api-key: 个人 api-keymodel-name: wanx2.1-t2i-turbo
  1. 配置 WanxImageModel,编写相关接口
@Configuration
public class AIConfig {@Value("${gen-img.api-key}")private String genImgApiKey;@Value("${gen-img.model-name}")private String genImgModelName;@Bean/*** 图片绘制模型*/public WanxImageModel wanxImageModel() {return WanxImageModel.builder().apiKey(genImgApiKey).modelName(genImgModelName).build();}
}
@Autowired
private WanxImageModel wanxImageModel;@RequestMapping("/test3")
public String test3(@RequestParam(defaultValue = "午后的公园") String message) {Response<Image> generate = wanxImageModel.generate(message);// 具体返回结构可查看官方定义,这里只获取图片的 urlreturn generate.content().url().toString();
}
  1. 测试接口响应

在浏览器中输入:http://localhost:8080/chat/test3?message=雨后的公园
下图中返回数据为生成图片的 url,使用浏览器访问该 url,可以在浏览器中下载生成后的图片。
在这里插入图片描述
生成的图片如下:
在这里插入图片描述

案例四 — 记忆对话

  1. 配置 AiService 相关对象
// 定义聊天助手接口
public interface MyAssistant {String chat(String message);TokenStream stream(String message);
}@Bean
public MyAssistant assistant(ChatLanguageModel qwenChatModel, StreamingChatLanguageModel qwenStreamingChatModel) {MyAssistant assistant = AiServices.builder(MyAssistant.class).chatLanguageModel(qwenChatModel).streamingChatLanguageModel(qwenStreamingChatModel).chatMemory(MessageWindowChatMemory.withMaxMessages(20))// 自定义对话存储方式
//                .chatMemoryProvider(memoryId -> MessageWindowChatMemory
//                        .builder()
//                        .chatMemoryStore(new ChatMemoryStore() {
//                            @Override
//                            public List<ChatMessage> getMessages(Object memoryId) {
//                                return null;
//                            }
//
//                            @Override
//                            public void updateMessages(Object memoryId, List<ChatMessage> messages) {
//
//                            }
//
//                            @Override
//                            public void deleteMessages(Object memoryId) {
//
//                            }
//                        }
//                ).build()).build();return assistant;
}
  1. 编写接口,采用流式返回
@Autowired
private AIConfig.MyAssistant assistant;@RequestMapping(value = "/test4", produces = "text/stream;charset=UTF-8")
public Flux<String> test4(@RequestParam(defaultValue = "你好") String message) {TokenStream stream = assistant.stream(message);return Flux.create(sink -> {stream.onPartialResponse(sink::next).onCompleteResponse(c -> sink.complete()).onError(sink::error).start();});
}
  1. 测试接口响应
    1. 直接进行询问
      在这里插入图片描述

    2. 通过接口给模型写入记忆在这里插入图片描述

    3. 根据写入记忆,进行对话
      在这里插入图片描述

上述聊天信息默认存储在内存中,程序重启后会丢失记忆,可以重写被注释掉的内容,将信息存储到 mysql、redis等存储容器中。

案例五 — 记忆对话,数据隔离

上述案例中,所有的问答都是混合到一起的,即 A 对模型输入的信息,B 也可以读取到,本案例将通过 memoryId 对记忆数据进行隔离。

  1. 配置 AiService 相关对象
public interface MyAssistantIsolate {String chat(@MemoryId String memoryId, @UserMessage String message);TokenStream stream(@MemoryId String memoryId, @UserMessage String message);
}@Bean
public MyAssistantIsolate myAssistantMemory(ChatLanguageModel qwenChatModel, StreamingChatLanguageModel qwenStreamingChatModel) {ChatMemoryProvider chatMemoryProvider = memoryId -> MessageWindowChatMemory.builder().id(memoryId).maxMessages(20)// 自定义对话存储方式
//                .chatMemoryStore(new ChatMemoryStore() {
//                    @Override
//                    public List<ChatMessage> getMessages(Object memoryId) {
//                        return null;
//                    }
//
//                    @Override
//                    public void updateMessages(Object memoryId, List<ChatMessage> messages) {
//
//                    }
//
//                    @Override
//                    public void deleteMessages(Object memoryId) {
//
//                    }
//                }).build();MyAssistantIsolate assistant = AiServices.builder(MyAssistantIsolate.class).chatLanguageModel(qwenChatModel).streamingChatLanguageModel(qwenStreamingChatModel).chatMemoryProvider(chatMemoryProvider).build();return assistant;
}
  1. 编写接口
@Autowired
private AIConfig.MyAssistantIsolate myAssistantIsolate;@RequestMapping(value = "/test5", produces = "text/stream;charset=UTF-8")
// 通过不同的 memoryId 对记忆进行分割,memoryId 可以使用 userId 或 uuid
public Flux<String> test5(String memoryId, String message) {TokenStream stream = myAssistantIsolate.stream(memoryId, message);return Flux.create(sink -> {stream.onPartialResponse(sink::next).onCompleteResponse(c -> sink.complete()).onError(sink::error).start();});
}
  1. 测试接口响应
    1. 给 memoryId = 1,设置记忆信息
      在这里插入图片描述
    2. 通过 memoryId = 1,查询记忆信息
      在这里插入图片描述
    3. 通过 memoryId = 2,查询记忆信息
      在这里插入图片描述

上述内容为 LangChain4j 整合 SpringBoot 的基本示例。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/74048.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

3.30学习总结 Java包装类+高精度算法+查找算法

包装类&#xff1a; 基本数据类型对应的引用数据类型。 基本数据类型&#xff1a;在内存中记录的是真实的值。 八种包装类的父类都是Object类。 对象之间不能直接进行计算。 JDK5之后可以把int和integer看成一个东西&#xff0c;因为会进行内部优化。自动装箱和自动拆箱。 …

centos 7 LVM管理命令

物理卷&#xff08;PV&#xff09;管理命令 pvcreate&#xff1a;用于将物理磁盘分区或整个磁盘创建为物理卷。 示例&#xff1a;sudo pvcreate /dev/sdb1 解释&#xff1a;将 /dev/sdb1 分区创建为物理卷。 pvdisplay&#xff1a;显示物理卷的详细信息&#xff0c;如大小、所属…

借助FastAdmin和uniapp,高效搭建AI智能平台

在数字化办公时代&#xff0c;效率与协作是企业发展的核心竞争力。传统的办公工具虽然功能丰富&#xff0c;但在面对复杂多变的团队协作需求时&#xff0c;往往显得力不从心。为了解决这一痛点&#xff0c;我们推出了一款全新的办公AI平台&#xff0c;它不仅能够满足文字和语音…

项目上传github——SSH连接配置文档

1. 检查是否已有 SSH 密钥 打开终端&#xff0c;检查是否已经存在 SSH 密钥对&#xff1a; ls ~/.ssh如果你看到类似 id_rsa 和 id_rsa.pub 的文件&#xff0c;说明你已经有 SSH 密钥。否则&#xff0c;继续下一步。 2. 生成 SSH 密钥 如果你没有 SSH 密钥&#xff0c;使用…

传奇类网游页游2.5D游戏场景地图素材Eagle库 沙漠沙海隔壁

传奇类网游页游2.5D游戏场景地图素材Eagle库 沙漠沙海隔壁 链接: https://pan.baidu.com/s/1GY8N-KEkHBGEbS7uxrE4Dg 提取码: yrs8 备用下载地址&#xff1a;http://pan.1234f.com:5212/s/rLzIp 电子资料文档&#xff1a;https://www.1234f.com/sj/GitHub/sucai/20250327/1323…

通过TIM+DMA Burst 实现STM32输出变频且不同脉冲数量的PWM波形

Burst介绍&#xff1a; DMA控制器可以生成单次传输或增量突发传输&#xff0c;传输的节拍数为4、8或16。 为了确保数据一致性&#xff0c;构成突发传输的每组传输都是不可分割的&#xff1a;AHB传输被锁定&#xff0c;AHB总线矩阵的仲裁器在突发传输序列期间不会撤销DMA主设备…

鸿蒙学习手册(HarmonyOSNext_API16)_数据持久化③:关系型数据库

概述 关系型数据库&#xff1a;像“Excel表格联合作战”的管家 关系型数据库就像一个超级智能的表格管理系统&#xff0c;专门处理数据之间有复杂关联的情况。比如学生和成绩、订单和商品、用户和评论——这些数据像蜘蛛网一样相互连接&#xff0c;用键值数据库的“独立抽屉”…

Windows 11 VS Code C/C++ 开发环境搭建——一种尽量“绿色”的方法

我的电脑是Windows 11 系统&#xff0c;安装了Visual Studio Code&#xff0c;在上面搭建C/C开发环境&#xff0c;当然&#xff0c;这需要用到MinGW之流了。作为一个绿色爱好者&#xff08;帽子除外&#xff09;&#xff0c;我也尽量绿色地架设这样一个环境…… 第一步&#x…

mysql-分区和性能

mysql自身只支持表的横向分区。 常听到开发人员说“”对表做个分区“&#xff0c;然后数据的查询就会快了。这是真的吗&#xff1f;实际上可能跟根本感觉不到查询速度的提升&#xff0c;甚至会发现查询速度急剧下降。因此&#xff0c;在合理使用分区之前&#xff0c;必须了解分…

DeepSeek协助优化-GTX750Ti文物显卡0.65秒卷完400MB float 音频512阶时域FIR

文章目录 1. 学习目的2. 阶段成果2.1 NVVP 性能探查2.2 测试编译环境2.3 测试样例 3 学习过程3.1 提问DeepSeek3.2 最终代码 4. 体会 1. 学习目的 最近在学习cuda&#xff0c;准备给我的taskBus SDR添加CUDA的模块支持&#xff0c;以便可以用PC机压榨山寨 B210那56M的带宽。 因…

RabbitMQ高级特性--TTL和死信队列

目录 1.TTL 1.1设置消息的TTL 1.1.1配置交换机&队列 1.1.2发送消息 1.1.3运行程序观察结果 1.2设置队列的TTL 1.2.1配置队列和交换机的绑定关系 1.2.2发送消息 1.2.3运行程序观察结果 1.3两者区别 2.死信队列 2.1 声名队列和交换机 2.2正常队列绑定死信交换机 …

【JavaEE】UDP数据报套接字编程

目录 网络编程基础 基本概念 发送端和接收端 请求和响应 客户端和服务端 常见的客户端服务端模型 Socket套接字 TCP/UDP特点 Java数据报套接字通信模型(UDP通信) UDP数据报套接字编程 DatagramSocket 1.类定义 2.构造方法 3.核心方法 4.特性说明 DatagramPacke…

Spring Boot 3.4.3 基于 SpringDoc 2 和 Swagger 3 实现项目接口文档管理

在现代企业级应用开发中&#xff0c;前后端分离已成为主流模式&#xff0c;前端负责界面呈现&#xff0c;后端专注提供 RESTful API 接口。然而&#xff0c;接口文档的编写和维护往往是开发过程中的痛点。Spring Boot 3.4.3 结合 SpringDoc 2 和 Swagger 3&#xff0c;为开发者…

构建大语言模型应用:数据准备(第二部分)

本专栏通过检索增强生成&#xff08;RAG&#xff09;应用的视角来学习大语言模型&#xff08;LLM&#xff09;。 本系列文章 简介数据准备&#xff08;本文&#xff09;句子转换器向量数据库搜索与检索大语言模型开源检索增强生成评估大语言模型服务高级检索增强生成 RAG 如上…

Linux 随机数据生成

目录 一. /dev/urandom1.1 dd 命令1.2 head命令1.3 随机字母 二. openssl 命令三. yes命令 一. /dev/urandom ⏹/dev/urandom 是 Linux 和 Unix 系统中的一个特殊文件&#xff0c;它是一个伪随机数生成器&#xff0c;用于提供高吞吐量的随机数据。 1.1 dd 命令 bs1M count10…

项目如何安装本地tgz包并配置局部registry

一、判断包来源是否正确 1. 检查url curl <registry_url>2. 查看包是否存在 npm view <package_name> --registry<registry_url>二、局部registry配置步骤&#xff1a; 1. 全局配置 如果你希望对所有项目生效&#xff0c;可以将这行配置添加到全局.npmr…

QCustomPlot入门

QCustomPlot 是一个基于 Qt 的 C++ 绘图库,专注于高效、美观的 2D 数据可视化。进入QCustomPlot下载页,下载最新的完整包(包含:源码、文档、示例)。 一、核心架构设计 1. 分层架构模型 层级主要组件职责说明用户接口层QCustomPlot 类提供顶层API,管理所有子组件逻辑控制…

C语言快速入门-C语言基础知识

这个c语言入门&#xff0c;目标人群是有代码基础的&#xff0c;例如你之前学过javaSE&#xff0c;看此文章可能是更有帮助&#xff0c;会让你快速掌握他们之间的差异&#xff0c;文章内容大部分都是泛谈&#xff0c;详细的部分我会在之后时间发布&#xff0c;我也在慢慢学习&am…

【商城实战(91)】安全审计与日志管理:为电商平台筑牢安全防线

【商城实战】专栏重磅来袭!这是一份专为开发者与电商从业者打造的超详细指南。从项目基础搭建,运用 uniapp、Element Plus、SpringBoot 搭建商城框架,到用户、商品、订单等核心模块开发,再到性能优化、安全加固、多端适配,乃至运营推广策略,102 章内容层层递进。无论是想…

信息安全工程师第 1 章

《信息安全工程师教程(第2版)》第一章 一、网络信息安全基本概念与重要性 网络信息安全定义 狭义:保障信息系统的机密性(C)、完整性(I)、可用性(A)——CIA三性。广义:涵盖国家安全、经济安全、社会安全等的“大安全”。法律依据:《网络安全法》定义网络安全为防范攻…