Spring Boot + Spring AI 完整实战手册
**从零到生产 完整实战手册:**基础 + 进阶 + 生产踩坑 + 多模型 + 容错 + RAG + 函数调用
目录
- 版本适配与前置约束
- 完整依赖配置(BOM + 多模型)
- 全量配置文件详解
- 核心两大 API:ChatModel / ChatClient
- 基础对话、角色设定、Prompt 模板
- 流式 SSE 输出(含异常兜底)
- 标准多轮对话(内置 ChatMemory 防溢出)
- 多模型无缝切换(OpenAI / 通义 / Ollama)
- 函数调用 Function Calling 完整实现
- RAG 检索增强生成全流程
- 全局异常处理 & AI 专属异常
- 生产级:超时、重试、熔断、降级
- 拦截器、监控、日志可观测
- 企业级最佳实践 & 红线禁忌
- 高频踩坑问题汇总
1. 版本适配与前置约束
1.1 强版本绑定(必遵守)
- Spring AI 1.1.x → Spring Boot 3.2.x | JDK17+
- Spring AI 1.2.x → Spring Boot 3.3.x
- Spring AI 2.0.x → Spring Boot 3.4+ | JDK21+
1.2 核心前置规则
- 必须引入 Spring AI BOM 统一版本,杜绝依赖冲突
- 引入对应模型 Starter 即可自动装配,无需手动创建 Bean
- API Key 禁止硬编码,使用环境变量 / 配置中心托管
- 所有 AI 接口必须配置超时、重试、异常兜底
- 多轮对话必须做上下文裁剪,防止 Token 溢出
2. 完整依赖配置
2.1 统一版本 BOM
xml
XML
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>1.1.4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
2.2 基础核心依赖
xml
XML
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- OpenAI -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-openai-spring-boot-starter</artifactId>
</dependency>
<!-- 阿里云通义千问 -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-dashscope-spring-boot-starter</artifactId>
</dependency>
<!-- 本地 Ollama 离线模型 -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-ollama-spring-boot-starter</artifactId>
</dependency>
<!-- RAG 向量库 -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-pgvector-store-spring-boot-starter</artifactId>
</dependency>
<!-- 重试容错 -->
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
</dependencies>
2.3 仓库配置
xml
XML
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</repository>
</repositories>
3. 全量配置文件(application.yml)
yaml
XML
spring:
ai:
# 全局公共配置
chat:
options:
temperature: 0.5
max-tokens: 2048
top-p: 0.9
timeout: 30s
system-prompt: 你是资深Java架构师,回答精简专业,附带可运行代码
# OpenAI 配置
openai:
api-key: ${OPENAI_API_KEY:}
base-url: https://api.openai.com/v1
connection-timeout: 15000
read-timeout: 30000
chat:
options:
model: gpt-3.5-turbo
# 通义千问配置
dashscope:
api-key: ${DASHSCOPE_API_KEY:}
chat:
options:
model: qwen-plus
# Ollama 本地模型
ollama:
base-url: http://localhost:11434
chat:
options:
model: qwen2.5
# 关闭指定自动配置(排错使用)
autoconfigure:
exclude:
- org.springframework.ai.openai.autoconfigure.OpenAiChatAutoConfiguration
4. 核心两大 API
4.1 底层原生 ChatModel(自由度高)
java
@RestController
@RequiredArgsConstructor
public class AiController {
private final ChatModel chatModel;
@GetMapping("/model/chat")
public String modelChat(String msg) {
ChatRequest request = ChatRequest.builder()
.messages(List.of(new UserMessage(msg)))
.temperature(0.5)
.build();
return chatModel.call(request).getResult().getOutput().getContent();
}
}
4.2 高层推荐 ChatClient(企业首选)
自动装配、链式调用、拦截器、记忆、模板一体化
java
private final ChatClient chatClient;
@GetMapping("/client/chat")
public String clientChat(String msg) {
return chatClient.prompt()
.user(msg)
.call()
.content();
}
5. 进阶能力
5.1 全局角色 + 单次临时角色
java
@GetMapping("/system/chat")
public String systemChat(String msg) {
return chatClient.prompt()
.system("你是Redis高级专家,回答精简,只讲核心原理")
.user(msg)
.call()
.content();
}
5.2 Prompt 模板化(杜绝硬编码)
java
@GetMapping("/template/chat")
public String templateChat(String question) {
String promptStr = """
请以Java工程师视角解答问题:
问题:{question}
要求:精简、带代码示例、避免废话
""";
PromptTemplate template = new PromptTemplate(promptStr);
Prompt prompt = template.create(Map.of("question", question));
return chatClient.call(prompt).getResult().getOutput().getContent();
}
6. 流式 SSE 输出(生产标准写法)
自带异常兜底、SSE 标准响应头、空值防护
java
@GetMapping(value = "/ai/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> streamChat(String prompt) {
return chatClient.stream()
.user(prompt)
.stream()
.map(res -> Optional.ofNullable(res.getResult().getOutput().getContent()).orElse(""))
.onErrorResume(e -> Flux.just("AI服务调用异常,请稍后重试"));
}
7. 标准多轮对话(内置 ChatMemory)
自动管理上下文、限制最大轮次、防止无限膨胀
java
// 全局单例内存记忆,保留最近5轮
private final ChatMemory chatMemory = new InMemoryChatMemory(5);
@GetMapping("/multi/chat")
public String multiChat(String msg) {
return chatClient.prompt()
.user(msg)
.chatMemory(chatMemory)
.call()
.content();
}
8. 多模型无缝切换
- 只更换 starter 依赖 + 配置
- 业务代码
ChatClient完全不用改 - 适用:OpenAI、通义千问、文心一言、讯飞星火、Ollama
核心价值:一套代码,适配所有大模型。
9. 函数调用 Function Calling
9.1 定义业务工具
java
@Configuration
public class AiFunctionConfig {
@Bean
@Description("根据用户id查询订单信息")
public Function<OrderQueryReq, OrderResp> getOrderInfo(OrderService orderService) {
return req -> orderService.getOrder(req.userId());
}
}
// 请求/响应
record OrderQueryReq(String userId) {}
record OrderResp(String orderNo, String status, BigDecimal amount) {}
9.2 开启函数调用
java
@GetMapping("/function/chat")
public String functionChat(String msg) {
return chatClient.prompt()
.user(msg)
.functions("getOrderInfo")
.call()
.content();
}
10. RAG 检索增强生成(企业知识库)
10.1 核心流程
文档加载 → 文本分片 → 向量化 → 向量库存储 → 相似度检索 → 拼接上下文 → AI 回答
10.2 核心代码
java
@Service
@RequiredArgsConstructor
public class RagService {
private final ChatClient chatClient;
private final VectorStore vectorStore;
// 初始化文档入库
@PostConstruct
public void loadDoc() {
List<Document> docs = new PagePdfDocumentReader(new ClassPathResource("company-doc.pdf")).get();
TextSplitter splitter = new TokenTextSplitter(500, 50, 10, 100);
vectorStore.add(splitter.apply(docs));
}
// RAG问答
public String ragChat(String question) {
List<Document> relatedDocs = vectorStore.similaritySearch(
SearchRequest.query(question).withTopK(3).withSimilarityThreshold(0.7)
);
String context = relatedDocs.stream().map(Document::getContent).collect(Collectors.joining("\n"));
String prompt = """
严格根据下方参考资料回答问题,禁止编造内容:
参考资料:%s
问题:%s
""".formatted(context, question);
return chatClient.prompt().user(prompt).call().content();
}
}
11. 全局异常处理
java
@RestControllerAdvice
@Slf4j
public class AiGlobalExceptionHandler {
@ExceptionHandler(ApiKeyInvalidException.class)
public Result<Void> apiKeyErr() {
return Result.fail(5001, "AI密钥配置错误或已过期");
}
@ExceptionHandler(TimeoutException.class)
public Result<Void> timeoutErr() {
return Result.fail(5002, "大模型请求超时");
}
@ExceptionHandler(Exception.class)
public Result<Void> aiCommonErr(Exception e) {
log.error("AI调用异常", e);
return Result.fail(5000, "AI服务暂时不可用");
}
}
12. 生产级容错
12.1 重试机制
java
@EnableRetry
@SpringBootApplication
public class AiApplication {}
// 业务方法
@Retryable(maxAttempts = 3, delay = 1000, retryFor = TimeoutException.class)
public String aiChat(String msg) {
return chatClient.prompt().user(msg).call().content();
}
12.2 降级策略
- 主模型异常自动切换备用模型
- 高频问题本地缓存兜底
- 限制 max-tokens 控制成本
13. 拦截器与监控
全局 AI 请求拦截器(耗时、Token、日志)
java
@Bean
public ChatClientCustomizer chatClientCustomizer() {
return builder -> builder.defaultInterceptors(context -> {
long start = System.currentTimeMillis();
// 请求前
context.advance();
// 响应后
long cost = System.currentTimeMillis() - start;
log.info("AI调用耗时:{}ms,模型:{}", cost, context.getPrompt().getChatOptions().getModel());
});
}
14. 企业级最佳实践
- 环境变量托管 APIKey,杜绝明文配置
- 统一全局 system-prompt,规范 AI 输出风格
- 所有接口强制超时时间,避免线程阻塞
- 多轮对话限制上下文长度,控制 Token 成本
- RAG 必须配置相似度阈值,减少无关文档
- 流式接口统一 SSE 协议,增加异常熔断
- 接入监控:调用量、耗时、失败率、Token 消耗
- 敏感内容过滤、输出内容安全校验
15. 高频踩坑汇总
- 版本不匹配 → 自动配置失效、Bean 找不到
- 国内网络无法访问 OpenAI → 配置代理 / 切换国产模型
- 多轮对话上下文无限累积 → 使用 ChatMemory 限制轮次
- RAG 回答乱编 → 增加相似度阈值、强约束 prompt
- 流式输出乱码 / 中断 → 标准 SSE 响应头 + 异常兜底
- 函数调用不生效 → 缺少 @Description 注解、参数不规范
- 大模型接口超时 → 调整超时时间、增加重试
- 依赖混乱 → 必须使用 Spring AI BOM
所有模块:底层双 API、全量配置、内存会话记忆、模板提示词、拦截器监控、生产容错、异常体系、多模型、RAG 完整落地、踩坑避坑。