Spring AI 实战:从零开始调用大模型接口,构建 Java AI 应用
一、为什么需要 Spring AI?
随着大语言模型(LLM)在企业应用中的普及,Java 开发者开始面临一个新问题:如何将大模型能力集成到现有的 Spring Boot 系统中?
传统方式通常是使用 RestTemplate、WebClient 或 HTTP 客户端,手动构造请求 JSON、设置 API Key、处理响应结果和异常。虽然这种方式可以实现模型调用,但当系统需要切换模型供应商、增加流式输出、接入知识库或实现多轮对话时,代码维护成本会逐渐增加。
Spring AI 正是为解决这些问题而设计的 AI 应用开发框架。它借鉴 Spring 生态的设计理念,为不同大模型提供统一的调用抽象,并支持提示词管理、结构化输出、对话记忆、RAG 检索增强生成和工具调用等能力。
官方文档:https://docs.spring.io/spring-ai/reference/
本文将从最基础的接口调用开始,逐步实现一个可运行的 Spring Boot 大模型服务。
二、Spring AI 的核心架构
Spring AI 并不是一个新的大模型,而是 Java 应用与大模型服务之间的适配层。
典型调用链路如下:
text
用户请求
|
v
Spring Boot Controller
|
v
业务 Service
|
v
Spring AI ChatClient
|
v
ChatModel 模型适配层
|
v
HTTP API 请求
|
v
大模型服务
|
v
模型响应 -> 解析 -> 返回业务系统
Spring AI 的几个核心组件如下:
| 组件 | 主要作用 |
|---|---|
ChatClient |
提供简洁、流畅的大模型调用 API |
ChatModel |
抽象底层聊天模型的调用能力 |
Prompt |
封装系统指令、用户输入和模型调用选项 |
ChatResponse |
承载模型响应及相关元数据 |
Advisors |
扩展对话记忆、RAG 等通用 AI 处理流程 |
其中,日常业务开发优先使用 ChatClient;当需要更底层的模型控制或处理完整响应元数据时,可以使用 ChatModel。
Spring AI 的模型抽象使应用能够在支持的模型实现之间切换,减少业务代码对特定供应商 API 的直接依赖。
三、创建 Spring Boot 项目
3.1 环境准备
本文示例使用以下技术栈:
- JDK 17 或更高版本。
- Maven 3.8+。
- Spring Boot 3.5.x。
- Spring AI 1.0.x。
- 一个兼容 OpenAI Chat Completions API 的大模型服务。
为了便于在现有 Spring Boot 项目中集成,本文采用 Spring AI 1.0.x 版本体系。实际项目应选择与 Spring Boot 版本兼容的 Spring AI 版本,并使用对应版本的官方文档。
3.2 添加 Maven 依赖
在 pom.xml 中添加以下依赖:
xml
<properties>
<java.version>17</java.version>
<spring-ai.version>1.0.9</spring-ai.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>${spring-ai.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- Spring Boot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring AI OpenAI 兼容模型适配器 -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-openai</artifactId>
</dependency>
</dependencies>
这里使用 OpenAI 兼容模型适配器,并不意味着只能连接 OpenAI 官方服务。只要目标服务实现了兼容的接口协议,就可以根据服务商提供的地址、密钥和模型名称进行配置。
如果使用其他 Spring AI 版本,请以对应版本的依赖坐标和配置属性为准。
四、配置大模型 API
大模型接口通常需要三个核心参数:
base-url:模型服务的 API 地址。api-key:用于身份认证的访问密钥。model:需要调用的模型名称。
在 src/main/resources/application.yml 中添加配置:
yaml
server:
port: 8080
spring:
ai:
openai:
base-url: ${LLM_BASE_URL}
api-key: ${LLM_API_KEY}
chat:
options:
model: ${LLM_MODEL}
temperature: 0.3
这里通过环境变量注入参数,而不是将真实密钥直接写入源代码。
例如,在本地开发环境中设置:
bash
# 以下地址、密钥和模型名仅为配置示例
export LLM_BASE_URL="https://your-llm-provider.example"
export LLM_API_KEY="your-api-key"
export LLM_MODEL="your-model-name"
注意:
LLM_BASE_URL应填写供应商要求的 API 基础地址,不要未经确认就自行拼接/v1。LLM_MODEL必须使用服务商实际支持的模型标识。temperature用于控制生成随机性,具体支持范围以模型服务为准。
Spring AI 会根据配置自动创建相应的模型组件,并提供可注入的 ChatClient.Builder。
五、第一种方式:使用 ChatClient 调用大模型
这是最常见、也最适合业务开发的调用方式。
5.1 创建业务服务
创建 AiService.java:
java
package com.example.demo.service;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.stereotype.Service;
@Service
public class AiService {
private final ChatClient chatClient;
public AiService(ChatClient.Builder builder) {
this.chatClient = builder.build();
}
public String chat(String message) {
return chatClient.prompt()
.user(message)
.call()
.content();
}
}
这段代码完成了最核心的大模型调用逻辑。
逐步分析:
第一步:构建 ChatClient
java
this.chatClient = builder.build();
通过 Spring 自动配置提供的 ChatClient.Builder 创建客户端,无须手动管理底层 HTTP 请求和 JSON 解析。
第二步:设置用户输入
java
.user(message)
将业务系统收到的问题作为用户消息传给模型。
第三步:发起同步调用
java
.call()
选择同步响应模式。实际模型调用会在读取响应内容等终结操作执行时触发。
第四步:获取文本结果
java
.content();
提取模型生成的文本,方便控制器或其他业务逻辑使用。
5.2 创建 REST 接口
创建 AiController.java:
java
package com.example.demo.controller;
import com.example.demo.service.AiService;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
@RestController
@RequestMapping("/api/ai")
public class AiController {
private final AiService aiService;
public AiController(AiService aiService) {
this.aiService = aiService;
}
@PostMapping("/chat")
public Map<String, String> chat(
@RequestBody Map<String, String> request) {
String message = request.get("message");
if (message == null || message.isBlank()) {
throw new IllegalArgumentException("message 不能为空");
}
String answer = aiService.chat(message);
return Map.of("answer", answer);
}
}
现在,Java 应用已经具备一个可以调用大模型的 HTTP 接口。
5.3 启动与测试
启动 Spring Boot 项目后,使用以下命令测试:
bash
curl -X POST "http://localhost:8080/api/ai/chat" \
-H "Content-Type: application/json" \
-d '{"message":"请解释什么是大语言模型"}'
请求 JSON:
json
{
"message": "请解释什么是大语言模型"
}
返回结果示例:
json
{
"answer": "大语言模型是一类基于大规模文本数据训练的人工智能模型,能够理解和生成自然语言,并执行问答、总结、分类等任务。"
}
以上返回内容仅为格式示例,实际回答由所配置的模型生成。
至此,一个基础的大模型调用服务就搭建完成了。
六、第二种方式:使用 ChatModel 直接调用
除了 ChatClient,还可以直接使用 ChatModel。
java
package com.example.demo.service;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.stereotype.Service;
@Service
public class DirectChatService {
private final ChatModel chatModel;
public DirectChatService(ChatModel chatModel) {
this.chatModel = chatModel;
}
public String chat(String message) {
return chatModel.call(message);
}
}
这种方式更加直接,适合简单的模型调用场景。
两种方式的区别:
| 对比维度 | ChatClient | ChatModel |
|---|---|---|
| API 风格 | 流畅式调用 | 模型抽象接口 |
| 系统指令和用户消息组合 | 方便 | 可通过 Prompt 实现 |
| Advisor 扩展 | 支持 | 通常需自行组织调用流程 |
| 获取文本回答 | .call().content() |
call(message) |
| 推荐用途 | 常规业务开发 | 底层模型调用和精细控制 |
需要注意:如果应用需要在同一个请求中组合系统指令、用户输入、对话记忆以及检索上下文,优先使用 ChatClient 通常更方便。
七、进阶一:通过 System Prompt 约束模型行为
在实际业务中,仅仅将用户问题发送给模型往往不够。我们通常还需要限定模型的身份、输出风格和回答边界。
例如,构建一个面向工业场景的技术助手:
java
public String industrialAssistant(String question) {
return chatClient.prompt()
.system("""
你是一名工业技术助手。
回答应专业、准确、结构清晰。
对于缺少数据支撑的结论,应明确说明不确定性。
不得将未经验证的推测描述为确定事实。
""")
.user(question)
.call()
.content();
}
这里的 system() 用于提供系统级指令,user() 用于传递本次业务问题。
例如,用户询问"如何分析设备振动异常",模型会根据系统指令组织回答,而不是仅依据问题自由发挥。
但要注意:Prompt 只能引导模型行为,并不能保证模型永远正确。对于生产控制、设备保护和安全操作等场景,关键结论仍需要结合实时数据、企业规程及专业人员审核。
八、进阶二:使用模板参数构建动态提示词
实际应用中,提示词往往需要包含动态变量,例如设备名称、测量值和报警等级。
可以通过模板参数组织输入:
java
public String diagnose(String device, String value) {
return chatClient.prompt()
.user(u -> u
.text("""
请分析以下设备数据:
设备名称:{device}
当前测量值:{value}
请给出可能原因、需要核查的数据和后续建议。
""")
.param("device", device)
.param("value", value))
.call()
.content();
}
这种写法比直接拼接长字符串更加清晰,也更容易复用提示词模板。
不过,提示词参数并不等于安全校验。用户输入仍需进行长度限制、权限检查和必要的数据清洗。
九、进阶三:实现流式输出
同步调用需要等待模型生成结果后再返回完整文本。如果模型回答较长,用户可能需要等待较久。
流式输出可以让前端逐步接收生成内容。
Spring AI 的 ChatClient 支持通过 stream() 获取响应流。结合 Spring WebFlux,可以将结果以 Server-Sent Events(SSE)形式返回前端。
在项目中添加响应式 Web 依赖:
xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
创建流式接口:
java
package com.example.demo.controller;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
@RestController
@RequestMapping("/api/ai")
public class AiStreamController {
private final ChatClient chatClient;
public AiStreamController(ChatClient.Builder builder) {
this.chatClient = builder.build();
}
@GetMapping(
value = "/stream",
produces = MediaType.TEXT_EVENT_STREAM_VALUE
)
public Flux<String> stream(
@RequestParam String message) {
return chatClient.prompt()
.user(message)
.stream()
.content();
}
}
测试请求:
bash
curl -N \
"http://localhost:8080/api/ai/stream?message=介绍Spring%20AI"
客户端可以逐步接收模型生成的文本,而不必等到完整回答生成后才开始展示。
注意:流式接口需要模型服务支持流式响应。若使用 Spring MVC 与 WebFlux 混合依赖,应明确项目采用的 Web 技术栈,避免配置冲突。生产环境还需要考虑客户端断开、请求超时、取消订阅及异常事件的处理。
十、企业应用中需要注意的问题
完成接口调用只是第一步。真正上线时,还需要关注以下问题。
10.1 API Key 安全
不要把 API Key 提交到 Git 仓库,也不要通过前端代码直接暴露密钥。应使用环境变量、密钥管理服务或部署平台的 Secret 机制。
10.2 超时与重试
模型接口可能受到网络波动、服务限流和推理耗时影响。需要根据模型服务能力配置合理的连接超时、读取超时及重试策略。
对于限流、网络错误等可恢复异常,可以进行有限次数的退避重试;对于参数错误、认证失败等问题,应优先修复配置,而不是反复请求。
10.3 日志与监控
建议记录请求耗时、模型标识、调用状态、Token 用量和错误类型。生产环境应对敏感数据进行脱敏,避免将密钥、个人信息或企业机密写入普通日志。
10.4 并发与成本控制
大模型调用通常具有较高的网络延迟和推理成本。应根据业务规模设置并发限制、请求队列、调用配额及必要的缓存机制,避免突发请求造成服务过载。
10.5 结果可靠性
大模型回答不应直接等同于业务事实。对于设备联锁、工艺参数调整、质量判定等关键场景,应结合规则引擎、实时数据、权限体系和人工确认机制,确保输出能够被验证和追溯。
十一、总结
Spring AI 为 Java 开发者提供了统一的大模型集成方式。通过 ChatClient,开发者可以使用简洁的链式 API 完成模型调用;通过 ChatModel,可以更直接地访问底层聊天模型能力;结合系统提示词、动态模板和流式响应,还可以逐步构建更加完整的 AI 应用。
对于已经使用 Spring Boot 的企业系统,推荐采用以下演进路线:
- 基础调用: 使用 ChatClient 实现问答接口。
- 业务约束: 添加系统提示词和模板参数。
- 交互优化: 根据需要支持流式输出。
- 知识增强: 通过 Advisors 和向量检索构建 RAG。
- 能力扩展: 接入工具调用、业务 API 和智能体工作流。
- 生产部署: 补齐权限、监控、超时、限流和安全审计。
大模型的价值不仅在于能够回答问题,更在于将语言理解、知识检索和业务系统能力整合到现有应用中。Spring AI 提供了连接这两类能力的一条实用技术路径。