开发者

SpringBoot 整合 Langchain4j AIService 深度使用操作实战教程

目录
  • 一、前言
  • 二、AIService 介绍
    • 2.1 AiService 是什么
    • 2.2 AiService 主要功能
    • 2.3 AiService 使用步骤
  • 三、AIService 操作实践
    • 3.1 前置准备
      • 3.1.1 获取apikey
      • 3.1.2 导入核心依赖
      • 3.1.3 添加配置文件
      • 3.1.4 前置导入案例
    • 3.2 AIService 案例操作详解
      • 3.2.1 入门案例使用
      • 3.2.2 简化写法
      • 3.2.3 问题说明
    • 3.3 AIService 高级用法
      • 3.3.1 @SystemMessage 注解使用
      • 3.3.2 添加测试接口
      • 3.3.3 接口效果测试
    • 3.4 AIService 原理解读
      • 3.4.1 AIService 核心原理
      • 3.4.2 AIService 代码跟踪
  • 四、写在文末

    一、前言

    LangChain4j 是一个基于 Java 的框架,旨在简化与大型语言模型(LLMs)的集成和应用开发。它提供了丰富的工具和组件,帮助开发者快速构建基于 LLM 的应用程序,如聊天机器人、问答系统、文本生成等。利用LangChain4j ,SpringBoot微服务应用可以快速实现对接市场上各种主流大模型的能力,从而快速验证业务的价值,本文以LangChain4j 中一个非常核心的与大模型交互的组件AIService 为例进行详细的说明。

    二、AIService 介绍

    2.1 AiService 是什么

    AiService 是 LangChain4j 中的一个核心组件,用于将 AI 模型(如 OpenAI、通义千问,DeepSeek,Hugging Face 等)的能力封装为服务接口,方便开发者调用。通过 AiService,开发者可以轻松地将 AI 模型集成到应用程序中,而无需直接处理复杂的模型调用和数据处理逻辑。

    SpringBoot 整合 Langchain4j AIService 深度使用操作实战教程

    2.2 AiService 主要功能

    AiService 主要提供了如下的功能:

    • 模型调用封装:
      • AiService 将 AI 模型的调用逻辑封装为简单的 Java 接口,开发者只需定义接口方法即可调用模型。
    • 自动请求/响应处理:
      • AiService 会自动处理输入数据的预处理和输出数据的后处理,简化开发流程。
    • 多模型支持:
      • 支持多种 AI 模型(如 GPT、BERT 等),并可以根据需要切换模型。
    • 异步调用:
      • 支持异步调用 AI 模型,提升应用程序的性能和响应速度。

    2.3 AiService 使用步骤

    AiService 在实际开发使用中,遵循下面的几步即可:

    • 定义服务接口:创建一个 Java 接口,定义需要调用的 AI 模型功能。
    • 配置模型:在配置文件中指定使用的 AI 模型及其参数。
    • 创建服务实例:通过 AiService 创建服务实例。
    • 调用服务:通过服务实例调用定义的方法,获取 AI 模型的输出。

    通过 AiService,开发者可以更高效地将 AI 能力集成到 Java 应用程序中,降低开发复杂度,提升开发效率。

    三、AIService 操作实践

    3.1 前置准备

    3.1.1 获取apikey

    为了方便与大模型交互,本文案例使用阿里云百炼平台进行对接,所以需要先去百炼大模型平台获取apikey,操作入口:大模型服务平台百炼控制台

    SpringBoot 整合 Langchain4j AIService 深度使用操作实战教程

    3.1.2 导入核心依赖

    创建一个springboot 工程,并导入下面的核心依赖

    <properties>
         <maven.compiler.source>17</maven.compiler.source>
         <maven.compiler.target>17</maven.compiler.target>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
         <spring-boot.version>3.2.6</spring-boot.version>
         <langchain4j.version>1.0.0-beta3</langchain4j.version>
         <myBATis-plus.version>3.5.11</mybatis-plus.version>
     </properties>
     <dependencies>
         <!-- web应用程序核心依赖 -->
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-web</artifactId>
         </dependency>
         <!-- 编写和运行测试用例 -->
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-test</artifactId>
             <scope>test</scope>
         </dependency>
         <!-- 接入阿里云百炼平台 -->
         <dependency>
             <groupId>dev.langchain4j</groupId>
             <artifactId>langchain4j-community-dashscope-spring-boot-starter</artifactId>
         </dependency>
         <!--langchain4j高级功能-->
         <dependency>
             <groupId>dev.langchain4j</groupId>
             <artifactId>langchain4j-spring-boot-starter</artifactId>
         </dependency>
     </dependencies>
     <dependencyManagement>
         <dependencies>
             <!--引入SpringBoot依赖管理清单-->
             <dependency>
                 <groupId>org.springframework.boot</grpythonoupId>
                 <artifactId>spring-boot-dependencies</artifactId>
                 <version>${spring-boot.version}</version>
                 <type>pom</type>
                 <scope>import</scope>
             </dependency>
             <!--引入langchain4j依赖管理清单-->
             <dependency>
                 <groupId>dev.langchain4j</groupId>
                 <artifactId>langchain4j-bom</artifactId>
                 <version>${langchain4j.version}</version>
                 <type>pom</type>
                 <scope>import</scope>
             </dependency>
             <!--引入百炼依赖管理清单-->
             <dependency>
                 <groupId>dev.langchain4j</groupId>
                 <artifactId>langchain4j-community-bom</artifactId>
                 <version>${langchain4j.version}</version>
                 <type>pom</type>
                 <scope>import</scope>
             </dependency>
         </dependencies>
     </dependencyManagement>

    3.1.3 添加配置文件

    在工程的配置文件中添加下面的配置信息

    server:
      port: 8082
    #直接对接的是deepseek官网的的大模型
    langchain4j:
      #阿里百炼平台的模型
      community:
        dashscope:
          chat-model:
            api-key: 你的apikey  #这个是白炼平台的apikey
            model-name: qwen-max
    logging:
      level:
        root: debug

    3.1.4 前置导入案例

    还记得在之前学习Langchain4j与大模型整合进行对话时,像下面的这样的接口写法:

    package com.congge.controller;
    import dev.langchain4j.community.model.dashscope.QwenChatModel;
    import dev.langchqepcKDDain4j.model.openai.OpenAiChatModel;
    import dev.langchain4j.model.output.Response;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    import java.net.URI;
    @RestController
    @RequestMapping("/qwen")
    public class QwenCahtcontroller {
        @Autowired
        private QwenChatModel qwenChatModel;
        //localhost:8082/qwen/chat?question=你是谁
        @GetMapping("/chat")
        public Object chat(@RequestParam("question") String question){
            String chat = qwenChatModel.chat(question);
            return chat;
        }
    }

    调用一下接口,可以得到预期的结果

    SpringBoot 整合 Langchain4j AIService 深度使用操作实战教程

    尽管大模型给出了回复,但是细心的同学会发现,这种方式的实现,很明显在调用chat方法的时候需要依赖具体的模型提供商,假如说本次使用的是千问大模型,下一次如果更换为openai大模型,再下一次更换为deepseek的话,代码是不是就需要调整了,这么来看,使用这种方式是存在一定的局限性的,于是在Langchain4j中,还提供了另一种更为简单灵活,并且更优雅的实现方式,即使用AIService 这个组件。

    3.2 AIService 案例操作详解

    官方文档:AI Services | LangChain4j

    SpringBoot 整合 Langchain4j AIService 深度使用操作实战教程

    3.2.1 入门案例使用

    参考官方文档可以看到,AIService 的使用很简单。首先需要定义一个接口,里面定义一个chat方法,然后基于AiServices 这个对象创建chat方法所在的接口代理对象,最后就可以调用这个chat方法与大模型进行对话了。

    1)定义一个接口

    如下,自定义一个接口,里面有一个chat方法

    package com.congge.assistant;
    public interface Assistant {
        String chat(String userMessage);
    }

    2)添加测试接口

    添加一个测试接口,从下面这段代码不难看出,使用这种方式,其核心就是通过AiServices这个对象创建出接口的带理对象,然后再由带理对象调用chat方法,相比传统的方式,这样的写法显得更加灵活便捷

    package com.congge.controller;
    import com.congge.assistant.Assistant;
    //import com.congge.assistant.QwenAssistant;
    import dev.langchain4j.community.model.dashscope.QwenChatModel;
    import dev.langchain4j.service.AiServices;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMaphttp://www.devze.comping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    @RestController
    @RequestMapping("/assistant")
    public class AssistantController {
        @Autowired
        private QwenChatModel qwenChatModel;
        //localhost:8082/assistant/chat/v1?userMessage=你是谁
        @GetMapping("/chat/v1")
        public String chat(@RequestParam("userMessage") String userMessage) {
            Assistant assistant = AiServices.create(Assistant.class, qwenChatModel);
            String chatRes = assistant.chat(userMessage);
            return chatRes;
        }
    }

    3)接口效果测试

    启动工程后,调用下接口,可以正常与大模型进行对话

    SpringBoot 整合 Langchain4j AIService 深度使用操作实战教程

    3.2.2 简化写法

    上面这种方式需要通过AiServices对象创建代理对象来调用,实际上,AiService还提供了更简单的方式,即只需要在接口上面增加一个 @AiService注解即可 ,这样就可以直接将接口注入到需要调用的类中就能使用了,简单改造下,如下代码:

    1)接口改造

    package com.congge.assistant;
    import dev.langchain4j.service.spring.AiService;
    @AiService
    public interface Assistant {
        String chat(String userMessage);
    }

    2)测试接口

    改为注入Assistant

    package com.congge.controller;
    import com.congge.assistant.Assistant;
    //import com.congge.assistant.QwenAssistant;
    import dev.langchain4j.community.model.dashscope.QwenChatModel;
    import dev.langchain4j.service.AiServices;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    @RestController
    @RequestMapping("/assistant")
    public class AssistantController {
        @Autowired
        private Assistant assistant;
        //localhost:8082/assistant/chat/v1?userMessage=你是谁
        @GetMapping("/chat/v1")
        public String chat(@RequestParam("userMessage") String userMessage) {
            //Assistant assistant = AiServices.create(Assistant.class, qwenChatModel);
            String chatRes = assistant.chat(userMessage);
            return chatRes;
        }
    }

    3)效果测试

    调用一下接口,可以看到仍然可以得到预期的效果

    SpringBoot 整合 Langchain4j AIService 深度使用操作实战教程

    3.2.3 问题说明

    基于上面的这一步,细心的同学会发现,使用上面带注解的方式改造后,在测试的接口中并没有注入具体的ChatModel,最后也能够正常与大模型对话,这是因为在上面的配置文件中,我们配置的是与百炼的apikey,使用的是千问大模型,所以@AiService 注解就会在上下文环境中查找并自动注入了千问的ChatModel,在@AiService注解源码中也可以看到该注解可以接收一个chatModel的属性

    SpringBoot 整合 Langchain4j AIService 深度使用操作实战教程

    但是假如在你的配置文件中,同时配置了多个大模型厂商的信息,在工程启动的时候报就会报下面找不到ChatModel的错误

    SpringBoot 整合 Langchain4j AIService 深度使用操作实战教程

    遇到这个问题的时候,在控制台中,错误的提示中也给出了解决建议

    SpringBoot 整合 Langchain4j AIService 深度使用操作实战教程

    参照这个提示,接口改造后代码如下:

    package com.congge.assistant;
    import dev.langchain4j.service.spring.AiService;
    import dev.langchain4j.service.spring.AiServiceWiringMode;
    @AiService(wiringMode = AiServiceWiringMode.EXPLICIT, chatModel = "qwenChatModel")
    public interface Assistant {
        String chat(String userMessage);
    }

    再次启动的时候,如果保持配置文件不编程客栈变,仍然配置了多个大模型的信息,此时就不会报错了。

    3.3 AIService 高级用法

    3.3.1 @SystemMessage 注解使用

    AIService 还可以基于接口中的方法,搭配@SystemMessage 注解使用,通过这个注解,可以赋予接口中的方法更灵活的能力,比如在实际使用中,为了将这个chat方法以更灵活的模板方式进行封装,可以通过传入更多的参数,然后以参数的形式传递到模板描述中,如下:

    import dev.langchain4j.service.SystemMessage;
    import dev.langchain4j.service.UserMessage;
    import dev.langchain4j.service.V;
    import dev.langchain4j.service.spring.AiService;
    @AiService
    public interface Assistant {
        //String chat(String userMessage);
        @SystemMessage("你是一个知名的散文作家,根据输入的{{title}},写一篇不超过{{count}}字的散文")
        String chat(@UserMessage String message, @V("title") String title, @V("count") Long count);
    }

    3.3.2 添加测试接口

    增加一个测试接口,可以接收上述新增的方法中的多个参数

    package com.congge.controller;
    import com.congge.assistant.Assistant;
    //import com.congge.assistant.QwenAssistant;
    import dev.langchain4j.community.model.dashscope.QwenChatModel;
    import dev.langchain4j.service.AiServices;
    import org.springframework.beans.factory.annotation.Autowired;javascript
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    @RestController
    @RequestMapping("/assistant")
    public class AssistantController {
        @Autowired
        private Assistant assistant;
        //localhost:8082/assistant/chat/v1?userMessage=歌颂祖国的大好河山&title=歌颂祖国的大好河山&count=300
        @GetMapping("/chat/v1")
        public String chat(
                @RequestParam("userMessage") String userMessage,
                @RequestParam("title") String title,
                @RequestParam("count") Long count) {
            String chatRes = assistant.chat(userMessage, title, count);
            return chatRes;
        }
    }    

    3.3.3 接口效果测试

    调用一下接口,可以看到下面的效果

    SpringBoot 整合 Langchain4j AIService 深度使用操作实战教程

    不难看出,有了@SystemMessage这个注解,在实际的开发中,让对接大模型的程序,在设计上提供了更多的扩展性,也让程序的可定制性增强了,从而让应用更灵活。

    3.4 AIService 原理解读

    3.4.1 AIService 核心原理

    AiServices会组装Assistant接口以及其他组件,并使用反射机制创建一个实现Assistant接口的代理对象。这个代理对象会处理输入和输出的所有转换工作。在上面的案例中,chat方法的输入是一个字符串,但是大模型需要一个 UserMessage 对象。所以,代理对象将这个字符串转换为 UserMessage ,并调用聊天语言模型。chat方法的输出类型也是字符串,但是大模型返回的是 AiMessage 对象,代理对象会将其转换为字符串。

    3.4.2 AIService 代码跟踪

    通过上面的代码演示基本掌握了AIService的用法,下面对其原理做一下详细的说明,方便我们对其底层设计有更深刻的理解,通过 AiServices.create 方法进入到下面的源码中

    public static <T> T create(Class<T> aiService, ChatLanguageModel chatLanguageModel) {
        return builder(aiService).chatLanguageModel(chatLanguageModel).build();
    }

    启动工程后,执行接口调用 ,进入到下面的 new DefaultAiServices 方法

    SpringBoot 整合 Langchain4j AIService 深度使用操作实战教程

    继续往下走,进入到下面的方法,在这个方法中可以看到,需要接收aiService 和 chatLanguageModel

    SpringBoot 整合 Langchain4j AIService 深度使用操作实战教程

    这一步创建完成后,代理对象就有了,最后使用assistant调用chat方法的时候,通过debug源码可以看到,此时的assistant就是一个代理对象了

    SpringBoot 整合 Langchain4j AIService 深度使用操作实战教程

    四、写在文末

    本文通过较大的篇幅详细介绍了Langchain4j中的核心组件AIService的使用,并通过案例演示了其实际的使用过程,希望对看到的同学有用哦,本篇到此结束,感谢观看。

    到此这篇关于SpringBoot 整合 Langchain4j AIService 深度使用操作实战教程的文章就介绍到这了,更多相关SpringBoot Langchain4j AIService使用内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!

    0

    上一篇:

    下一篇:

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    最新开发

    开发排行榜