随着大模型技术的普及,企业对智能问答、内容生成等AI能力的集成需求日益迫切。Spring AI作为Spring生态的官方AI开发框架,提供了标准化的大模型集成接口,无需关注不同厂商模型的调用差异,可快速将ChatGPT、文心一言等能力嵌入Java应用。本文以"快速落地"为核心,手把手教你在30分钟内完成Spring AI环境搭建、双模型集成、智能问答接口开发与测试,全程贴合Java开发者技术栈,确保新手也能快速上手。
补充说明:本文基于Spring Boot 3.2.x、Spring AI 0.8.1版本实战,兼容JDK 17+(推荐版本),同时覆盖ChatGPT(OpenAI API)与文心一言(百度智能云API)两种主流模型,可根据需求灵活切换。
一、前置准备(5分钟)
集成前需完成环境配置与API密钥申请,为后续开发扫清障碍,核心准备工作分为三步:
1. 环境要求确认
-
JDK:17+(Spring AI 0.8.x及以上版本不再支持JDK 11及以下);
-
构建工具:Maven 3.8+ 或 Gradle 7.5+(本文以Maven为例);
-
依赖管理:Spring Boot 3.2.x(确保与Spring AI版本兼容);
-
网络环境:需能访问外网(集成ChatGPT)或百度智能云服务(集成文心一言)。
2. API密钥申请
需分别申请对应模型的API密钥,用于接口调用鉴权:
-
ChatGPT密钥 :登录OpenAI官网(https://platform.openai.com/),进入API Keys页面创建密钥,记录密钥信息(后续配置使用,切勿泄露);
-
文心一言密钥 :登录百度智能云官网(https://cloud.baidu.com/),开通"文心一言"服务,创建应用后获取API Key与Secret Key(双密钥鉴权)。
注意:两种模型均有免费额度(OpenAI新用户有试用金额,百度智能云提供免费调用次数),适合前期开发测试;生产环境需根据并发量购买对应套餐。
3. 项目初始化
通过Spring Initializr(https://start.spring.io/)快速初始化Spring Boot项目,核心依赖选择:
-
Spring Web(用于开发RESTful接口);
-
Spring AI OpenAI(集成ChatGPT);
-
Spring AI Baidu(集成文心一言);
-
Lombok(可选,简化实体类代码)。
生成项目后下载解压,用IDEA或Eclipse打开,进入后续依赖配置环节。
二、依赖配置与环境搭建(5分钟)
Spring AI已将不同大模型的集成封装为starter依赖,只需在pom.xml中引入对应依赖,再配置API密钥即可完成环境搭建。
1. 核心依赖配置(pom.xml)
在pom.xml中添加Spring AI核心依赖与模型依赖,确保版本统一:
xml
<!-- Spring Boot 父依赖 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.5</version>
<relativePath/>
</parent>
<dependencies>
<!-- Spring Web 核心依赖(开发接口用) -->
<dependency>
<groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring AI 核心依赖 -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-core</artifactId>
<version>0.8.1</version>
</dependency>
<!-- Spring AI OpenAI 依赖(集成ChatGPT) -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-openai-spring-boot-starter</artifactId>
<version>0.8.1</version>
</dependency>
<!-- Spring AI 百度文心一言依赖 -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-baidu-spring-boot-starter</artifactId>
<version>0.8.1</version>
</dependency>
<!-- Lombok 简化代码(可选) -->
<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>
<!-- 配置Spring仓库(部分Spring AI依赖需从Spring仓库获取) -->
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
2. 模型密钥配置(application.yml)
在src/main/resources下创建application.yml文件,配置ChatGPT与文心一言的API密钥、模型参数,支持灵活切换模型:
yaml
spring:
application:
name: spring-ai-quickstart
# Spring AI 配置
ai:
# 默认使用的模型(可切换为baidu或openai)
default-ai-client: openai
# OpenAI(ChatGPT)配置
openai:
api-key: sk-your-openai-api-key # 替换为你的OpenAI API密钥
model: gpt-3.5-turbo # 模型版本(gpt-3.5-turbo性价比最高,适合测试)
temperature: 0.7 # 生成内容随机性(0-1,值越大越随机)
max-tokens: 2048 # 单次响应最大token数
# 百度文心一言配置
baidu:
api-key: your-baidu-api-key # 替换为你的百度API Key
secret-key: your-baidu-secret-key # 替换为你的百度Secret Key
model: ernie-3.5 # 模型版本(ernie-3.5为免费常用版本)
temperature: 0.7
max-tokens: 2048
# 服务器配置(可选,默认8080端口)
server:
port: 8080
关键说明:① default-ai-client用于指定默认模型,切换时只需修改为baidu或openai即可;② temperature参数控制生成内容的创造性,0为确定性输出,1为最大随机性,测试阶段建议设为0.7;③ 若需代理访问OpenAI,可在openai配置下添加proxy-host与proxy-port参数。
三、核心功能开发(15分钟)
基于Spring AI封装的API,快速开发智能问答接口,支持单轮问答、多轮对话,同时实现模型动态切换功能,全程无需编写复杂的HTTP调用逻辑。
1. 实体类定义(用于接口请求/响应)
创建实体类封装接口请求参数与响应结果,使用Lombok简化getter/setter方法:
java
import lombok.Data;
/**
* 智能问答请求参数
*/
@Data
public class ChatRequest {
// 提问内容
private String question;
// 模型类型(openai/baidu,可选,默认使用配置文件中的default-ai-client)
private String modelType;
// 对话ID(多轮对话用,用于关联上下文)
private String conversationId;
}
/**
* 智能问答响应结果
*/
@Data
public class ChatResponse {
// 响应状态(success/fail)
private String status;
// 回答内容
private String answer;
// 对话ID(多轮对话返回,用于后续上下文关联)
private String conversationId;
// 模型类型(实际使用的模型)
private String modelType;
// 错误信息(失败时返回)
private String errorMsg;
}
2. 服务层开发(封装AI调用逻辑)
创建服务类,注入Spring AI提供的ChatClient接口,封装单轮问答、多轮对话逻辑,支持模型动态切换:
java
import org.springframework.ai.chat.ChatClient;
import org.springframework.ai.chat.ChatResponse;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.openai.OpenAiChatClient;
import org.springframework.ai.baidu.BaiduChatClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
@Service
public class AIService {
// 注入默认ChatClient(由配置文件default-ai-client指定)
@Autowired
private ChatClient defaultChatClient;
// 注入OpenAI客户端(单独调用ChatGPT时使用)
@Autowired(required = false)
private OpenAiChatClient openAiChatClient;
// 注入百度文心一言客户端(单独调用时使用)
@Autowired(required = false)
private BaiduChatClient baiduChatClient;
// 存储多轮对话上下文(key:conversationId,value:对话历史)
private final ConcurrentHashMap<String, StringBuilder> conversationContext = new ConcurrentHashMap<>();
/**
* 智能问答核心方法(支持单轮/多轮、动态切换模型)
*/
public ChatResponse chat(com.example.ai.dto.ChatRequest request) {
ChatResponse response = new ChatResponse();
try {
// 生成/获取对话ID(多轮对话关联上下文)
String conversationId = request.getConversationId() == null ?
UUID.randomUUID().toString() : request.getConversationId();
// 获取对话历史上下文
StringBuilder context = conversationContext.getOrDefault(conversationId, new StringBuilder());
// 选择要使用的模型客户端
ChatClient chatClient = selectChatClient(request.getModelType());
String modelType = request.getModelType() == null ? "openai" : request.getModelType();
// 拼接上下文(多轮对话)
String fullQuestion = context.append("用户:").append(request.getQuestion()).append("\n").toString();
// 构建用户消息
Message userMessage = new UserMessage(fullQuestion);
Prompt prompt = new Prompt(userMessage);
// 调用AI模型获取回答
org.springframework.ai.chat.ChatResponse aiResponse = chatClient.call(prompt);
String answer = aiResponse.getResult().getOutput().getContent();
// 更新对话上下文
context.append("AI:").append(answer).append("\n");
conversationContext.put(conversationId, context);
// 封装响应结果
response.setStatus("success");
response.setAnswer(answer);
response.setConversationId(conversationId);
response.setModelType(modelType);
} catch (Exception e) {
response.setStatus("fail");
response.setErrorMsg("问答失败:" + e.getMessage());
}
return response;
}
/**
* 选择模型客户端
*/
private ChatClient selectChatClient(String modelType) {
if (modelType == null || modelType.isEmpty()) {
return defaultChatClient; // 使用默认模型
}
return switch (modelType.toLowerCase()) {
case "baidu" -> baiduChatClient;
case "openai" -> openAiChatClient;
default -> defaultChatClient;
};
}
/**
* 清除对话上下文(多轮对话结束后调用)
*/
public void clearConversationContext(String conversationId) {
conversationContext.remove(conversationId);
}
}
关键说明:① 多轮对话通过conversationId关联上下文,将历史对话存储在ConcurrentHashMap中(生产环境可替换为Redis,支持分布式部署);② selectChatClient方法实现模型动态切换,根据请求参数选择对应的客户端;③ 异常捕获确保接口稳定,避免因模型调用失败导致服务宕机。
3. 接口层开发(RESTful接口)
创建控制器,开发智能问答接口、清除上下文接口,对外提供HTTP服务:
java
import com.example.ai.dto.ChatRequest;
import com.example.ai.dto.ChatResponse;
import com.example.ai.service.AIService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/ai")
@Slf4j
public class AIController {
@Autowired
private AIService aiService;
/**
* 智能问答接口(支持GET/POST,方便测试)
*/
@PostMapping("/chat")
public ChatResponse chat(@RequestBody ChatRequest request) {
log.info("接收AI问答请求:question={}, modelType={}, conversationId={}",
request.getQuestion(), request.getModelType(), request.getConversationId());
return aiService.chat(request);
}
/**
* GET方式接口(方便浏览器快速测试)
*/
@GetMapping("/chat")
public ChatResponse chatGet(
@RequestParam String question,
@RequestParam(required = false) String modelType,
@RequestParam(required = false) String conversationId) {
ChatRequest request = new ChatRequest();
request.setQuestion(question);
request.setModelType(modelType);
request.setConversationId(conversationId);
return aiService.chat(request);
}
/**
* 清除对话上下文接口
*/
@DeleteMapping("/conversation/{conversationId}")
public String clearConversation(@PathVariable String conversationId) {
aiService.clearConversationContext(conversationId);
return "对话上下文已清除:" + conversationId;
}
}
4. 启动类编写
创建Spring Boot启动类,开启Spring Web支持:
java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringAiQuickstartApplication {
public static void main(String[] args) {
SpringApplication.run(SpringAiQuickstartApplication.class, args);
System.out.println("Spring AI 智能问答服务启动成功!访问地址:http://localhost:8080/api/ai/chat");
}
}
四、接口测试与验证(5分钟)
启动项目后,通过Postman、浏览器或curl命令测试接口,验证ChatGPT、文心一言的调用效果,同时测试多轮对话功能。
1. 启动项目
运行SpringAiQuickstartApplication的main方法,控制台输出"Spring AI 智能问答服务启动成功"即表示环境搭建正常。
2. 单轮问答测试(ChatGPT)
通过浏览器访问GET接口,测试ChatGPT回答效果:
响应结果示例:
3. 单轮问答测试(文心一言)
修改modelType参数为baidu,测试文心一言:
响应结果示例:
4. 多轮对话测试
使用上一轮返回的conversationId,关联上下文进行多轮对话:
AI会基于上一轮"Spring AI是什么"的对话上下文回答,实现连贯的多轮交互。
五、常见问题与避坑指南
1. API密钥无效或权限不足
现象:接口响应失败,errorMsg提示"Invalid API key"或"Insufficient quota"。解决方案:① 检查API密钥是否正确,有无多余空格;② 确认密钥未过期、未泄露,OpenAI密钥可在官网重置;③ 检查账号余额或免费额度是否耗尽,及时充值或更换账号。
2. 无法访问OpenAI服务
现象:调用ChatGPT时超时,提示"Connection timed out"。解决方案:① 配置代理,在application.yml的openai配置下添加proxy-host和proxy-port;② 确保代理能正常访问外网,无端口限制;③ 若无法使用代理,可优先测试文心一言(国内可直接访问)。
3. 模型客户端注入失败
现象:启动项目时报错"Could not autowire field: OpenAiChatClient"。解决方案:① 检查pom.xml中对应模型的依赖是否引入,版本是否与Spring AI一致;② 确认配置文件中模型密钥是否填写,无密钥会导致客户端无法初始化。
4. 多轮对话上下文丢失
现象:多轮对话时AI无法关联历史内容。解决方案:① 确保每次请求都携带正确的conversationId;② 生产环境建议将上下文存储在Redis中,而非本地Map(避免服务重启后丢失)。
六、进阶优化建议(可选)
若需将接口用于生产环境,可从以下维度优化,提升稳定性与性能:
-
上下文存储优化:将对话历史从ConcurrentHashMap迁移至Redis,支持分布式部署,同时设置过期时间(如30分钟),避免内存溢出;
-
限流与熔断:通过Sentinel或Resilience4j对接口限流,避免因高频调用触发模型API的限流机制;添加熔断逻辑,模型调用失败时降级返回预设内容;
-
日志与监控:记录每一次问答请求与响应,集成Spring Boot Actuator+Prometheus监控接口调用量、响应时间;
-
模型参数优化:根据业务场景调整temperature、max-tokens参数,如知识问答场景temperature设为0.2(更精准),内容生成场景设为0.8(更多样);
-
多模型负载均衡:实现模型轮询调用,当一个模型不可用时自动切换至另一个模型,提升服务可用性。
七、总结
本文通过"前置准备-环境搭建-功能开发-接口测试"四步流程,30分钟内完成了Spring AI集成ChatGPT与文心一言的智能问答接口开发。Spring AI的核心价值在于提供了标准化的AI调用接口,屏蔽了不同厂商模型的调用差异,让Java开发者无需掌握复杂的HTTP请求、鉴权逻辑,即可快速集成AI能力。
后续可基于本文基础,扩展更多功能:如内容生成、代码辅助、智能客服等,适配不同业务场景。对于Java开发者而言,Spring AI降低了AI应用的开发门槛,让传统Java应用快速具备智能化能力,是云原生时代AI与业务融合的优选工具。