LangChain4j实战之九:高级API(AI Services)实例的创建方式
使用高级API服务时,对应的实现类的bean如何创建?这里提供了三种方法供您选择
欢迎访问我的GitHub
这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos
LangChain4j实战全系列链接
本篇概览
-
高级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)实例的三种创建方式全部体验完成了,希望能给您提供一些参考,不论是想通过代码精确控制还是想尽量简化,总有一款适合您
你不孤单,欣宸原创一路相伴
更多推荐


所有评论(0)