【Spring AI & LangChain4j 基础篇】Spring AI实战:手把手搭建Java大模型对话Demo,新手也能快速上手
Spring AI大模型对话应用开发实战 本文介绍如何使用Spring AI快速开发大模型对话应用。首先进行环境准备,包括JDK17+、Maven3.8+等开发工具,并配置Spring AI和OpenAI的Maven依赖。接着通过最简Demo实现同步对话接口开发,核心代码仅需注入OpenAiChatClient并调用generate方法。然后进阶实现异步调用和流式SSE输出,优化响应性能,同时讲解
引言
随着AIGC技术爆发,大模型对话应用已成为企业级开发的高频需求。但原生大模型API调用繁琐、异步处理复杂、参数调优无章法,让不少Java开发者望而却步。Spring AI的出现,完美解决了这些痛点——它将大模型调用封装为简洁的Spring Bean,轻松实现同步、异步、流式输出等能力。本文就手把手教你搭建第一个可运行Demo,从最简代码到进阶优化,再到源码解读,让你快速掌握Spring AI开发大模型对话应用的核心技巧~
文章目录
一、环境准备(前置必备)
✨ 工欲善其事,必先利其器。在开始编码前,我们需要准备好基础环境,确保Demo能顺利运行。
1.1 开发环境清单
- JDK:17+(Spring AI对JDK版本有最低要求,17是最稳定的选择)
- 构建工具:Maven 3.8+ 或 Gradle 7.5+(本文以Maven为例)
- 开发工具:IntelliJ IDEA(推荐,自带Spring Boot支持,调试更便捷)
- 大模型API密钥:本文以OpenAI API为例(也可替换为国内大模型,如百度文心一言、阿里通义千问,配置方式类似)
- 测试工具:Postman 或 Swagger(用于接口调试)
1.2 Maven依赖配置
在Spring Boot项目的pom.xml中,引入核心依赖(Spring AI Starter + 大模型客户端),无需额外导入过多依赖,Spring AI已做好封装:
<!-- Spring Boot父工程 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.4</version>
<relativePath/>
</parent>
<dependencies>
<!-- Spring Web:用于开发接口 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring AI OpenAI Starter:核心依赖,封装大模型调用 -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-openai-spring-boot-starter</artifactId>
<version>1.0.0-M1</version>
</dependency>
<!-- Swagger:接口文档,方便调试 -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.2.0</version>
</dependency>
<!-- 测试依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId><scope>test</scope>
</dependency>
</dependencies>
💡 注意:Spring AI目前处于快速迭代阶段,版本可能更新,建议使用最新稳定版;若替换为其他大模型,只需替换对应的starter依赖(如spring-ai-ernie-starter for 文心一言)。
1.3 配置文件设置
在application.yml中配置大模型API密钥、模型名称等核心参数,无需硬编码,方便后续修改:
spring:
ai:
openai:
api-key: 你的OpenAI API密钥
chat:
model: gpt-3.5-turbo # 模型名称,可替换为gpt-4(需开通权限)
temperature: 0.7 # 默认温度,后续会讲解调优技巧
top-p: 0.9 # 默认top_p参数,控制输出的多样性
# Swagger配置(可选,方便接口调试)
springdoc:
api-docs:
path: /api-docs
swagger-ui:
path: /swagger-ui.html
operationsSorter: method
二、最简Demo:同步对话接口开发(核心第一步)
这一部分我们实现最基础的同步对话功能——前端发送问题,后端调用大模型,同步返回回答。代码极简,新手也能快速跑通。
2.1 核心代码实现(Controller层)
创建ChatController,注入OpenAiChatClient(Spring AI自动配置的Bean),编写一个POST接口,接收用户提问,调用大模型并返回结果:
import org.springframework.ai.openai.OpenAiChatClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
/**
* 大模型对话接口控制器
* 关注我,获取更多Spring AI实战技巧~
*/
@RestController
public class ChatController {
// 注入Spring AI自动配置的OpenAI对话客户端
private final OpenAiChatClient openAiChatClient;
// 构造方法注入(Spring Boot自动装配,无需手动new)
public ChatController(OpenAiChatClient openAiChatClient) {
this.openAiChatClient = openAiChatClient;
}
/**
* 同步对话接口:接收用户提问,同步返回大模型回答
* @param request 用户提问内容(封装为实体类,更规范)
* @return 大模型回答结果
*/
@PostMapping("/api/chat/sync")
public String syncChat(@RequestBody ChatRequest request) {
// 直接调用客户端的generate方法,传入提问内容,返回回答
return openAiChatClient.generate(request.getQuestion());
}
// 静态内部类:接收前端请求参数
public static class ChatRequest {
private String question; // 用户提问内容
// getter/setter
public String getQuestion() {
return question;
}
public void setQuestion(String question) {
this.question = question;
}
}
}
2.2 启动项目,测试接口
- 启动Spring Boot项目,确保无报错(若提示API密钥错误,检查配置文件中的api-key是否正确);
- 打开Postman,发送POST请求:
- 地址:http://localhost:8080/api/chat/sync
- 请求体(JSON):{“question”:“请用Java代码实现一个简单的单例模式”}
- 查看响应结果:大模型会返回对应的Java代码,同步接口开发完成!
🌟 小技巧:此时可以点赞收藏本文,后续开发时直接复用这段代码,省去重复编码的时间~
2.3 关键说明
- OpenAiChatClient是Spring AI封装的核心客户端,无需我们手动处理HTTP请求、签名验证等繁琐操作;
- 同步调用适合简单场景,但如果大模型回答较长,会导致接口响应时间过长,用户体验不佳,这就需要用到下一部分的异步和流式输出。
三、进阶实现:异步+流式SSE+参数调优
这一部分是重点,我们优化接口性能,实现异步调用(不阻塞主线程)、流式SSE输出(实时返回回答,类似ChatGPT的打字效果),并讲解temperature、top_p等核心参数的调优技巧。
3.1 异步对话接口开发
异步调用通过Spring的@Async注解实现,结合CompletableFuture返回结果,避免接口阻塞。
3.1.1 新增异步服务层
创建ChatService,编写异步调用方法(记得添加@Async注解):
import org.springframework.ai.openai.OpenAiChatClient;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.util.concurrent.CompletableFuture;
/**
* 大模型对话服务层(封装业务逻辑,便于复用)
*/
@Service
public class ChatService {
private final OpenAiChatClient openAiChatClient;
public ChatService(OpenAiChatClient openAiChatClient) {
this.openAiChatClient = openAiChatClient;
}
/**
* 异步对话调用
* @param question 用户提问
* @return 异步结果(CompletableFuture)
*/
@Async
public CompletableFuture<String> asyncChat(String question) {
// 调用大模型,返回CompletableFuture
return CompletableFuture.supplyAsync(() -> openAiChatClient.generate(question));
}
}
3.1.2 新增异步接口(Controller层)
在ChatController中注入ChatService,新增异步接口:
// 注入对话服务
private final ChatService chatService;
// 构造方法添加ChatService注入
public ChatController(OpenAiChatClient openAiChatClient, ChatService chatService) {
this.openAiChatClient = openAiChatClient;
this.chatService = chatService;
}
/**
* 异步对话接口:不阻塞主线程,提高接口吞吐量
* @param request 用户提问
* @return 异步结果
*/
@PostMapping("/api/chat/async")
public CompletableFuture<String> asyncChat(@RequestBody ChatRequest request) {
return chatService.asyncChat(request.getQuestion());
}
3.1.3 开启异步支持
在Spring Boot启动类上添加@EnableAsync注解,开启异步功能:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
@SpringBootApplication
@EnableAsync // 开启异步支持
public class SpringAiChatDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SpringAiChatDemoApplication.class, args);
}
}
3.2 流式SSE输出(实时响应)
流式输出通过SSE(Server-Sent Events)实现,大模型的回答会分批次返回,前端可以实时展示,极大提升用户体验。Spring AI已封装好流式调用方法,直接使用即可。
3.2.1 流式接口开发(Controller层)
新增流式接口,返回SseEmitter(Spring提供的SSE工具类):
import org.springframework.http.MediaType;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
/**
* 流式SSE对话接口:实时返回大模型回答(类似ChatGPT打字效果)
* @param request 用户提问
* @return SseEmitter 流式响应
*/
@PostMapping(value = "/api/chat/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public SseEmitter streamChat(@RequestBody ChatRequest request) {
// 创建SseEmitter,设置超时时间(30秒,避免连接断开)
SseEmitter emitter = new SseEmitter(30000L);
// 调用Spring AI的流式生成方法,分批次接收结果
openAiChatClient.stream(request.getQuestion())
.doOnNext(chunk -> {
try {
// 每收到一个分片,发送到前端
emitter.send(chunk.getContent());
} catch (Exception e) {
emitter.completeWithError(e);
}
})
.doOnComplete(() -> {
// 生成完成,关闭连接
emitter.complete();
})
.doOnError(error -> {
// 出现错误,返回错误信息并关闭连接
emitter.completeWithError(error);
})
.subscribe();
return emitter;
}
3.2.2 流式接口测试
用Postman测试流式接口:
- 发送POST请求,地址:http://localhost:8080/api/chat/stream
- 请求体:{“question”:“请详细讲解Spring AI的核心原理”}
- 观察响应:会分批次返回内容,类似ChatGPT的实时打字效果,体验拉满!
3.3 对话参数调优(temperature/top_p)
大模型的输出效果,主要通过temperature和top_p两个参数控制,合理调优能让回答更贴合需求。
3.3.1 核心参数解读
-
temperature(温度):取值范围0~2,控制回答的随机性。
- 取值越低(如0.1~0.3):回答越严谨、确定,适合事实查询、代码生成等场景;
- 取值越高(如1.5~2.0):回答越有创意、发散,适合文案创作、 brainstorming 等场景;
- 默认值0.7:平衡严谨性和创意性,适合大多数场景。
-
top_p(核采样):取值范围0~1,控制回答的多样性(与temperature二选一即可,不建议同时调整)。
- 取值越低(如0.5):只选择概率最高的少数 tokens,回答更集中;
- 取值越高(如0.9):选择更多概率较低的 tokens,回答更多样;
- 默认值0.9:兼顾多样性和准确性。
3.3.2 参数调优实现(动态调整)
我们可以在接口中动态接收参数,实现不同场景下的参数自定义:
- 修改ChatRequest实体类,添加temperature和top_p字段:
public static class ChatRequest {
private String question;
private Float temperature; // 可选,不传递则使用配置文件默认值
private Float topP; // 可选,不传递则使用配置文件默认值
// getter/setter 省略
}
- 优化同步对话接口,支持动态参数:
@PostMapping("/api/chat/sync")
public String syncChat(@RequestBody ChatRequest request) {
// 构建对话参数,优先使用请求中的参数,无则使用默认值
OpenAiChatOptions options = OpenAiChatOptions.builder()
.temperature(request.getTemperature() != null ? request.getTemperature() : 0.7f)
.topP(request.getTopP() != null ? request.getTopP() : 0.9f)
.build();
// 调用大模型,传入参数
return openAiChatClient.generate(request.getQuestion(), options);
}
📌 提示:异步和流式接口也可以用同样的方式,添加动态参数调优功能,需要的同学可以自己动手实现(评论区可以交流实现思路哦~)
四、接口封装与测试(Postman/Swagger)
接口开发完成后,必须进行调试和测试,确保功能正常。下面分别介绍Postman和Swagger的测试方法。
4.1 Postman测试(推荐,功能更全)
4.1.1 同步接口测试
- 方法:POST
- 地址:http://localhost:8080/api/chat/sync
- 请求体:
{
"question": "请用Java代码实现冒泡排序",
"temperature": 0.2,
"topP": 0.8
}
- 预期结果:返回正确的冒泡排序代码,格式规范。
4.1.2 异步接口测试
- 方法:POST
- 地址:http://localhost:8080/api/chat/async
- 请求体:同上
- 预期结果:返回CompletableFuture格式的响应,包含大模型回答。
4.1.3 流式接口测试
- 方法:POST
- 地址:http://localhost:8080/api/chat/stream
- 请求体:同上
- 预期结果:分批次返回内容,实时展示。
4.2 Swagger测试(快速调试)
启动项目后,访问:http://localhost:8080/swagger-ui.html,即可看到所有接口的文档,直接在页面上输入参数,点击“Try it out”即可测试,无需额外工具,适合快速调试。
💡 小技巧:可以将测试通过的接口保存为Postman集合,后续迭代开发时,直接复用测试用例,提高效率。
五、核心源码极简解读(Spring AI对话调用流程)
很多同学可能好奇:Spring AI到底是如何封装大模型调用的?底层执行流程是什么?这里用极简的方式拆解核心源码,不用深入复杂逻辑,快速理解核心原理。
5.1 核心执行流程(3步)
-
自动装配:Spring Boot启动时,Spring AI的AutoConfiguration类(如OpenAiAutoConfiguration)会自动配置OpenAiChatClient、OpenAiChatOptions等Bean,我们直接注入即可使用,无需手动创建。
-
请求封装:当我们调用openAiChatClient.generate()方法时,Spring AI会将用户的提问、参数(temperature/top_p)封装为大模型API要求的请求格式(如OpenAI的ChatCompletionRequest)。
-
请求发送与结果解析:Spring AI通过RestTemplate或WebClient发送HTTP请求到大模型API,接收响应后,解析返回的JSON数据,提取回答内容,封装为我们需要的格式(String或流式分片),返回给上层。
5.2 核心源码片段(关键类)
- OpenAiChatClient:核心客户端,提供generate(同步)、stream(流式)等方法,是我们调用的入口。
- OpenAiChatOptions:参数配置类,封装temperature、top_p、model等参数。
- OpenAiChatCompletionClient:底层请求发送类,负责与大模型API交互,处理请求和响应。
📚 拓展:如果想深入学习,可以查看Spring AI的源码(GitHub地址:https://github.com/spring-projects/spring-ai),重点看openai模块下的相关类,难度不大,适合Java开发者阅读。
六、总结
本文从环境准备、最简Demo开发,到进阶的异步调用、流式SSE输出、参数调优,再到接口测试和源码解读,完整覆盖了用Spring AI实现Java版大模型对话应用的核心流程。
核心亮点:Spring AI极大简化了大模型调用的复杂度,让Java开发者无需关注底层HTTP请求、签名等细节,专注于业务逻辑;同步、异步、流式三种调用方式,满足不同场景的需求;参数调优能让大模型的回答更贴合实际业务。
✨ 最后,如果你觉得本文对你有帮助,欢迎点赞、收藏、评论,关注我(予枫),后续会分享更多Spring AI、Java、AIGC相关的实战技巧~
如果在开发过程中遇到问题,可以在评论区留言,我会第一时间回复~
更多推荐


所有评论(0)