SpringBoot 快速接入AI:从0到1实现智能交互(两种主流方式)
在AI普及的当下,给SpringBoot项目接入AI能力已成为开发者的必备技能——无论是智能问答、文本生成,还是图像处理,只需简单几步,就能让后端服务拥有强大的AI交互能力。本文将结合实战,讲解两种最常用的SpringBoot接入AI方式,兼顾简洁性和实用性,新手也能快速上手,同时规避实际开发中的常见坑点。
核心说明:目前SpringBoot接入AI主要有两种主流路径——Spring AI Starter集成(推荐,官方适配,无需重复造轮子)和直接调用AI平台API(灵活,适配所有提供HTTP API的AI服务)。本文将分别实现两种方式,以OpenAI(GPT系列)为例,同时兼容本地大模型(如Ollama部署的DeepSeek),适配不同开发需求。
前置准备
在开始接入前,需要完成2个基础准备,避免后续踩坑:
- 环境要求:JDK 17+(Spring Boot 3.2+ 及 Spring AI 1.0+ 要求,若使用Spring Boot 2.x,需对应降低Spring AI版本)、Maven/Gradle、IDE(IDEA推荐)。
- AI资源准备:
- 若对接OpenAI:注册OpenAI账号,获取API Key(需注意密钥安全,避免硬编码泄露);
- 若对接本地大模型:通过Ollama部署本地模型(如DeepSeek、Llama 3),获取本地API地址(默认端口11434);
- 若对接国内AI平台(阿里云通义、百度文心一言):注册对应平台账号,获取API Key和API地址,步骤与OpenAI类似。
方式一:Spring AI Starter 集成(推荐,最快上手)
Spring AI 是Spring官方推出的AI集成框架,相当于“AI万能适配器”,封装了主流AI平台的调用逻辑,支持OpenAI、阿里云通义、本地Ollama等多种模型,无需手动处理HTTP请求、序列化等细节,切换模型只需修改配置,极大提升开发效率。
步骤1:创建SpringBoot项目,引入依赖
通过Spring Initializr(https://start.spring.io/)创建项目,选择Spring Boot 3.2.x,引入以下依赖(Maven示例),若使用Gradle,对应转换依赖即可:
<!-- Spring AI OpenAI Starter(对接OpenAI) --> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-openai-spring-boot-starter</artifactId> <version>1.0.0</version> <!-- 对应Spring AI 1.0 GA版本,与Spring Boot 3.2+兼容 --> </dependency> <!-- Spring Web(用于提供接口测试) --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- 可选:若对接本地Ollama,替换为以下依赖 --> <!-- <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-ollama-spring-boot-starter</artifactId> <version>1.0.0</version> </dependency> --> 避坑提醒:Spring Boot 3.2+ 基于Java 17/Jakarta EE 10,与部分旧版AI SDK存在依赖冲突(如Apache HttpClient、Jackson Databind),使用Spring AI Starter可自动处理大部分依赖兼容,无需手动调整。
步骤2:配置AI参数(application.yml)
在resources目录下的application.yml中添加配置,根据对接的AI平台选择对应配置,无需编写额外配置类,Spring AI会自动装配客户端:
配置1:对接OpenAI(GPT-3.5/4.0)
server: port: 8080 # 项目端口,可自定义 spring: ai: openai: api-key: sk-xxxxxxx # 替换为你的OpenAI API Key base-url: https://api.openai.com/v1 # OpenAI官方API地址,若有代理可修改 chat: model: gpt-3.5-turbo # 默认使用的模型,可替换为gpt-4o、gpt-4等 options: temperature: 0.7 # 创造性参数,0.0-1.0,值越高越灵活 num-ctx: 4096 # 上下文窗口大小,控制对话记忆长度 配置2:对接本地Ollama(DeepSeek为例)
server: port: 8080 spring: ai: ollama: base-url: http://localhost:11434 # Ollama默认本地地址 chat: model: deepseek-r1:7b # 本地部署的模型名称,需提前通过ollama pull下载 options: temperature: 0.7 步骤3:编写业务代码,调用AI能力
Spring AI提供了统一的ChatClient接口,无论是对接OpenAI还是Ollama,调用方式完全一致,只需注入ChatClient即可实现同步/流式调用,无需修改业务代码。
3.1 编写AI服务类(Service)
import org.springframework.ai.chat.client.ChatClient; import org.springframework.stereotype.Service; @Service public class AIService { // 构造器注入ChatClient,Spring AI自动装配,无需手动创建 private final ChatClient chatClient; public AIService(ChatClient.Builder chatClientBuilder) { this.chatClient = chatClientBuilder.build(); } /** * 同步调用:适合短文本问答,等待AI完整响应后返回 * @param prompt 用户提问内容 * @return AI响应结果 */ public String syncChat(String prompt) { // 链式调用,简洁高效,无需手动构建请求体 return chatClient.prompt() .user(prompt) // 设置用户提问 .call() // 发起调用 .content(); // 获取AI响应的文本内容 } /** * 流式调用:适合长文本生成(如文章、代码),实现“打字机”效果 * @param prompt 用户提问内容 * @return 流式响应(Flux),前端可逐字渲染 */ public Flux<String> streamChat(String prompt) { return chatClient.prompt() .user(prompt) .stream() // 开启流式调用 .content(); // 逐段获取响应内容 } } 3.2 编写接口(Controller),用于测试
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import reactor.core.publisher.Flux; @RestController public class AIController { @Autowired private AIService aiService; // 同步问答接口,访问方式:http://localhost:8080/ai/sync?prompt=你的问题 @GetMapping("/ai/sync") public String syncChat(@RequestParam String prompt) { return aiService.syncChat(prompt); } // 流式问答接口,设置MediaType为text/event-stream,支持前端流式渲染 @GetMapping(value = "/ai/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE) public Flux<String> streamChat(@RequestParam String prompt) { return aiService.streamChat(prompt); } } 步骤4:启动项目,测试AI接口
- 启动SpringBoot项目,确保配置的API Key或本地Ollama服务正常;
- 测试同步接口:打开浏览器访问
http://localhost:8080/ai/sync?prompt=SpringBoot如何快速接入AI,即可看到AI返回的完整响应; - 测试流式接口:访问
http://localhost:8080/ai/stream?prompt=写一段SpringBoot接入AI的博客开头,可看到响应内容逐字加载(类似ChatGPT的打字机效果)。
方式二:直接调用AI平台API(灵活,适配所有AI服务)
若Spring AI未支持你需要的AI平台,或需要更灵活的请求控制(如自定义请求头、处理复杂响应),可直接调用AI平台提供的HTTP API,手动处理请求和响应,适配性更强。
步骤1:引入HTTP客户端依赖
使用Spring Boot自带的WebClient(非阻塞,推荐)或RestTemplate,这里以WebClient为例,引入依赖:
<!-- WebClient依赖(非阻塞HTTP客户端) --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> </dependency> <!-- Jackson依赖(用于JSON序列化/反序列化) --> <dependency> <groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId> </dependency> 步骤2:配置AI参数(application.yml)
server: port: 8080 openai: api-key: sk-xxxxxxx # 你的OpenAI API Key base-url: https://api.openai.com/v1/chat/completions # OpenAI聊天接口地址 model: gpt-3.5-turbo # 默认模型 步骤3:编写工具类,封装API调用
手动构建请求体、发送HTTP请求、解析响应,这里封装一个工具类,处理同步和流式调用:
import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.stereotype.Component; import org.springframework.web.reactive.function.client.WebClient; import reactor.core.publisher.Flux; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @Component public class OpenAIApiUtil { @Value("${openai.api-key}") private String apiKey; @Value("${openai.base-url}") private String baseUrl; @Value("${openai.model}") private String model; private final WebClient webClient; private final ObjectMapper objectMapper; // 初始化WebClient,设置请求头(认证信息、内容类型) public OpenAIApiUtil(WebClient.Builder webClientBuilder, ObjectMapper objectMapper) { this.webClient = webClientBuilder .baseUrl(baseUrl) .defaultHeader(HttpHeaders.AUTHORIZATION, "Bearer " + apiKey) .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) .build(); this.objectMapper = objectMapper; } /** * 同步调用OpenAI API */ public String syncCall(String prompt) throws Exception { // 1. 构建请求体(符合OpenAI API要求) Map<String, Object> requestBody = new HashMap<>(); requestBody.put("model", model); List<Map<String, String>> messages = new ArrayList<>(); Map<String, String> message = new HashMap<>(); message.put("role", "user"); // 角色:user(用户)、system(系统提示)、assistant(AI响应) message.put("content", prompt); messages.add(message); requestBody.put("messages", messages); // 2. 发送POST请求,获取响应并解析 String response = webClient.post() .bodyValue(requestBody) .retrieve() .bodyToMono(String.class) .block(); // 阻塞等待响应(同步调用) // 3. 解析响应JSON,提取AI回答(简化解析,实际开发可封装实体类) Map<String, Object> responseMap = objectMapper.readValue(response, Map.class); List<Map<String, Object>> choices = (List<Map<String, Object>>) responseMap.get("choices"); Map<String, Object> choice = choices.get(0); Map<String, String> messageMap = (Map<String, String>) choice.get("message"); return messageMap.get("content"); } /** * 流式调用OpenAI API(SSE) */ public Flux<String> streamCall(String prompt) { // 构建请求体,与同步调用一致 Map<String, Object> requestBody = new HashMap<>(); requestBody.put("model", model); requestBody.put("stream", true); // 开启流式响应 List<Map<String, String>> messages = new ArrayList<>(); Map<String, String> message = new HashMap<>(); message.put("role", "user"); message.put("content", prompt); messages.add(message); requestBody.put("messages", messages); // 流式获取响应,逐段解析 return webClient.post() .bodyValue(requestBody) .retrieve() .bodyToFlux(String.class) .map(line -> { // 解析SSE响应格式(过滤空行和结束标识) if (line.isEmpty() || line.equals("data: [DONE]")) { return null; } String data = line.replace("data: ", ""); try { Map<String, Object> responseMap = objectMapper.readValue(data, Map.class); List<Map<String, Object>> choices = (List<Map<String, Object>>) responseMap.get("choices"); Map<String, Object> choice = choices.get(0); Map<String, String> delta = (Map<String, String>) choice.get("delta"); return delta.get("content"); // 返回逐段内容 } catch (Exception e) { return null; } }) .filter(Objects::nonNull); // 过滤空值 } } 步骤4:编写接口测试
与方式一的Controller类似,注入OpenAIApiUtil,提供同步和流式接口,测试方式完全一致,此处不再赘述。
开发避坑与优化建议
结合实际项目经验,总结几个高频避坑点和优化方案,避免上线后出现问题:
- 密钥安全:禁止在配置文件中硬编码API Key,推荐使用环境变量注入、KMS解密或Spring Cloud Vault实现密钥动态轮转,降低泄露风险。
- 超时与熔断:AI接口响应时间波动较大(200ms~60s),需设置分级超时(连接超时5s、请求超时15~45s),并添加熔断降级机制(连续超时触发熔断),避免拖垮服务。
- 上下文管理:长对话场景下,需注意Token限制,避免对话内容被静默截断,可采用“摘要压缩+关键句提取”的双级压缩架构,控制输入Token量。
- 线程安全:高并发场景下,避免共用HTTP客户端导致连接池耗尽,需配置独立线程池,使用同步机制保护共享客户端,预防死锁和资源泄漏。
- 成本监控:对接OpenAI等收费平台时,需监控Token消耗和调用成本,通过AOP切面统计请求Token数,设置成本告警阈值,避免预算超支。
总结
SpringBoot接入AI其实非常简单,两种方式各有优势:
- Spring AI Starter:适合大多数场景,官方封装,无需关注底层实现,切换模型只需修改配置,开发效率最高,新手首选;
- 直接调用API:适合需要灵活定制请求/响应、或对接Spring AI未支持的AI平台,可控性更强,但需手动处理更多细节。
本文的示例代码可直接复制使用,只需替换自己的API Key或本地模型配置,就能快速实现AI交互功能。后续可基于此扩展,实现更复杂的场景(如RAG检索增强、多角色对话、函数调用等),让AI更好地服务于业务。
如果觉得本文对你有帮助,欢迎点赞、收藏,若有疑问或补充,欢迎在评论区交流~