欢迎访问我的GitHub

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

LangChain4j实战全系列链接

  1. 准备工作
  2. 极速开发体验
  3. 细说聊天API
  4. 集成到spring-boot
  5. 图像模型
  6. 聊天记忆,低级API版
  7. 聊天记忆,高级API版
  8. 响应流式传输
  9. 高级API(AI Services)实例的创建方式

本篇概览

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

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

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

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

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

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

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

方法二,代码+注解

  • 先看方法二的步骤,如下图
    在这里插入图片描述
  • 总结方法二的三个重点:
  1. 需要配置类
  2. 要写代码来创建模型服务的实例
  3. 不用写代码来创建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)实例的三种创建方式全部体验完成了,希望能给您提供一些参考,不论是想通过代码精确控制还是想尽量简化,总有一款适合您

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

  1. Java系列
  2. Spring系列
  3. Docker系列
  4. kubernetes系列
  5. 数据库+中间件系列
  6. DevOps系列
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐