Spring AI 快速开始
Spring AI 快速开始
学习目标
- 理解 Spring AI 框架的核心价值和应用场景
- 掌握 Spring AI 的快速上手方法
- 能够在 5 分钟内创建第一个 AI 应用
- 了解 Spring AI 的学习路线和资源
- 建立对 AI 应用开发的整体认知
知识结构
一、项目场景引入
1.1 实际项目需求
在现代企业应用中,AI 能力正在成为标配:
场景 1:智能客服系统
需求:电商平台需要 7x24 小时回答用户咨询
传统方案:雇佣大量客服人员,成本高、响应慢
AI 方案:使用 AI 自动回答常见问题,人工处理复杂问题
场景 2:文档问答系统
需求:企业内部有大量技术文档,员工查找困难
传统方案:手动搜索文档,效率低下
AI 方案:基于企业知识库的智能问答系统
场景 3:代码助手
需求:帮助开发者快速生成代码、审查代码
传统方案:手动编写、人工审查
AI 方案:AI 辅助代码生成和审查
1.2 技术挑战
直接使用 AI 模型 API 面临的问题:
-
API 调用复杂
- 不同模型提供商的 API 格式不同
- 需要处理 HTTP 请求、认证、错误处理
- 代码重复度高
-
缺乏统一抽象
- OpenAI、Azure、本地模型接口各不相同
- 切换模型需要大量代码修改
- 难以维护
-
缺少企业级特性
- 没有现成的缓存机制
- 没有统一的异常处理
- 没有监控和日志
-
与 Spring 生态集成困难
- 需要手动管理 Bean
- 配置管理不统一
- 难以利用 Spring 的依赖注入
1.3 Spring AI 的解决方案
Spring AI 提供了统一的抽象层:
传统方式:
应用代码 → OpenAI API
应用代码 → Azure API
应用代码 → Ollama API
(每个都需要不同的代码)
Spring AI 方式:
应用代码 → Spring AI 抽象层 → 各种 AI 模型
(统一的接口,配置切换)
核心优势:
- ✅ 统一的编程接口
- ✅ 配置化的模型切换
- ✅ Spring Boot 自动配置
- ✅ 企业级特性支持
- ✅ 完善的文档和社区
二、Spring AI 核心思想
2.1 一句话总结
Spring AI = Spring Boot + AI 模型的统一抽象
让 Java 开发者像使用 Spring Data 一样简单地使用 AI
2.2 设计理念
1. 可移植性(Portability)
// 同样的代码,只需修改配置就能切换模型
ChatClient chatClient; // 可以是 OpenAI、Azure、Ollama...
String response = chatClient.call("你好");
2. 模块化(Modularity)
spring-ai-core # 核心抽象
spring-ai-openai # OpenAI 实现
spring-ai-azure-openai # Azure 实现
spring-ai-ollama # Ollama 实现
3. Spring 原生(Spring Native)
@Service
public class AIService {
@Autowired
private ChatClient chatClient; // 自动注入
public String chat(String message) {
return chatClient.call(message);
}
}
2.3 核心组件
组件说明:
| 组件 | 作用 | 示例 |
|---|---|---|
| ChatClient | 对话交互 | 聊天机器人、问答系统 |
| EmbeddingClient | 文本向量化 | 语义搜索、文档检索 |
| ImageClient | 图像生成 | AI 绘画、图像处理 |
| VectorStore | 向量存储 | 知识库、RAG 应用 |
三、5 分钟快速上手
3.1 前置准备
环境要求:
- JDK 17 或更高版本
- Maven 3.6+ 或 Gradle 7.5+
- IDE(推荐 IntelliJ IDEA)
- OpenAI API Key(或其他模型的访问凭证)
获取 API Key:
- 访问 https://platform.openai.com/
- 注册账号并登录
- 进入 API Keys 页面
- 创建新的 API Key
- 保存 Key(只显示一次)
3.2 创建 Spring Boot 项目
方式 1:使用 Spring Initializr
访问 https://start.spring.io/,配置如下:
Project: Maven
Language: Java
Spring Boot: 3.2.0 或更高
Group: com.example
Artifact: spring-ai-demo
Name: spring-ai-demo
Package name: com.example.springai
Packaging: Jar
Java: 17
方式 2:使用 IDEA 创建
File → New → Project → Spring Initializr
填写项目信息
选择 Spring Boot 版本 3.2.0+
3.3 添加依赖
编辑 pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.0</version>
<relativePath/>
</parent>
<groupId>com.example</groupId>
<artifactId>spring-ai-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-ai-demo</name>
<description>Spring AI Demo Project</description>
<properties>
<java.version>17</java.version>
<spring-ai.version>0.8.1</spring-ai.version>
</properties>
<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-openai-spring-boot-starter</artifactId>
</dependency>
<!-- Lombok(可选,简化代码) -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- Spring Boot Test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<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>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<!-- Spring Milestone 仓库 -->
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
</project>
3.4 配置 API Key
创建 src/main/resources/application.yml:
spring:
application:
name: spring-ai-demo
ai:
openai:
# OpenAI API Key
api-key: ${OPENAI_API_KEY}
# 聊天模型配置
chat:
options:
model: gpt-3.5-turbo
temperature: 0.7
max-tokens: 1000
# 服务器配置
server:
port: 8080
# 日志配置
logging:
level:
org.springframework.ai: DEBUG
配置说明:
| 配置项 | 说明 | 默认值 |
|---|---|---|
| api-key | OpenAI API 密钥 | 必填 |
| model | 使用的模型 | gpt-3.5-turbo |
| temperature | 创造性(0-2) | 0.7 |
| max-tokens | 最大输出长度 | 无限制 |
环境变量设置:
Windows:
set OPENAI_API_KEY=sk-your-api-key-here
Linux/Mac:
export OPENAI_API_KEY=sk-your-api-key-here
或者在 IDEA 中配置:
Run → Edit Configurations → Environment Variables
添加:OPENAI_API_KEY=sk-your-api-key-here
3.5 编写第一个 AI 应用
项目结构:
src/main/java/com/example/springai/
├── SpringAiDemoApplication.java # 启动类
├── controller/
│ └── ChatController.java # 控制器
├── service/
│ └── ChatService.java # 服务层
└── dto/
├── ChatRequest.java # 请求对象
└── ChatResponse.java # 响应对象
1. 创建 DTO 类
ChatRequest.java:
package com.example.springai.dto;
import lombok.Data;
/**
* 聊天请求对象
*/
@Data
public class ChatRequest {
/**
* 用户消息
*/
private String message;
}
ChatResponse.java:
package com.example.springai.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 聊天响应对象
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ChatResponse {
/**
* AI 回复
*/
private String reply;
/**
* 响应时间(毫秒)
*/
private Long responseTime;
}
2. 创建服务层
ChatService.java:
package com.example.springai.service;
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.stereotype.Service;
/**
* AI 聊天服务
* 项目场景:智能客服系统的核心服务
*/
@Service
public class ChatService {
private final ChatClient chatClient;
/**
* 构造函数注入 ChatClient
* Spring AI 会自动配置并注入 ChatClient Bean
*/
public ChatService(ChatClient chatClient) {
this.chatClient = chatClient;
}
/**
* 简单对话
*
* @param userMessage 用户消息
* @return AI 回复
*/
public String simpleChat(String userMessage) {
// 直接调用 call 方法,传入字符串
return chatClient.call(userMessage);
}
/**
* 标准对话(推荐方式)
*
* @param userMessage 用户消息
* @return ChatResponse 包含完整的响应信息
*/
public ChatResponse chat(String userMessage) {
// 1. 创建用户消息对象
Message message = new UserMessage(userMessage);
// 2. 创建 Prompt(提示词)
Prompt prompt = new Prompt(message);
// 3. 调用 AI 模型
ChatResponse response = chatClient.call(prompt);
// 4. 返回响应
return response;
}
/**
* 获取 AI 回复文本
*
* @param userMessage 用户消息
* @return AI 回复文本
*/
public String getChatReply(String userMessage) {
ChatResponse response = chat(userMessage);
return response.getResult().getOutput().getContent();
}
}
3. 创建控制器
ChatController.java:
package com.example.springai.controller;
import com.example.springai.dto.ChatRequest;
import com.example.springai.dto.ChatResponse;
import com.example.springai.service.ChatService;
import org.springframework.web.bind.annotation.*;
/**
* AI 聊天控制器
* 提供 RESTful API 接口
*/
@RestController
@RequestMapping("/api/chat")
public class ChatController {
private final ChatService chatService;
public ChatController(ChatService chatService) {
this.chatService = chatService;
}
/**
* 简单聊天接口
* GET /api/chat/simple?message=你好
*
* @param message 用户消息
* @return AI 回复
*/
@GetMapping("/simple")
public String simpleChat(@RequestParam String message) {
return chatService.simpleChat(message);
}
/**
* 标准聊天接口
* POST /api/chat
* Body: {"message": "你好"}
*
* @param request 聊天请求
* @return 聊天响应
*/
@PostMapping
public ChatResponse chat(@RequestBody ChatRequest request) {
long startTime = System.currentTimeMillis();
// 调用服务层
String reply = chatService.getChatReply(request.getMessage());
long responseTime = System.currentTimeMillis() - startTime;
// 返回响应
return new ChatResponse(reply, responseTime);
}
/**
* 健康检查接口
* GET /api/chat/health
*
* @return 健康状态
*/
@GetMapping("/health")
public String health() {
return "Spring AI is running!";
}
}
4. 启动类
SpringAiDemoApplication.java:
package com.example.springai;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* Spring AI 演示应用
*/
@SpringBootApplication
public class SpringAiDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SpringAiDemoApplication.class, args);
}
}
3.6 运行和测试
1. 启动应用
# 方式 1:使用 Maven
mvn spring-boot:run
# 方式 2:使用 IDEA
右键 SpringAiDemoApplication → Run
# 方式 3:打包后运行
mvn clean package
java -jar target/spring-ai-demo-0.0.1-SNAPSHOT.jar
2. 测试接口
使用 curl 测试:
# 测试健康检查
curl http://localhost:8080/api/chat/health
# 测试简单聊天(GET)
curl "http://localhost:8080/api/chat/simple?message=你好"
# 测试标准聊天(POST)
curl -X POST http://localhost:8080/api/chat \
-H "Content-Type: application/json" \
-d '{"message": "介绍一下 Spring AI"}'
使用 Postman 测试:
1. 创建 POST 请求
2. URL: http://localhost:8080/api/chat
3. Headers: Content-Type: application/json
4. Body (raw JSON):
{
"message": "你好,请介绍一下自己"
}
5. 点击 Send
3. 预期响应
{
"reply": "你好!我是一个 AI 助手,基于 Spring AI 框架开发。我可以回答各种问题,提供信息和建议。有什么我可以帮助你的吗?",
"responseTime": 1523
}
3.7 代码执行流程
四、核心概念速览
4.1 ChatClient
作用: 与 AI 模型进行对话交互的客户端
核心方法:
// 方法 1:简单调用
String reply = chatClient.call("你好");
// 方法 2:使用 Prompt
Prompt prompt = new Prompt("你好");
ChatResponse response = chatClient.call(prompt);
// 方法 3:流式响应
Flux<ChatResponse> stream = chatClient.stream(prompt);
自动配置:
// Spring AI 自动配置,无需手动创建
@Autowired
private ChatClient chatClient;
4.2 Prompt(提示词)
作用: 封装发送给 AI 模型的消息和参数
组成部分:
Prompt = Messages + Options
↓ ↓
消息内容 模型参数
示例:
// 1. 简单 Prompt
Prompt prompt = new Prompt("你好");
// 2. 带消息的 Prompt
Message message = new UserMessage("你好");
Prompt prompt = new Prompt(message);
// 3. 带参数的 Prompt
OpenAiChatOptions options = OpenAiChatOptions.builder()
.withModel("gpt-4")
.withTemperature(0.8)
.build();
Prompt prompt = new Prompt("你好", options);
4.3 Message(消息)
消息类型:
| 类型 | 类名 | 作用 | 示例 |
|---|---|---|---|
| 用户消息 | UserMessage | 用户输入 | “你好” |
| 系统消息 | SystemMessage | 设定角色 | “你是一个专业的客服” |
| 助手消息 | AssistantMessage | AI 回复 | “你好,有什么可以帮助你的?” |
示例:
// 用户消息
Message userMsg = new UserMessage("介绍一下 Spring AI");
// 系统消息(设定角色)
Message systemMsg = new SystemMessage("你是一个 Java 技术专家");
// 多轮对话
List<Message> messages = List.of(
new SystemMessage("你是一个友好的助手"),
new UserMessage("你好"),
new AssistantMessage("你好!有什么可以帮助你的?"),
new UserMessage("介绍一下 Spring AI")
);
Prompt prompt = new Prompt(messages);
4.4 ChatResponse(响应)
响应结构:
ChatResponse
├── Result # 主要结果
│ ├── Output # 输出内容
│ │ └── Content # 文本内容
│ └── Metadata # 元数据
│ ├── FinishReason # 结束原因
│ └── ContentFilter # 内容过滤
└── Metadata # 响应元数据
├── Usage # Token 使用情况
│ ├── PromptTokens # 输入 Token 数
│ ├── GenerationTokens # 输出 Token 数
│ └── TotalTokens # 总 Token 数
└── RateLimit # 速率限制
获取响应内容:
ChatResponse response = chatClient.call(prompt);
// 获取回复文本
String content = response.getResult().getOutput().getContent();
// 获取 Token 使用情况
Usage usage = response.getMetadata().getUsage();
Long promptTokens = usage.getPromptTokens();
Long generationTokens = usage.getGenerationTokens();
Long totalTokens = usage.getTotalTokens();
// 获取结束原因
String finishReason = response.getResult().getMetadata().getFinishReason();
4.5 自动配置原理
Spring AI 的自动配置流程:
配置类示例:
// Spring AI 自动配置(无需手动编写)
@Configuration
@ConditionalOnClass(OpenAiApi.class)
@EnableConfigurationProperties(OpenAiChatProperties.class)
public class OpenAiAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public ChatClient chatClient(OpenAiChatProperties properties) {
return new OpenAiChatClient(
new OpenAiApi(properties.getApiKey()),
properties.getOptions()
);
}
}
五、实战应用场景
5.1 场景一:智能问答机器人
需求: 创建一个能回答技术问题的机器人
实现:
package com.example.springai.service;
import org.springframework.ai.chat.ChatClient;
import org.springframework.ai.chat.messages.SystemMessage;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 技术问答服务
*/
@Service
public class TechQAService {
private final ChatClient chatClient;
// 系统提示词:设定 AI 的角色和行为
private static final String SYSTEM_PROMPT = """
你是一个专业的 Java 技术专家,擅长 Spring 框架和微服务架构。
请用简洁、专业的语言回答技术问题。
如果问题超出你的知识范围,请诚实地说明。
""";
public TechQAService(ChatClient chatClient) {
this.chatClient = chatClient;
}
/**
* 回答技术问题
*
* @param question 技术问题
* @return 答案
*/
public String answerQuestion(String question) {
// 创建消息列表
List<org.springframework.ai.chat.messages.Message> messages = List.of(
new SystemMessage(SYSTEM_PROMPT),
new UserMessage(question)
);
// 创建 Prompt
Prompt prompt = new Prompt(messages);
// 调用 AI
return chatClient.call(prompt)
.getResult()
.getOutput()
.getContent();
}
}
控制器:
package com.example.springai.controller;
import com.example.springai.service.TechQAService;
import org.springframework.web.bind.annotation.*;
/**
* 技术问答控制器
*/
@RestController
@RequestMapping("/api/qa")
public class TechQAController {
private final TechQAService qaService;
public TechQAController(TechQAService qaService) {
this.qaService = qaService;
}
/**
* 提问接口
* POST /api/qa/ask
* Body: {"question": "什么是 Spring Boot?"}
*/
@PostMapping("/ask")
public String ask(@RequestBody QuestionRequest request) {
return qaService.answerQuestion(request.getQuestion());
}
// 请求对象
public record QuestionRequest(String question) {}
}
测试:
curl -X POST http://localhost:8080/api/qa/ask \
-H "Content-Type: application/json" \
-d '{"question": "什么是 Spring Boot 自动配置?"}'
5.2 场景二:文本摘要生成器
需求: 自动生成文章摘要
实现:
package com.example.springai.service;
import org.springframework.ai.chat.ChatClient;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.stereotype.Service;
/**
* 文本摘要服务
*/
@Service
public class SummaryService {
private final ChatClient chatClient;
public SummaryService(ChatClient chatClient) {
this.chatClient = chatClient;
}
/**
* 生成文本摘要
*
* @param text 原文
* @param maxWords 摘要最大字数
* @return 摘要
*/
public String generateSummary(String text, int maxWords) {
// 构建提示词
String promptText = String.format("""
请为以下文本生成一个不超过 %d 字的摘要。
要求:
1. 保留核心信息
2. 语言简洁明了
3. 不要添加原文没有的内容
原文:
%s
摘要:
""", maxWords, text);
// 创建 Prompt
Prompt prompt = new Prompt(new UserMessage(promptText));
// 调用 AI
return chatClient.call(prompt)
.getResult()
.getOutput()
.getContent();
}
/**
* 生成多语言摘要
*
* @param text 原文
* @param language 目标语言
* @return 摘要
*/
public String generateSummaryInLanguage(String text, String language) {
String promptText = String.format("""
请为以下文本生成一个 %s 语言的摘要,不超过 100 字。
原文:
%s
%s 摘要:
""", language, text, language);
Prompt prompt = new Prompt(new UserMessage(promptText));
return chatClient.call(prompt)
.getResult()
.getOutput()
.getContent();
}
}
控制器:
package com.example.springai.controller;
import com.example.springai.service.SummaryService;
import lombok.Data;
import org.springframework.web.bind.annotation.*;
/**
* 摘要生成控制器
*/
@RestController
@RequestMapping("/api/summary")
public class SummaryController {
private final SummaryService summaryService;
public SummaryController(SummaryService summaryService) {
this.summaryService = summaryService;
}
/**
* 生成摘要
* POST /api/summary/generate
*/
@PostMapping("/generate")
public SummaryResponse generate(@RequestBody SummaryRequest request) {
String summary = summaryService.generateSummary(
request.getText(),
request.getMaxWords()
);
return new SummaryResponse(summary);
}
/**
* 生成多语言摘要
* POST /api/summary/translate
*/
@PostMapping("/translate")
public SummaryResponse translateSummary(@RequestBody TranslateSummaryRequest request) {
String summary = summaryService.generateSummaryInLanguage(
request.getText(),
request.getLanguage()
);
return new SummaryResponse(summary);
}
@Data
public static class SummaryRequest {
private String text;
private int maxWords = 100;
}
@Data
public static class TranslateSummaryRequest {
private String text;
private String language = "English";
}
public record SummaryResponse(String summary) {}
}
测试:
# 生成中文摘要
curl -X POST http://localhost:8080/api/summary/generate \
-H "Content-Type: application/json" \
-d '{
"text": "Spring AI 是 Spring 生态系统中用于构建 AI 应用的框架...",
"maxWords": 50
}'
# 生成英文摘要
curl -X POST http://localhost:8080/api/summary/translate \
-H "Content-Type: application/json" \
-d '{
"text": "Spring AI 是 Spring 生态系统中用于构建 AI 应用的框架...",
"language": "English"
}'
5.3 场景三:代码解释器
需求: 解释代码的功能和原理
实现:
package com.example.springai.service;
import org.springframework.ai.chat.ChatClient;
import org.springframework.ai.chat.messages.SystemMessage;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 代码解释服务
*/
@Service
public class CodeExplainerService {
private final ChatClient chatClient;
private static final String SYSTEM_PROMPT = """
你是一个专业的代码解释器。
请用清晰、易懂的语言解释代码的功能和原理。
解释应该包括:
1. 代码的整体功能
2. 关键代码的作用
3. 使用的技术和模式
4. 可能的优化建议
""";
public CodeExplainerService(ChatClient chatClient) {
this.chatClient = chatClient;
}
/**
* 解释代码
*
* @param code 代码
* @param language 编程语言
* @return 解释
*/
public String explainCode(String code, String language) {
String userPrompt = String.format("""
请解释以下 %s 代码:
```%s
%s
```
""", language, language, code);
List<org.springframework.ai.chat.messages.Message> messages = List.of(
new SystemMessage(SYSTEM_PROMPT),
new UserMessage(userPrompt)
);
Prompt prompt = new Prompt(messages);
return chatClient.call(prompt)
.getResult()
.getOutput()
.getContent();
}
/**
* 代码审查
*
* @param code 代码
* @return 审查意见
*/
public String reviewCode(String code) {
String userPrompt = String.format("""
请审查以下代码,指出潜在的问题和改进建议:
```java
%s
```
请从以下方面进行审查:
1. 代码规范
2. 性能问题
3. 安全隐患
4. 可维护性
5. 最佳实践
""", code);
Prompt prompt = new Prompt(new UserMessage(userPrompt));
return chatClient.call(prompt)
.getResult()
.getOutput()
.getContent();
}
}
控制器:
package com.example.springai.controller;
import com.example.springai.service.CodeExplainerService;
import lombok.Data;
import org.springframework.web.bind.annotation.*;
/**
* 代码解释控制器
*/
@RestController
@RequestMapping("/api/code")
public class CodeExplainerController {
private final CodeExplainerService codeExplainerService;
public CodeExplainerController(CodeExplainerService codeExplainerService) {
this.codeExplainerService = codeExplainerService;
}
/**
* 解释代码
* POST /api/code/explain
*/
@PostMapping("/explain")
public ExplanationResponse explain(@RequestBody CodeRequest request) {
String explanation = codeExplainerService.explainCode(
request.getCode(),
request.getLanguage()
);
return new ExplanationResponse(explanation);
}
/**
* 审查代码
* POST /api/code/review
*/
@PostMapping("/review")
public ExplanationResponse review(@RequestBody ReviewRequest request) {
String review = codeExplainerService.reviewCode(request.getCode());
return new ExplanationResponse(review);
}
@Data
public static class CodeRequest {
private String code;
private String language = "Java";
}
@Data
public static class ReviewRequest {
private String code;
}
public record ExplanationResponse(String explanation) {}
}
测试:
# 解释代码
curl -X POST http://localhost:8080/api/code/explain \
-H "Content-Type: application/json" \
-d '{
"code": "@Service\npublic class UserService {\n @Autowired\n private UserRepository userRepository;\n}",
"language": "Java"
}'
# 审查代码
curl -X POST http://localhost:8080/api/code/review \
-H "Content-Type: application/json" \
-d '{
"code": "public String getUser(String id) {\n return userRepository.findById(id).get();\n}"
}'
六、Spring AI 学习路线
6.1 学习路径图
6.2 学习时间规划
| 阶段 | 内容 | 建议时间 | 学习目标 |
|---|---|---|---|
| 第一阶段 | 基础入门 | 1-2 天 | 能够创建简单的 AI 应用 |
| 第二阶段 | 模型集成 | 2-3 天 | 掌握多种模型的集成方法 |
| 第三阶段 | 核心功能 | 3-5 天 | 掌握对话、提示词、函数调用 |
| 第四阶段 | 高级特性 | 5-7 天 | 掌握 RAG、向量检索等高级功能 |
| 第五阶段 | 实战项目 | 7-10 天 | 完成完整的 AI 应用项目 |
| 第六阶段 | 生产部署 | 3-5 天 | 掌握生产环境部署和优化 |
总计: 约 3-4 周完成完整学习
6.3 学习建议
1. 循序渐进
- 不要跳过基础章节
- 每个知识点都要动手实践
- 理解原理比记忆 API 更重要
2. 项目驱动
- 边学边做项目
- 从简单项目开始
- 逐步增加复杂度
3. 多看源码
- 阅读 Spring AI 源码
- 理解自动配置原理
- 学习设计模式
4. 关注社区
- 关注 Spring AI 官方文档
- 参与 GitHub 讨论
- 学习优秀的开源项目
6.4 学习资源
官方资源:
推荐博客:
- Spring 官方博客
- Baeldung Spring AI 教程
- DZone Spring AI 文章
视频教程:
- Spring I/O 大会视频
- YouTube Spring AI 教程
- B站 Spring AI 中文教程
开源项目:
- spring-ai-examples
- awesome-spring-ai
- spring-ai-demos
七、最佳实践
7.1 配置管理
使用环境变量管理敏感信息:
# application.yml
spring:
ai:
openai:
api-key: ${OPENAI_API_KEY} # ✓ 使用环境变量
# api-key: sk-xxx # ✗ 不要硬编码
多环境配置:
# application-dev.yml(开发环境)
spring:
ai:
openai:
chat:
options:
model: gpt-3.5-turbo
temperature: 0.7
# application-prod.yml(生产环境)
spring:
ai:
openai:
chat:
options:
model: gpt-4
temperature: 0.5
7.2 异常处理
统一异常处理:
package com.example.springai.exception;
import org.springframework.ai.retry.RetryUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
/**
* 全局异常处理器
*/
@RestControllerAdvice
public class GlobalExceptionHandler {
/**
* 处理 AI 调用异常
*/
@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handleAIException(Exception e) {
// 记录日志
log.error("AI 调用失败", e);
// 返回友好的错误信息
ErrorResponse error = new ErrorResponse(
"AI_ERROR",
"AI 服务暂时不可用,请稍后重试",
System.currentTimeMillis()
);
return ResponseEntity
.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(error);
}
public record ErrorResponse(
String code,
String message,
Long timestamp
) {}
}
7.3 日志记录
添加详细的日志:
package com.example.springai.service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.ChatClient;
import org.springframework.ai.chat.ChatResponse;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.stereotype.Service;
/**
* 带日志的聊天服务
*/
@Slf4j
@Service
public class LoggingChatService {
private final ChatClient chatClient;
public LoggingChatService(ChatClient chatClient) {
this.chatClient = chatClient;
}
public String chat(String message) {
log.info("收到用户消息: {}", message);
long startTime = System.currentTimeMillis();
try {
Prompt prompt = new Prompt(message);
ChatResponse response = chatClient.call(prompt);
String reply = response.getResult().getOutput().getContent();
long duration = System.currentTimeMillis() - startTime;
// 记录 Token 使用情况
var usage = response.getMetadata().getUsage();
log.info("AI 响应成功 - 耗时: {}ms, Token: {}/{}/{}",
duration,
usage.getPromptTokens(),
usage.getGenerationTokens(),
usage.getTotalTokens()
);
return reply;
} catch (Exception e) {
long duration = System.currentTimeMillis() - startTime;
log.error("AI 调用失败 - 耗时: {}ms", duration, e);
throw e;
}
}
}
7.4 性能优化
使用缓存减少 API 调用:
package com.example.springai.service;
import org.springframework.ai.chat.ChatClient;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
/**
* 带缓存的聊天服务
*/
@Service
public class CachedChatService {
private final ChatClient chatClient;
public CachedChatService(ChatClient chatClient) {
this.chatClient = chatClient;
}
/**
* 缓存相同问题的答案
*
* @param message 用户消息
* @return AI 回复
*/
@Cacheable(value = "chatResponses", key = "#message")
public String chat(String message) {
return chatClient.call(message);
}
}
配置缓存:
package com.example.springai.config;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import java.time.Duration;
/**
* 缓存配置
*/
@Configuration
@EnableCaching
public class CacheConfig {
@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) {
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofHours(1)) // 缓存 1 小时
.disableCachingNullValues();
return RedisCacheManager.builder(connectionFactory)
.cacheDefaults(config)
.build();
}
}
7.5 成本控制
限制 Token 使用:
package com.example.springai.service;
import org.springframework.ai.chat.ChatClient;
import org.springframework.ai.openai.OpenAiChatOptions;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.stereotype.Service;
/**
* 成本控制服务
*/
@Service
public class CostControlService {
private final ChatClient chatClient;
public CostControlService(ChatClient chatClient) {
this.chatClient = chatClient;
}
/**
* 限制 Token 数量的对话
*
* @param message 用户消息
* @param maxTokens 最大 Token 数
* @return AI 回复
*/
public String chatWithLimit(String message, int maxTokens) {
// 设置 Token 限制
OpenAiChatOptions options = OpenAiChatOptions.builder()
.withMaxTokens(maxTokens)
.build();
Prompt prompt = new Prompt(message, options);
return chatClient.call(prompt)
.getResult()
.getOutput()
.getContent();
}
/**
* 使用更便宜的模型
*
* @param message 用户消息
* @return AI 回复
*/
public String chatWithCheapModel(String message) {
// 使用 gpt-3.5-turbo 而不是 gpt-4
OpenAiChatOptions options = OpenAiChatOptions.builder()
.withModel("gpt-3.5-turbo")
.build();
Prompt prompt = new Prompt(message, options);
return chatClient.call(prompt)
.getResult()
.getOutput()
.getContent();
}
}
八、常见问题
Q1: 如何获取 OpenAI API Key?
A:
- 访问 https://platform.openai.com/
- 注册并登录账号
- 进入 API Keys 页面
- 点击 “Create new secret key”
- 复制并保存 Key(只显示一次)
- 设置环境变量或配置文件
注意事项:
- API Key 只显示一次,请妥善保存
- 不要将 API Key 提交到代码仓库
- 定期更换 API Key
- 监控 API 使用量和费用
Q2: 为什么调用 AI 很慢?
A: 可能的原因和解决方案:
原因 1:网络问题
问题:国内访问 OpenAI API 可能较慢
解决:使用代理或选择国内的 AI 服务商
原因 2:模型选择
问题:gpt-4 比 gpt-3.5-turbo 慢
解决:根据需求选择合适的模型
原因 3:Token 数量过多
问题:生成的内容太长
解决:限制 max-tokens 参数
原因 4:没有使用缓存
问题:相同问题重复调用 API
解决:使用 Redis 缓存结果
Q3: 如何处理 API 调用失败?
A: 实现重试机制:
package com.example.springai.service;
import org.springframework.ai.chat.ChatClient;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;
/**
* 带重试的聊天服务
*/
@Service
public class RetryableChatService {
private final ChatClient chatClient;
public RetryableChatService(ChatClient chatClient) {
this.chatClient = chatClient;
}
/**
* 自动重试的对话方法
* 最多重试 3 次,每次间隔 2 秒
*/
@Retryable(
maxAttempts = 3,
backoff = @Backoff(delay = 2000)
)
public String chatWithRetry(String message) {
return chatClient.call(message);
}
}
启用重试:
package com.example.springai.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.retry.annotation.EnableRetry;
@Configuration
@EnableRetry
public class RetryConfig {
}
Q4: 如何切换到其他 AI 模型?
A: 只需修改依赖和配置:
切换到 Azure OpenAI:
<!-- 替换依赖 -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-azure-openai-spring-boot-starter</artifactId>
</dependency>
# 修改配置
spring:
ai:
azure:
openai:
api-key: ${AZURE_OPENAI_API_KEY}
endpoint: ${AZURE_OPENAI_ENDPOINT}
切换到 Ollama(本地模型):
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-ollama-spring-boot-starter</artifactId>
</dependency>
spring:
ai:
ollama:
base-url: http://localhost:11434
chat:
options:
model: llama2
代码无需修改!
Q5: 如何控制 AI 的回复风格?
A: 使用 System Message 和 Temperature 参数:
package com.example.springai.service;
import org.springframework.ai.chat.ChatClient;
import org.springframework.ai.chat.messages.SystemMessage;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.openai.OpenAiChatOptions;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 风格控制服务
*/
@Service
public class StyleControlService {
private final ChatClient chatClient;
public StyleControlService(ChatClient chatClient) {
this.chatClient = chatClient;
}
/**
* 专业风格回复
*/
public String professionalChat(String message) {
SystemMessage systemMsg = new SystemMessage(
"你是一个专业的技术顾问,回答要准确、简洁、专业。"
);
UserMessage userMsg = new UserMessage(message);
// 低 temperature = 更确定性的回复
OpenAiChatOptions options = OpenAiChatOptions.builder()
.withTemperature(0.3)
.build();
Prompt prompt = new Prompt(List.of(systemMsg, userMsg), options);
return chatClient.call(prompt)
.getResult()
.getOutput()
.getContent();
}
/**
* 创意风格回复
*/
public String creativeChat(String message) {
SystemMessage systemMsg = new SystemMessage(
"你是一个富有创意的助手,回答要生动、有趣、富有想象力。"
);
UserMessage userMsg = new UserMessage(message);
// 高 temperature = 更有创造性的回复
OpenAiChatOptions options = OpenAiChatOptions.builder()
.withTemperature(1.5)
.build();
Prompt prompt = new Prompt(List.of(systemMsg, userMsg), options);
return chatClient.call(prompt)
.getResult()
.getOutput()
.getContent();
}
}
Q6: 如何监控 API 使用情况?
A: 记录和统计 Token 使用:
package com.example.springai.service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.ChatClient;
import org.springframework.ai.chat.ChatResponse;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.stereotype.Service;
/**
* 使用监控服务
*/
@Slf4j
@Service
public class UsageMonitorService {
private final ChatClient chatClient;
// 统计信息
private long totalRequests = 0;
private long totalPromptTokens = 0;
private long totalGenerationTokens = 0;
private long totalTokens = 0;
public UsageMonitorService(ChatClient chatClient) {
this.chatClient = chatClient;
}
/**
* 带监控的对话
*/
public String chatWithMonitoring(String message) {
Prompt prompt = new Prompt(message);
ChatResponse response = chatClient.call(prompt);
// 更新统计信息
var usage = response.getMetadata().getUsage();
totalRequests++;
totalPromptTokens += usage.getPromptTokens();
totalGenerationTokens += usage.getGenerationTokens();
totalTokens += usage.getTotalTokens();
// 记录日志
log.info("API 调用统计 - 总请求: {}, 总 Token: {}",
totalRequests, totalTokens);
return response.getResult().getOutput().getContent();
}
/**
* 获取使用统计
*/
public UsageStats getUsageStats() {
return new UsageStats(
totalRequests,
totalPromptTokens,
totalGenerationTokens,
totalTokens
);
}
public record UsageStats(
long totalRequests,
long totalPromptTokens,
long totalGenerationTokens,
long totalTokens
) {}
}
九、练习题
基础练习
练习 1:创建简单的翻译服务
要求:
- 创建一个翻译服务,支持中英互译
- 提供 REST API 接口
- 返回翻译结果和耗时
提示:
@Service
public class TranslationService {
public String translate(String text, String targetLanguage) {
// TODO: 实现翻译逻辑
}
}
练习 2:实现情感分析服务
要求:
- 分析文本的情感倾向(正面/负面/中性)
- 返回情感分类和置信度
- 提供批量分析接口
提示:
public record SentimentResult(
String sentiment, // POSITIVE, NEGATIVE, NEUTRAL
double confidence
) {}
练习 3:创建关键词提取服务
要求:
- 从文本中提取关键词
- 支持指定提取数量
- 返回关键词和权重
进阶练习
练习 4:实现多轮对话
要求:
- 支持上下文记忆
- 每个用户独立的对话历史
- 提供清除历史的接口
提示:
@Service
public class ConversationService {
// 存储对话历史
private Map<String, List<Message>> conversationHistory = new ConcurrentHashMap<>();
public String chat(String userId, String message) {
// TODO: 实现多轮对话
}
}
练习 5:实现智能客服路由
要求:
- 根据用户问题类型自动路由
- 技术问题 → 技术客服
- 售后问题 → 售后客服
- 其他问题 → 通用客服
提示:
public enum QuestionType {
TECHNICAL, AFTER_SALES, GENERAL
}
public QuestionType classifyQuestion(String question) {
// TODO: 使用 AI 分类问题
}
练习 6:实现内容审核服务
要求:
- 检测文本中的敏感内容
- 返回审核结果和原因
- 支持自定义审核规则
综合练习
练习 7:构建完整的智能问答系统
要求:
- 用户管理(注册、登录)
- 问答功能(提问、回答)
- 历史记录(查看、删除)
- 统计分析(使用量、Token 消耗)
- 管理后台(用户管理、数据统计)
技术栈:
- Spring Boot 3.2+
- Spring AI
- MySQL(用户和历史数据)
- Redis(缓存和会话)
- Spring Security(认证授权)
项目结构:
intelligent-qa-system/
├── src/main/java/
│ ├── controller/
│ │ ├── AuthController.java
│ │ ├── QAController.java
│ │ └── AdminController.java
│ ├── service/
│ │ ├── UserService.java
│ │ ├── QAService.java
│ │ └── StatisticsService.java
│ ├── repository/
│ │ ├── UserRepository.java
│ │ └── QAHistoryRepository.java
│ ├── entity/
│ │ ├── User.java
│ │ └── QAHistory.java
│ └── config/
│ ├── SecurityConfig.java
│ └── AIConfig.java
└── src/main/resources/
├── application.yml
└── schema.sql
十、学习检查清单
完成以下检查项,确保你已经掌握了 Spring AI 快速开始的内容:
基础知识
- 理解 Spring AI 的核心价值和应用场景
- 了解 Spring AI 的设计理念和核心组件
- 掌握 Spring AI 与传统 AI API 调用的区别
- 理解 Spring AI 的自动配置原理
环境搭建
- 能够创建 Spring Boot 项目
- 能够正确添加 Spring AI 依赖
- 能够配置 API Key 和模型参数
- 能够成功启动 Spring AI 应用
核心概念
- 理解 ChatClient 的作用和使用方法
- 掌握 Prompt 的创建和配置
- 了解 Message 的类型和用途
- 能够解析 ChatResponse 获取所需信息
代码实践
- 能够编写简单的对话服务
- 能够创建 REST API 接口
- 能够处理用户请求和 AI 响应
- 能够添加日志和异常处理
实战应用
- 完成至少 1 个实战案例
- 能够根据需求设计 AI 应用
- 能够优化 Prompt 提高回复质量
- 能够测试和调试 AI 应用
最佳实践
- 掌握配置管理的最佳实践
- 了解异常处理和重试机制
- 能够添加缓存优化性能
- 了解成本控制的方法
问题解决
- 能够解决常见的配置问题
- 能够处理 API 调用失败
- 能够优化响应速度
- 能够监控 API 使用情况
十一、下一步学习
完成快速开始后,建议按以下顺序继续学习:
1. Spring AI 概述与核心概念
- 深入理解 Spring AI 架构
- 学习核心接口和抽象
- 掌握设计模式和最佳实践
2. 环境搭建与第一个 AI 应用
- 详细的环境配置
- 完整的项目开发流程
- 生产环境部署指南
3. 模型集成
- OpenAI 模型集成
- Azure OpenAI 集成
- Ollama 本地模型集成
- 模型切换和配置管理
4. 核心功能
- Chat Client 深入使用
- Prompt Engineering 技巧
- Function Calling 实战
- 流式响应处理
5. 高级特性
- Embedding 和向量化
- 向量数据库集成
- RAG 应用开发
- 异步处理和缓存
6. 实战项目
- 智能客服系统
- 文档问答系统
- AI 代码助手
- 内容生成系统
十二、扩展阅读
官方文档
技术博客
视频教程
开源项目
相关技术
总结
恭喜你完成了 Spring AI 快速开始的学习!
你现在已经:
- ✅ 了解了 Spring AI 的核心价值
- ✅ 掌握了快速创建 AI 应用的方法
- ✅ 理解了 Spring AI 的核心概念
- ✅ 完成了多个实战案例
- ✅ 学习了最佳实践和常见问题
下一步:
继续学习 Spring AI 的深入内容,完成更多实战项目,成为 AI 应用开发专家!
记住:
- 实践是最好的学习方法
- 不要害怕犯错,从错误中学习
- 保持好奇心,持续探索新技术
- 分享你的学习成果,帮助他人
祝你学习愉快!🎉
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)