LangChain4j 入门(二)

news2025/4/5 6:12:53

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-key
        model-name: qwen-max
  1. 创建 ChatController,并编写相关接口
@RestController
@RequestMapping("/chat")
public class ChatController {

    @Autowired
    private 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-max
        api-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() {

            @Override
            public void onPartialResponse(String partialResponse) {
                sink.next(partialResponse);
            }

            @Override
            public void onCompleteResponse(ChatResponse completeResponse) {
                sink.complete();
            }

            @Override
            public void onError(Throwable error) {
                sink.error(error);
            }
        });
    });
    return flux;
}
  1. 测试接口响应

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

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

在这里插入图片描述

案例三 — 图片生成

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

  1. 配置yaml
gen-img:
  api-key: 个人 api-key
  model-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);
    // 具体返回结构可查看官方定义,这里只获取图片的 url
    return 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.coloradmin.cn/o/2325689.html

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

相关文章

npm i 失败

当npm i 失败 且提示下面的错误 尝试降低npm 的版本 npm install npm6.14.15 -g

音视频基础(音视频的录制和播放原理)

文章目录 一、录制原理**1. 音视频数据解析****2. 音频处理流程****3. 视频处理流程****4. 同步控制****5. 关键技术点****总结** 二、播放原理**1. 音视频数据解析****2. 音频处理流程****3. 视频处理流程****4. 同步控制****5. 关键技术点****总结** 一、录制原理 这张图展示…

回溯(子集型):分割回文串

一、多维递归 -> 回溯 1.1&#xff1a;17. 电话号码的字母组合(力扣hot100&#xff09; 代码&#xff1a; mapping ["","", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv&qu…

2022年蓝桥杯第十三届CC++大学B组真题及代码

目录 1A&#xff1a;九进制转十进制 2B&#xff1a;顺子日期&#xff08;存在争议&#xff09; 3C&#xff1a;刷题统计 解析代码&#xff08;模拟&#xff09; 4D&#xff1a;修剪灌木 解析代码&#xff08;找规律&#xff09; 5E&#xff1a;X进制减法 解析代码1&…

1.oracle修改配置文件

1.找到oracle的安装路径 D:\app\baozi\product\11.2.0\dbhome_1\NETWORK\ADMIN &#xff0c;修改下面的两个文件。如果提示没有权限&#xff0c;可以先把这两个文件复制到桌面&#xff0c;修改完后&#xff0c;在复制回来。 2.查看自己电脑的主机名&#xff0c; 右击 - 此电脑 …

通义万相2.1 你的视频创作之路

通义万相2.1的全面介绍 一、核心功能与技术特点 通义万相2.1是阿里巴巴达摩院研发的多模态生成式AI模型&#xff0c;以视频生成为核心&#xff0c;同时支持图像、3D内容及中英文文字特效生成。其核心能力包括&#xff1a; 复杂动作与物理规律建模 能够稳定生成包含人体旋转、…

Muduo网络库实现 [四] - Channel模块

设计思路 具体来说每一个套接字都会对应一个 Channel 对象&#xff0c;用于对它的事件进行管理。可以对于描述符的监控事件在用户态更容易维护&#xff0c;以及触发事件后的操作流程更加的清晰 Channel模块是用于对一个描述符所需要监控的事件以及事件触发之后要执行的回调函…

XSS 攻击(详细)

目录 引言 一、XSS 攻击简介 二、XSS 攻击类型 1.反射型 XSS 2.存储型 XSS 3.基于 DOM 的 XSS 4.Self - XSS 三、XSS 攻击技巧 1.基本变形 2.事件处理程序 3.JS 伪协议 4.编码绕过 5.绕过长度限制 6.使用标签 四、XSS 攻击工具与平台 1.XSS 攻击平台 2.BEEF 五…

《ZooKeeper Zab协议深度剖析:构建高可用分布式系统的基石》

《ZooKeeper Zab协议深度剖析:构建高可用分布式系统的基石》 一、分布式协调的挑战与ZooKeeper的解决方案 1.1 分布式系统一致性难题 #mermaid-svg-iigak7YlgEw7o6lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-sv…

OpenCV 图形API(6)将一个矩阵(或图像)与一个标量值相加的函数addC()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 addC 函数将给定的标量值加到给定矩阵的每个元素上。该功能可以用矩阵表达式替换&#xff1a; dst src1 c \texttt{dst} \texttt{src1} \te…

同步SVPWM调制策略的初步学习记录

最近项目需要用到一些同步调制SVPWM相关的内容&#xff08;现在的我基本都是项目驱动了&#xff09;&#xff0c;因此对该内容进行一定的学习。 1 同步SVPWM调制的背景 我们熟知的一些知识是&#xff1a;SVPWM&#xff08;空间矢量脉宽调制&#xff09;是一种用于逆变器的调制…

排序算法3-交换排序

目录 1.常见排序算法 2.排序算法的预定函数 2.1交换函数 2.2测试算法运行时间的函数 2.3已经实现过的排序算法 3.交换排序的实现 3.1冒泡排序 3.2快速排序 3.2.1递归的快速排序 3.2.1.1hoare版本的排序 3.2.1.2挖坑法 3.2.1.3lomuto前后指针法 3.2.2非递归版本的快…

【Qt】数据库管理

数据库查询工具开发学习笔记 一、项目背景与目标 背景&#xff1a;频繁编写数据库查询语句&#xff0c;希望通过工具简化操作&#xff0c;提升效率。 二、总体设计思路 1. 架构设计 MVC模式&#xff1a;通过Qt控件实现视图&#xff08;UI&#xff09;&#xff0c;业务逻辑…

Ant Design Vue 中的table表格高度塌陷,造成行与行不齐的问题

前言&#xff1a; Ant Design Vue: 1.7.2 Vue2 less 问题描述&#xff1a; 在通过下拉框选择之后&#xff0c;在获取接口数据&#xff0c;第一列使用了fixed:left&#xff0c;就碰到了高度塌陷&#xff0c;查看元素的样式结果高度不一致&#xff0c;如&#x…

【qt】文件类(QFile)

很高兴你能看到这篇文章&#xff0c;同时我的语雀文档也更新了许多嵌入式系列的学习笔记希望能帮到你 &#xff1a; https://www.yuque.com/alive-m4b9n 目录 QFile 主要功能QFile 操作步骤QFile 其他常用函数案例分析及实现功能一实现&#xff1a;打开文件并显示功能二实现:另…

3. 实战(一):Spring AI Trae ,助力开发微信小程序

1、前言 前面介绍了Spring boot快速集成Spring AI实现简单的Chat聊天模式。今天立马来实战一番&#xff0c;通过Trae这个火爆全网的工具&#xff0c;来写一个微信小程序。照理说&#xff0c;我们只是极少量的编码应该就可以完成这项工作。开撸~ 2、需求描述 微信小程序实现一…

UE5新材质系统效果Demo展示

1、玉质材质&#xff0c;透明玻璃材质&#xff0c;不同透射和散射。 2、浅水地面&#xff0c;地面层&#xff0c;水层&#xff0c;地面湿度&#xff0c;水面高度&#xff0c;水下扰动&#xff0c;水下浇洒&#xff0c;水下折射 Substrate-Water Substrate-Water-CodeV2

wps 怎么显示隐藏文字

wps 怎么显示隐藏文字 》文件》选项》视图》勾选“隐藏文字” wps怎么设置隐藏文字 wps怎么设置隐藏文字

CXL UIO Direct P2P学习

前言&#xff1a; 在CXL协议中&#xff0c;UIO&#xff08;Unordered Input/Output&#xff09; 是一种支持设备间直接通信&#xff08;Peer-to-Peer, P2P&#xff09;的机制&#xff0c;旨在绕过主机CPU或内存的干预&#xff0c;降低延迟并提升效率。以下是UIO的核心概念及UI…

leetcode138.随即链表的复制

思路源于 【力扣hot100】【LeetCode 138】随机链表的复制&#xff5c;哈希表 采用一个哈希表&#xff0c;键值对为<原链表的结点&#xff0c;新链表的结点>&#xff0c;第一次遍历原链表结点时只创建新链表的结点&#xff0c;第二次遍历原链表结点时&#xff0c;通过键拿…