SpringBoot 集成 LangChain4j OpenAI
- [1 依赖](#1 依赖)
- [2 配置](#2 配置)
- [3 代码](#3 代码)
-
- [1 AiConf.java](#1 AiConf.java)
- [2 ChatController.java](#2 ChatController.java)
- [3 ImageController.java](#3 ImageController.java)
- [4 AudioController.java](#4 AudioController.java)
- [5 Application.java](#5 Application.java)
- [4 结果](#4 结果)
1 依赖
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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.5.7</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.xu</groupId>
<artifactId>langchain-openai</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>langchain-openai</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>25</java.version>
<maven.compiler.source>25</maven.compiler.source>
<maven.compiler.target>25</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-bom</artifactId>
<version>1.8.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-community-bom</artifactId>
<version>1.8.0-beta15</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-open-ai-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<releases>
<enabled>false</enabled>
</releases>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<releases>
<enabled>false</enabled>
</releases>
</pluginRepository>
</pluginRepositories>
</project>
2 配置
yml
复制代码
server:
port: 8080
context-path: /
spring:
application:
name: langchain-openai
servlet:
multipart:
max-file-size: 50MB
max-request-size: 50MB
langchain4j:
open-ai:
chat-model:
api-key: demo
model-name: gpt-4o-mini
temperature: 0.7
base-url: http://*********
log-requests: true
log-responses: true
logging:
level:
dev.langchain4j: debug
3 代码
1 AiConf.java
java
复制代码
package com.xu.conf;
import dev.langchain4j.model.chat.StreamingChatModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.model.openai.OpenAiImageModel;
import dev.langchain4j.model.openai.OpenAiStreamingChatModel;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
/**
* @author hyacinth
*/
@Configuration
public class AiConf {
@Value("${langchain4j.open-ai.chat-model.api-key}")
private String apiKey;
@Value("${langchain4j.open-ai.chat-model.model-name}")
private String modelName;
@Value("${langchain4j.open-ai.chat-model.base-url}")
private String baseUrl;
@Value("${langchain4j.open-ai.chat-model.log-requests}")
private boolean logRequests;
@Value("${langchain4j.open-ai.chat-model.log-responses}")
private boolean logResponses;
@Bean
@Primary
public OpenAiImageModel openAiImageModel() {
return OpenAiImageModel.builder()
.baseUrl(baseUrl)
.apiKey(apiKey)
.modelName(modelName)
.logRequests(true)
.logResponses(true)
.build();
}
@Bean
public StreamingChatModel streamingChatModel(){
return OpenAiStreamingChatModel.builder()
.baseUrl(baseUrl)
.apiKey(apiKey)
.modelName(modelName)
.logRequests(logRequests)
.logResponses(logResponses)
.build();
}
}
2 ChatController.java
java
复制代码
package com.xu.controller;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.chat.StreamingChatModel;
import dev.langchain4j.model.chat.request.ChatRequest;
import dev.langchain4j.model.chat.response.ChatResponse;
import dev.langchain4j.model.chat.response.StreamingChatResponseHandler;
import dev.langchain4j.model.openai.OpenAiChatModel;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* 普通聊天
*
* @author hyacinth
*/
@Slf4j
@RestController
@RequestMapping("/openai/text")
@AllArgsConstructor
public class ChatController {
private final ChatModel chatModel;
private final StreamingChatModel streamingChatModel;
private final OpenAiChatModel openAiChatModel;
/**
* 聊天
*
* @param message 问题
* @return 结果
*/
@PostMapping("/chat1")
public Object chat1(@RequestParam(value = "message", defaultValue = "Hello") String message) {
return chatModel.chat(message);
}
/**
* 聊天
*
* @param message 问题
* @return 结果
*/
@PostMapping("/chat2")
public Object chat2(@RequestParam(value = "message", defaultValue = "Hello") String message) {
var user = UserMessage.from(message);
var request = ChatRequest.builder().messages(user).build();
return openAiChatModel.chat(request).aiMessage();
}
/**
* 聊天
*
* @param message 问题
* @return 结果
*/
@PostMapping("/chat3")
public Object chat3(@RequestParam(value = "message", defaultValue = "Hello") String message) {
streamingChatModel.chat(message, new StreamingChatResponseHandler() {
@Override
public void onPartialResponse(String partialResponse) {
log.info("开始: {}", partialResponse);
IO.println("开始: " + partialResponse);
}
@Override
public void onCompleteResponse(ChatResponse completeResponse) {
log.info("结束: {}", completeResponse);
}
@Override
public void onError(Throwable error) {
log.error("异常: {}", error.getMessage());
}
});
return 1;
}
}
3 ImageController.java
java
复制代码
package com.xu.controller;
import dev.langchain4j.data.message.ImageContent;
import dev.langchain4j.data.message.TextContent;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.model.chat.request.ChatRequest;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.model.openai.OpenAiImageModel;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.util.Base64;
/**
* 图片处理
*
* @author hyacinth
*/
@RestController
@RequestMapping("/openai/images")
@AllArgsConstructor
public class ImageController {
private final OpenAiImageModel openAiImageModel;
private final OpenAiChatModel openAiChatModel;
/**
* 生成图片
*
* @param message 描述
* @return 结果
*/
@PostMapping("/gen1")
public Object gen1(@RequestParam(value = "message", defaultValue = "生成一个唐老鸭图片") String message) {
var response = openAiImageModel.generate(message);
return response.content().base64Data();
}
/**
* 图片识别
*
* @param message 描述
* @param file 图片
* @return 结果
* @throws Exception 异常
*/
@PostMapping("/read")
public Object read(@RequestParam("message") String message, @RequestParam("file") MultipartFile file) throws Exception {
var user = UserMessage.from(
TextContent.from(message),
ImageContent.from(Base64.getEncoder().encodeToString(file.getBytes()), file.getContentType(), ImageContent.DetailLevel.AUTO)
);
var request = ChatRequest.builder().messages(user).build();
return openAiChatModel.chat(request).aiMessage();
}
}
4 AudioController.java
java
复制代码
package com.xu.controller;
import dev.langchain4j.data.message.AudioContent;
import dev.langchain4j.data.message.TextContent;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.model.chat.request.ChatRequest;
import dev.langchain4j.model.openai.OpenAiChatModel;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.util.Base64;
/**
* 语音处理
*
* @author hyacinth
*/
@RestController
@RequestMapping("/openai/audio")
@AllArgsConstructor
public class AudioController {
private final OpenAiChatModel openAiChatModel;
/**
* 语音转文字
*
* @param message 描述
* @param file 予以文件
* @return 结果
* @throws Exception 异常
*/
@PostMapping("/asr1")
public Object asr1(@RequestParam("message") String message, @RequestParam("file") MultipartFile file) throws Exception {
var user = UserMessage.from(
TextContent.from(message),
AudioContent.from(Base64.getEncoder().encodeToString(file.getBytes()), file.getContentType())
);
var request = ChatRequest.builder().messages(user).build();
return openAiChatModel.chat(request).aiMessage();
}
}
5 Application.java
java
复制代码
package com.xu;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author hyacinth
*/
@SpringBootApplication
public class Application {
static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
4 结果
java
复制代码
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v3.5.7)
2025-10-30T15:55:21.321+08:00 INFO 29536 --- [langchain-openai] [ restartedMain] com.xu.Application : Starting Application using Java 25 with PID 29536 (D:\SourceCode\JavaLearn\langchain-openai\target\classes started by hyacinth in D:\SourceCode\JavaLearn\langchain-openai)
2025-10-30T15:55:21.324+08:00 INFO 29536 --- [langchain-openai] [ restartedMain] com.xu.Application : No active profile set, falling back to 1 default profile: "default"
2025-10-30T15:55:21.365+08:00 INFO 29536 --- [langchain-openai] [ restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable
2025-10-30T15:55:21.365+08:00 INFO 29536 --- [langchain-openai] [ restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : For additional web related logging consider setting the 'logging.level.web' property to 'DEBUG'
2025-10-30T15:55:22.155+08:00 INFO 29536 --- [langchain-openai] [ restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port 8080 (http)
2025-10-30T15:55:22.168+08:00 INFO 29536 --- [langchain-openai] [ restartedMain] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2025-10-30T15:55:22.169+08:00 INFO 29536 --- [langchain-openai] [ restartedMain] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.48]
2025-10-30T15:55:22.203+08:00 INFO 29536 --- [langchain-openai] [ restartedMain] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2025-10-30T15:55:22.203+08:00 INFO 29536 --- [langchain-openai] [ restartedMain] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 838 ms
2025-10-30T15:55:22.678+08:00 INFO 29536 --- [langchain-openai] [ restartedMain] o.s.b.d.a.OptionalLiveReloadServer : LiveReload server is running on port 35729
2025-10-30T15:55:22.694+08:00 INFO 29536 --- [langchain-openai] [ restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) with context path '/'
2025-10-30T15:55:22.699+08:00 INFO 29536 --- [langchain-openai] [ restartedMain] com.xu.Application : Started Application in 1.772 seconds (process running for 2.246)