欢迎光临
我们一直在努力

LangChain4j实战之九:高级API(AI Services)实例的创建方式

欢迎访问我的GitHub

这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos

LangChain4j实战全系列链接

  • 准备工作
  • 极速开发体验
  • 细说聊天API
  • 集成到spring-boot
  • 图像模型
  • 聊天记忆,低级API版
  • 聊天记忆,高级API版
  • 响应流式传输
  • 高级API(AI Services)实例的创建方式
  • 本篇概览

    • 高级API:在LangChain4j中,高级API是指我们自己创建一个接口,然后LangCh4j负责创建该接口的实现类,此实现类的方法其实都是在调用大模型的服务,举例如下,Assistant接口是我们自己创建的,然后调用Assistant实现类的方法simpleChat,实际上就是调用了大模型的对话服务,返回值就是对话结果 在这里插入图片描述

    • 本篇目标是学习是如何创建高级API服务类实例,也就是上图的第二步,可见上图的做法是调用AiServices.create方法得到实例,但这只是其中的一种方式,总共有三种方式,另外两种方式是我们要学习的东西

    • 共有三种方式可以创建高级API(AI Services)实例,整理如下,前面咱们用到的是第一种 在这里插入图片描述

    • 接下来的咱们来一起体验方法二和方法三,看看这些方法中哪个最适合您

    方法二和方法三为什么不用创建AiServices实例

    • 如下图红框,可见方法一需要写代码创建AiServices实例,但是方法二和方法三都不需要,这也是它们最大的区别 在这里插入图片描述

    • 由于方法二和三都用了AiService注解,看看AiService的源码,如下图黄色箭头,原来如此,AiService包含了Service注解,因此AiService修饰的接口会被创建为bean 在这里插入图片描述

    方法二,代码+注解

    • 先看方法二的步骤,如下图 在这里插入图片描述
    • 总结方法二的三个重点:
  • 需要配置类
  • 要写代码来创建模型服务的实例
  • 不用写代码来创建AiService实例
    • 通过前面的对比可见,方法二相比方法一少写了创建AiService实例的代码,就是下图中的第二步 在这里插入图片描述
    • 方法二的关键是:通过写代码的方式在配置类中准备好模型类的bean,这是给高级API服务类实例用的,但是高级API服务类实例本身只要用@AiService注解就行了,不需要写代码创建
    • 接下来创建个真实的项目来体验一下吧,《准备工作》中创建了整个《LangChain4j实战》系列代码的父工程,现在在父工程下新建名为ai-service-code-and-annonation的子工程,pom.xml如下

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <parent>
    <groupId>com.bolingcavalry</groupId>
    <artifactId>langchain4j-totorials</artifactId>
    <version>1.0-SNAPSHOT</version>
    </parent>

    <artifactId>ai-service-code-and-annonation</artifactId>
    <packaging>jar</packaging>

    <dependencies>
    <!– Lombok –>
    <dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
    </dependency>

    <!– Spring Boot Starter –>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
    </dependency>

    <!– Spring Boot Web –>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!– Spring Boot Test –>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
    </dependency>

    <!– JUnit Jupiter Engine –>
    <dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-engine</artifactId>
    <scope>test</scope>
    </dependency>

    <!– Mockito Core –>
    <dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <scope>test</scope>
    </dependency>

    <!– Mockito JUnit Jupiter –>
    <dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-junit-jupiter</artifactId>
    <scope>test</scope>
    </dependency>

    <!– LangChain4j Core –>
    <dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j-core</artifactId>
    </dependency>

    <!– LangChain4j OpenAI支持(用于通义千问的OpenAI兼容接口) –>
    <dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j-open-ai</artifactId>
    </dependency>

    <!– 官方 langchain4j(包含 AiServices 等服务类) –>
    <dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j</artifactId>
    </dependency>

    <dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j-community-dashscope</artifactId>
    </dependency>

    <dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j-spring-boot-starter</artifactId>
    </dependency>

    <!– 日志依赖由Spring Boot Starter自动管理,无需单独声明 –>
    </dependencies>

    <build>
    <plugins>
    <!– Spring Boot Maven Plugin –>
    <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <version>3.3.5</version>
    <executions>
    <execution>
    <goals>
    <goal>repackage</goal>
    </goals>
    </execution>
    </executions>
    </plugin>
    </plugins>
    </build>

    </project>

    • 在父工程的pom.xml中加入新增的子工程 在这里插入图片描述

    • langchain4j-totorials/ai-service-code-and-annonation/src/main/resources新增配置文件application.properties,内容如下,主要是三个模型的配置信息,记得把your-api-key换成您自己的apikey

    # Spring Boot 应用配置
    server.port=8080
    server.servlet.context-path=/

    # LangChain4j 配置通义千问模型
    # 注意:请将your-api-key替换为您实际的通义千问API密钥
    langchain4j.open-ai.chat-model.api-key=your-api-key
    # 通义千问模型名称
    langchain4j.open-ai.chat-model.model-name=qwen3-max
    # 通义千问OpenAI兼容接口地址
    langchain4j.open-ai.chat-model.base-url=https://dashscope.aliyuncs.com/compatible-mode/v1

    # 日志配置
    logging.level.root=INFO
    logging.level.com.bolingcavalry=DEBUG
    logging.pattern.console=%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} – %msg%n
    # 应用名称
    spring.application.name=ai-service-code-and-annonation

    • 启动类没啥好说的

    package com.bolingcavalry;

    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;

    /**
    * Spring Boot应用程序的主类
    */

    @SpringBootApplication
    public class Application {

    public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
    }
    }

    • 创建一个自定义接口Assistant.java,该接口用AiService注解修饰,这样LangChain2j的starter就会创建对应的代理类实例

    package com.bolingcavalry.service;

    import dev.langchain4j.service.*;
    import dev.langchain4j.service.spring.AiService;

    @AiService
    public interface Assistant {
    /**
    * 最简单的对话,只返回助手的回答,不包含任何额外信息
    *
    * @param userMessage 用户消息
    * @return 助手生成的回答
    */

    @SystemMessage("你是历史学家,回答问题是简洁风格,不超过100字")
    String simpleChat(String userMessage);
    }

    • 然后是配置类,这里面要写代码创建model实例

    package com.bolingcavalry.config;

    import dev.langchain4j.memory.ChatMemory;
    import dev.langchain4j.memory.chat.ChatMemoryProvider;
    import dev.langchain4j.memory.chat.MessageWindowChatMemory;
    import dev.langchain4j.model.openai.OpenAiChatModel;

    import java.util.Map;

    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import dev.langchain4j.service.AiServices;
    import dev.langchain4j.store.memory.chat.ChatMemoryStore;

    import com.bolingcavalry.service.Assistant;

    /**
    * LangChain4j配置类
    */

    @Configuration
    public class LangChain4jConfig {

    @Value("${langchain4j.open-ai.chat-model.api-key}")
    private String apiKey;

    @Value("${langchain4j.open-ai.chat-model.model-name:qwen-turbo}")
    private String modelName;

    @Value("${langchain4j.open-ai.chat-model.base-url}")
    private String baseUrl;

    /**
    * 创建并配置OpenAiChatModel实例(使用通义千问的OpenAI兼容接口)
    *
    * @return OpenAiChatModel实例
    */

    @Bean
    public OpenAiChatModel chatModel() {
    return OpenAiChatModel.builder()
    .apiKey(apiKey)
    .modelName(modelName)
    .baseUrl(baseUrl)
    .build();
    }
    }

    • 创建服务类,该服务类会注入Assistant接口的实现类

    package com.bolingcavalry.service;

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;

    /**
    * 通义千问服务类,用于与通义千问模型进行交互
    */

    @Service
    public class QwenService {

    private static final Logger logger = LoggerFactory.getLogger(QwenService.class);

    @Autowired
    private Assistant assistant;

    /**
    * 最简单的高级API对话
    *
    * @param prompt
    * @return
    */

    public String simpleChat(String prompt) {
    String answer = assistant.simpleChat(prompt);
    logger.info("响应:" + answer);
    return answer + "[from simpleChat with code and annotation]";
    }
    }

    • 最后是controller类,定义一个web接口用于验证功能

    package com.bolingcavalry.controller;

    import org.springframework.http.ResponseEntity;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;

    import com.bolingcavalry.service.QwenService;

    import lombok.Data;

    /**
    * 通义千问控制器,处理与大模型交互的HTTP请求
    */

    @RestController
    @RequestMapping("/api/qwen")
    public class QwenController {

    private final QwenService qwenService;

    /**
    * 构造函数,通过依赖注入获取QwenService实例
    *
    * @param qwenService QwenService实例
    */

    public QwenController(QwenService qwenService) {
    this.qwenService = qwenService;
    }

    /**
    * 提示词请求实体类
    */

    @Data
    static class PromptRequest {
    private String prompt;
    private int userId;
    }

    /**
    * 响应实体类
    */

    @Data
    static class Response {
    private String result;

    public Response(String result) {
    this.result = result;
    }
    }

    /**
    * 检查请求体是否有效
    *
    * @param request 包含提示词的请求体
    * @return 如果有效则返回null,否则返回包含错误信息的ResponseEntity
    */

    private ResponseEntity<Response> check(PromptRequest request) {
    if (request == null || request.getPrompt() == null || request.getPrompt().trim().isEmpty()) {
    return ResponseEntity.badRequest().body(new Response("提示词不能为空"));
    }
    return null;
    }

    @PostMapping("/codeandannonation/simplechat")
    public ResponseEntity<Response> simpleChat(@RequestBody PromptRequest request) {
    ResponseEntity<Response> checkRlt = check(request);
    if (checkRlt != null) {
    return checkRlt;
    }

    try {
    String response = qwenService.simpleChat(request.getPrompt());
    return ResponseEntity.ok(new Response(response));
    } catch (Exception e) {
    // 捕获异常并返回错误信息
    return ResponseEntity.status(500).body(new Response("请求处理失败: " + e.getMessage()));
    }
    }
    }

    • 代码写完了,执行命令mvn spring-boot:run 把服务运行起来
    • 发送HTTP请求来验证AiService可用

    ### POST 高级API的实例用AiService注解创建,model实例在配置类中用代码创建
    POST http://localhost:8080/api/qwen/codeandannonation/simplechat
    Content-Type: application/json
    Accept: application/json

    {
    "prompt": "介绍一下曹操的五子良将"
    }

    • 收到响应,证明服务正常,Assistant接口的实现类实例可以正常使用

    HTTP/1.1 200 OK
    Content-Type: application/json
    Transfer-Encoding: chunked
    Date: Sat, 20 Dec 2025 09:45:34 GMT
    Connection: close

    {
    "result": "曹操“五子良将”指张辽、乐进、于禁、张郃、徐晃,皆曹魏名将,以勇略著称,屡立战功,为曹操统一北方立下汗马功劳。[from simpleChat with code and annotation]"
    }

    • 现在方法二已经验证通过,接下来试试方法三:仅用注解和配置文件就能完成AiService实例创建

    方法三,仅注解

    • 接下来是方法三,如下图 在这里插入图片描述

    • 相比方法二,方法三要解决的问题是:能不能做到不写代码就创建模型服务实例?

    • 答案是:针对特定模型服务是可以的,例如OpenAi以及兼容OpenAi格式的服务,而具体做法是使用OpenAi专用的starter库,如下图: 在这里插入图片描述

    • 接下来编码体验

    • 在父工程下新建名为ai-service-only-annonation的子工程,pom.xml如下,重点是增加了依赖库langchain4j-open-ai-spring-boot-starter,它可以根据配置信息自动创建模型实例

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <parent>
    <groupId>com.bolingcavalry</groupId>
    <artifactId>langchain4j-totorials</artifactId>
    <version>1.0-SNAPSHOT</version>
    </parent>

    <artifactId>ai-service-only-annonation</artifactId>
    <packaging>jar</packaging>

    <dependencies>
    <!– Lombok –>
    <dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
    </dependency>

    <!– Spring Boot Starter –>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
    </dependency>

    <!– Spring Boot Web –>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!– Spring Boot Test –>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
    </dependency>

    <!– JUnit Jupiter Engine –>
    <dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-engine</artifactId>
    <scope>test</scope>
    </dependency>

    <!– Mockito Core –>
    <dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <scope>test</scope>
    </dependency>

    <!– Mockito JUnit Jupiter –>
    <dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-junit-jupiter</artifactId>
    <scope>test</scope>
    </dependency>

    <!– LangChain4j Core –>
    <dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j-core</artifactId>
    </dependency>

    <!– LangChain4j OpenAI支持(用于通义千问的OpenAI兼容接口) –>
    <dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j-open-ai</artifactId>
    </dependency>

    <!– 官方 langchain4j(包含 AiServices 等服务类) –>
    <dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j</artifactId>
    </dependency>

    <dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j-community-dashscope</artifactId>
    </dependency>

    <dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j-spring-boot-starter</artifactId>
    </dependency>

    <dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j-open-ai-spring-boot-starter</artifactId>
    </dependency>

    <!– 日志依赖由Spring Boot Starter自动管理,无需单独声明 –>
    </dependencies>

    <build>
    <plugins>
    <!– Spring Boot Maven Plugin –>
    <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <version>3.3.5</version>
    <executions>
    <execution>
    <goals>
    <goal>repackage</goal>
    </goals>
    </execution>
    </executions>
    </plugin>
    </plugins>
    </build>

    </project>

    • 在父工程的pom.xml中加入新增的子工程 在这里插入图片描述

    • langchain4j-totorials/ai-service-only-annonation/src/main/resources新增配置文件application.properties,内容如下,主要是三个模型的配置信息,记得把your-api-key换成您自己的apikey

    # Spring Boot 应用配置
    server.port=8080
    server.servlet.context-path=/

    # LangChain4j 使用OpenAI兼容模式配置通义千问模型
    # 注意:请将your-api-key替换为您实际的通义千问API密钥
    langchain4j.open-ai.chat-model.api-key=your-api-key
    # 通义千问模型名称
    langchain4j.open-ai.chat-model.model-name=qwen3-max
    # 阿里云百炼OpenAI兼容接口地址
    langchain4j.open-ai.chat-model.base-url=https://dashscope.aliyuncs.com/compatible-mode/v1

    # 日志配置
    logging.level.root=INFO
    logging.level.com.bolingcavalry=DEBUG
    logging.pattern.console=%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} – %msg%n
    # 应用名称
    spring.application.name=ai-service-only-annonation

    • 启动类没啥好说的

    package com.bolingcavalry;

    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;

    /**
    * Spring Boot应用程序的主类
    */

    @SpringBootApplication
    public class Application {

    public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
    }
    }

    • 创建一个自定义接口Assistant.java,该接口用AiService注解修饰,这样LangChain2j的starter就会创建对应的代理类实例

    package com.bolingcavalry.service;

    import dev.langchain4j.service.*;
    import dev.langchain4j.service.spring.AiService;

    @AiService
    public interface Assistant {
    /**
    * 最简单的对话,只返回助手的回答,不包含任何额外信息
    *
    * @param userMessage 用户消息
    * @return 助手生成的回答
    */

    @SystemMessage("你是历史学家,回答问题是简洁风格,不超过100字")
    String simpleChat(String userMessage);
    }

    • 创建服务类,该服务类会注入Assistant接口的实现类

    package com.bolingcavalry.service;

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;

    /**
    * 通义千问服务类,用于与通义千问模型进行交互
    */

    @Service
    public class QwenService {

    private static final Logger logger = LoggerFactory.getLogger(QwenService.class);

    @Autowired
    private Assistant assistant;

    /**
    * 最简单的高级API对话
    *
    * @param prompt
    * @return
    */

    public String simpleChat(String prompt) {
    String answer = assistant.simpleChat(prompt);
    logger.info("响应:" + answer);
    return answer + "[from simpleChat only annotation]";
    }
    }

    • 最后是controller类,定义一个web接口用于验证功能

    package com.bolingcavalry.controller;

    import org.springframework.http.ResponseEntity;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;

    import com.bolingcavalry.service.QwenService;

    import lombok.Data;

    /**
    * 通义千问控制器,处理与大模型交互的HTTP请求
    */

    @RestController
    @RequestMapping("/api/qwen")
    public class QwenController {

    private final QwenService qwenService;

    /**
    * 构造函数,通过依赖注入获取QwenService实例
    *
    * @param qwenService QwenService实例
    */

    public QwenController(QwenService qwenService) {
    this.qwenService = qwenService;
    }

    /**
    * 提示词请求实体类
    */

    @Data
    static class PromptRequest {
    private String prompt;
    private int userId;
    }

    /**
    * 响应实体类
    */

    @Data
    static class Response {
    private String result;

    public Response(String result) {
    this.result = result;
    }
    }

    /**
    * 检查请求体是否有效
    *
    * @param request 包含提示词的请求体
    * @return 如果有效则返回null,否则返回包含错误信息的ResponseEntity
    */

    private ResponseEntity<Response> check(PromptRequest request) {
    if (request == null || request.getPrompt() == null || request.getPrompt().trim().isEmpty()) {
    return ResponseEntity.badRequest().body(new Response("提示词不能为空"));
    }
    return null;
    }

    @PostMapping("/onlyannonation/simplechat")
    public ResponseEntity<Response> simpleChat(@RequestBody PromptRequest request) {
    ResponseEntity<Response> checkRlt = check(request);
    if (checkRlt != null) {
    return checkRlt;
    }

    try {
    String response = qwenService.simpleChat(request.getPrompt());
    return ResponseEntity.ok(new Response(response));
    } catch (Exception e) {
    // 捕获异常并返回错误信息
    return ResponseEntity.status(500).body(new Response("请求处理失败: " + e.getMessage()));
    }
    }
    }

    • 代码写完了,执行命令mvn spring-boot:run 把服务运行起来
    • 发送HTTP请求来验证AiService可用

    ### POST 高级API的实例用AiService注解创建,model实例在配置类中用代码创建
    ### 高级API的实例用AiService注解创建,model实例用配置信息和openai的starter创建
    POST http://localhost:8080/api/qwen/onlyannonation/simplechat
    Content-Type: application/json
    Accept: application/json

    {
    "prompt": "介绍一下西魏八柱国"
    }

    • 收到响应,证明服务正常,Assistant接口的实现类实例可以正常使用

    HTTP/1.1 200 OK
    Content-Type: application/json
    Transfer-Encoding: chunked
    Date: Sun, 21 Dec 2025 11:21:51 GMT
    Connection: close

    {
    "result": "西魏八柱国是宇文泰设立的八位最高军事统帅,包括宇文泰、元欣、李虎、李弼、赵贵、于谨、独孤信、侯莫陈崇,奠定北周及隋唐关陇集团基础。[from simpleChat only annotation]"
    }

    • 至此,高级API(AI Services)实例的三种创建方式全部体验完成了,希望能给您提供一些参考,不论是想通过代码精确控制还是想尽量简化,总有一款适合您

    你不孤单,欣宸原创一路相伴

  • Java系列
  • Spring系列
  • Docker系列
  • kubernetes系列
  • 数据库+中间件系列
  • DevOps系列
  • 赞(0)
    未经允许不得转载:171主机测评 » LangChain4j实战之九:高级API(AI Services)实例的创建方式
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址