主题
Spring Boot 集成
LangChain4j 为以下提供了 Spring Boot starters:
- 流行的集成
- 声明式的 AI 服务
Spring Boot Starters
Spring Boot starters 帮助通过属性来创建与配置语言模型、嵌入模型、嵌入存储以及其他核心 LangChain4j 组件。
要使用某个 Spring Boot starter,
- 对 Spring Boot 3 用
langchain4j-{integration-name}-spring-boot-starter
例如,对 OpenAI(langchain4j-open-ai):
Spring Boot 4:
xml
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-open-ai-spring-boot4-starter</artifactId>
<version>1.22.0-beta32</version>
</dependency>Spring Boot 3:
xml
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-open-ai-spring-boot-starter</artifactId>
<version>1.22.0-beta32</version>
</dependency>然后,你可以按如下方式在 application.properties 文件中配置模型参数:
langchain4j.open-ai.chat-model.api-key=${OPENAI_API_KEY}
langchain4j.open-ai.chat-model.model-name=gpt-4o
langchain4j.open-ai.chat-model.log-requests=true
langchain4j.open-ai.chat-model.log-responses=true
...这种情况下,会自动创建一个 OpenAiChatModel(一个 ChatModel 的实现)实例,你可以在需要处自动注入它:
java
@RestController
public class ChatController {
ChatModel chatModel;
public ChatController(ChatModel chatModel) {
this.chatModel = chatModel;
}
@GetMapping("/chat")
public String model(@RequestParam(value = "message", defaultValue = "Hello") String message) {
return chatModel.chat(message);
}
}如果你需要一个 StreamingChatModel 实例,请使用 streaming-chat-model 属性,而非 chat-model 属性:
langchain4j.open-ai.streaming-chat-model.api-key=${OPENAI_API_KEY}
...面向声明式 AI 服务的 Spring Boot starter
LangChain4j 提供了一个 Spring Boot starter,用于自动配置 AI 服务、RAG、工具等。
假设你已经导入了某个集成 starter(见上文),
Spring Boot 4:
xml
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-spring-boot4-starter</artifactId>
<version>1.22.0-beta32</version>
</dependency>Spring Boot 3:
xml
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-spring-boot-starter</artifactId>
<version>1.22.0-beta32</version>
</dependency>现在你可以定义一个 AI 服务接口并用 @AiService 注解它:
java
@AiService
interface Assistant {
@SystemMessage("You are a polite assistant")
String chat(String userMessage);
}把它当作一个标准的 Spring Boot @Service,只不过具备 AI 能力。
当应用启动时,LangChain4j starter 会扫描 classpath,找到所有用 @AiService 注解的接口。对找到的每个 AI 服务,它会使用应用上下文中所有可用的 LangChain4j 组件创建该接口的实现,并把它注册为一个 bean,于是你可以在需要处自动注入它:
java
@RestController
class AssistantController {
@Autowired
Assistant assistant;
@GetMapping("/chat")
public String chat(String message) {
return assistant.chat(message);
}
}自动组件装配
以下组件若在应用上下文中可用,会被自动装配进 AI 服务:
ChatModelStreamingChatModelChatMemoryChatMemoryProviderContentRetrieverRetrievalAugmentorToolProviderToolExecutionErrorHandler与ToolArgumentsErrorHandler(见错误处理)- 任何被
@Tool注解的@Component或@Service类的方法 一个示例:
java
@Component
public class BookingTools {
private final BookingService bookingService;
public BookingTools(BookingService bookingService) {
this.bookingService = bookingService;
}
@Tool
public Booking getBookingDetails(String bookingNumber, String customerName, String customerSurname) {
return bookingService.getBookingDetails(bookingNumber, customerName, customerSurname);
}
@Tool
public void cancelBooking(String bookingNumber, String customerName, String customerSurname) {
bookingService.cancelBooking(bookingNumber, customerName, customerSurname);
}
}NOTE
若应用上下文中存在多个同类型的组件,应用将无法启动。这种情况下,请使用显式装配模式(下文解释)。
显式组件装配
如果你有多个 AI 服务,并希望把不同的 LangChain4j 组件装配进每一个,你可以用显式装配模式(@AiService(wiringMode = EXPLICIT))来指定使用哪些组件。
假设我们配置了两个 ChatModel:
properties
# OpenAI
langchain4j.open-ai.chat-model.api-key=${OPENAI_API_KEY}
langchain4j.open-ai.chat-model.model-name=gpt-4o-mini
# Ollama
langchain4j.ollama.chat-model.base-url=http://localhost:11434
langchain4j.ollama.chat-model.model-name=llama3.1java
@AiService(wiringMode = EXPLICIT, chatModel = "openAiChatModel")
interface OpenAiAssistant {
@SystemMessage("You are a polite assistant")
String chat(String userMessage);
}
@AiService(wiringMode = EXPLICIT, chatModel = "ollamaChatModel")
interface OllamaAssistant {
@SystemMessage("You are a polite assistant")
String chat(String userMessage);
}NOTE
这种情况下,你必须显式指定所有组件。
通过配置选择组件
与其硬编码 bean 名,你可以使用属性占位符,从而装配进某个 AI 服务的组件可以通过配置来更改(例如按环境或 profile):
properties
my-app.assistant.chat-model-bean=ollamaChatModel
my-app.assistant.tool-beans=weatherTools,calendarToolsjava
@AiService(
wiringMode = EXPLICIT,
chatModel = "${my-app.assistant.chat-model-bean:openAiChatModel}",
tools = "${my-app.assistant.tool-beans}"
)
interface Assistant {
String chat(String userMessage);
}有几点需要牢记:
- 一个占位符必须解析为一个 bean 名(例如
ollamaChatModel),而非某个 LLM 模型的名字(例如llama3.1)。 模型名是在ChatModelbean 本身上配置的(例如langchain4j.ollama.chat-model.model-name)。 - 可以在冒号后指定一个默认值:
${my-app.assistant.chat-model-bean:openAiChatModel}。 - 若一个占位符无法解析且没有默认值,应用将无法启动。
- 若一个占位符解析为空值,该属性会被当作未设置。
- 对于
tools,一个占位符可以解析为多个以逗号分隔的 bean 名。
更多细节可在这里找到(Spring Boot 4 变体使用相同的 API)。
监听 AI 服务注册事件
在你以声明方式完成 AI 服务的开发之后,你可以通过实现 ApplicationListener<AiServiceRegisteredEvent> 接口来监听 AiServiceRegisteredEvent。当某个 AI 服务被注册到 Spring 上下文时,该事件会被触发,让你能在运行时获取所有已注册 AI 服务及其工具的信息。示例如下:
java
@Component
class AiServiceRegisteredEventListener implements ApplicationListener<AiServiceRegisteredEvent> {
@Override
public void onApplicationEvent(AiServiceRegisteredEvent event) {
Class<?> aiServiceClass = event.aiServiceClass();
List<ToolSpecification> toolSpecifications = event.toolSpecifications();
for (int i = 0; i < toolSpecifications.size(); i++) {
System.out.printf("[%s]: [Tool-%s]: %s%n", aiServiceClass.getSimpleName(), i + 1, toolSpecifications.get(i));
}
}
}Flux
流式时,你可以用 Flux<String> 作为 AI 服务的返回类型:
java
@AiService
interface Assistant {
@SystemMessage("You are a polite assistant")
Flux<String> chat(String userMessage);
}为此,请导入 langchain4j-reactor 模块。更多细节见这里。
该模块也为非阻塞模式提供 Mono<T> 与 Flux<AiServiceStreamingEvent>,且该 starter 可以通过 langchain4j.executor.use-spring-task-executor=true 把 LangChain4j 卸载的工作路由到 Spring 自己的任务执行器,从而使追踪、MDC 与安全上下文跟随一个异步调用。
OpenAI、Mistral AI 与 Ollama 的 starter 用 Spring 的 HTTP 客户端发送请求:RestClient 用于阻塞调用,WebClient 用于非阻塞模式。所以,当你把非阻塞模式与这些 starter 之一、以及一个支持它们的提供者一起使用时(见提供者支持),WebClient 必须在 classpath 上。Flux<String> 与 TokenStream 不需要它。
- Spring Boot 4: 添加
spring-boot-starter-webclient。 - Spring Boot 3: 添加
org.springframework:spring-webflux。如果你的应用不是 web 应用(没有spring-boot-starter-web),还要设置spring.main.web-application-type=none,因为 Spring Boot 会把一个在 classpath 上有spring-webflux的应用当作响应式 web 应用。
除非你的应用是一个 WebFlux 应用,否则不要为此使用 spring-boot-starter-webflux:它还会带来一个 web 服务器。没有 WebClient 时,一个非阻塞调用会以一个说明该添加什么的 AsyncNotSupportedException 失败。
非阻塞请求由应用的 WebClient.Builder 构建,正如阻塞请求由其 RestClient.Builder 构建一样。因此在每个 builder 上配置的过滤器、默认头与可观测性都会生效,而一个为你的自有服务添加凭据的过滤器,也会针对发送给模型提供者的请求运行。这两个 builder 是分别配置的:对其中一个的定制不会作用于另一个。对于非阻塞请求,Spring Boot 所配置使用的连接器(包括其连接器定制器)会与 LangChain4j 中配置的超时组合;Spring Boot 的其他 HTTP 客户端设置(例如 SSL bundle)不被应用。若应用有多个 WebClient.Builder bean 且没有一个是 @Primary,LangChain4j 会改用一个新建的 WebClient.builder()。要给 LangChain4j 一个专用的 builder,请声明一个 WebClientBuilderHolder bean:
java
@Bean
WebClientBuilderHolder langchain4jWebClientBuilder() {
return WebClientBuilderHolder.of(WebClient.builder());
}可观测性
要为某个 ChatModel 或 StreamingChatModel bean 启用可观测性,你需要声明一个或多个 ChatModelListener bean:
java
@Configuration
class MyConfiguration {
@Bean
ChatModelListener chatModelListener() {
return new ChatModelListener() {
private static final Logger log = LoggerFactory.getLogger(ChatModelListener.class);
@Override
public void onRequest(ChatModelRequestContext requestContext) {
log.info("onRequest(): {}", requestContext.chatRequest());
}
@Override
public void onResponse(ChatModelResponseContext responseContext) {
log.info("onResponse(): {}", responseContext.chatResponse());
}
@Override
public void onError(ChatModelErrorContext errorContext) {
log.info("onError(): {}", errorContext.error().getMessage());
}
};
}
}应用上下文中的每个 ChatModelListener bean 都会被自动注入到由我们某个 Spring Boot starter 创建的所有 ChatModel 与 StreamingChatModel bean 中。
Micrometer 指标
把 langchain4j-micrometer-metrics 依赖添加到你的项目:
对于 Maven:
xml
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-micrometer-metrics</artifactId>
<version>1.22.0-beta32</version>
</dependency>对于 Gradle:
gradle
implementation 'dev.langchain4j:langchain4j-micrometer-metrics:1.22.0-beta32'Micrometer(Actuator)配置
你的项目里也应有所需的 Actuator 依赖。例如,如果你使用 Spring Boot,可以把以下依赖添加到你的 pom.xml:
对于 Maven:
xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>对于 Gradle:
gradle
implementation 'org.springframework.boot:spring-boot-starter-actuator'在你的属性中启用 /metrics Actuator 端点。
application.properties:
properties
management.endpoints.web.exposure.include=metricsapplication.yaml:
yaml
management:
endpoints:
web:
exposure:
include: metrics配置 MicrometerMetricsChatModelListener bean
在一个 Spring Boot 应用中,你可以把监听器定义为一个 bean 并注入 MeterRegistry:
java
import dev.langchain4j.micrometer.metrics.listeners.MicrometerMetricsChatModelListener;
import io.micrometer.core.instrument.MeterRegistry;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MetricsConfig {
@Bean
public MicrometerMetricsChatModelListener listener(MeterRegistry meterRegistry) {
return new MicrometerMetricsChatModelListener(meterRegistry);
}
}查看指标
你可以通过访问应用的 /actuator/metrics 端点来查看指标。
例如,如果你在 localhost:8080 上运行应用,你可以访问 http://localhost:8080/actuator/metrics 来查看指标。
词元用量指标
在以下地址查看词元用量指标:
http://localhost:8080/actuator/metrics/gen_ai.client.token.usage按词元类型过滤
gen_ai.token.type 标签指明这些词元是用于输入还是输出:
| 词元类型 | 端点 |
|---|---|
| 输入词元 | /actuator/metrics/gen_ai.client.token.usage?tag=gen_ai.token.type:input |
| 输出词元 | /actuator/metrics/gen_ai.client.token.usage?tag=gen_ai.token.type:output |
注:
gen_ai.client.token.usage指标是一个直方图(DistributionSummary)。不带任何标签的端点会显示跨所有词元类型、模型与提供者的聚合统计(count、total、max)。
Micrometer Observation API
这通过 Micrometer Observation API 实现了 ChatModelListener,只需添加以下依赖即可透明地生成指标与追踪:
对于 Maven:
xml
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-observation</artifactId>
</dependency>对于 Gradle:
gradle
implementation 'dev.langchain4j:langchain4j-observation'你需要按如下方式实例化 Observation 监听器……
配置 ObservationChatModelListener bean
java
@Configuration
public class ObservationConfig {
@Bean
public ObservationChatModelListener listener(ObservationRegistry observationRegistry, MeterRegistry meterRegistry) {
return new ObservationChatModelListener(observationRegistry, meterRegistry);
}
}该依赖要求配置 SpringBoot Actuator,如上所述。
关于 SpringBoot 应用上额外的可观测性需求,请遵循:构建你的第一个可观测应用
关于 langchain4j-observation 库的更多细节,请查看可观测性文档。
测试
支持的版本
LangChain4j 的 Spring Boot 集成需要 Java 17,并同时支持:
- Spring Boot 4(4.0+)—— 使用带
-spring-boot4-starter后缀的 starter - Spring Boot 3(3.5+)—— 使用带
-spring-boot-starter后缀的 starter,与 Spring Boot OSS 支持策略保持一致
两个系列一起发布并共享同一版本号。请选择与你项目中 Spring Boot 版本匹配的那一组 starter。