03-OpenAI模型集成
03-OpenAI模型集成
学习目标
- 掌握 Spring AI 集成 OpenAI 的完整流程
- 理解 OpenAI API 的配置和使用方法
- 能够在实际项目中集成 OpenAI 模型
- 掌握 OpenAI 不同模型的选择和优化策略
- 了解 OpenAI API 的成本控制和最佳实践
知识结构
一、项目场景引入
1.1 实际项目需求
在现代企业应用中,AI 能力已经成为提升用户体验和业务效率的关键因素。以下是几个典型的业务场景:
场景一:智能客服系统
一家电商公司需要构建智能客服系统,要求:
- 7x24小时在线服务
- 理解用户问题并提供准确答案
- 支持订单查询、退换货咨询等业务
- 能够处理复杂的多轮对话
场景二:内容生成平台
内容创作平台需要AI辅助功能:
- 自动生成商品描述
- 撰写营销文案
- 优化SEO标题
- 生成社交媒体内容
场景三:代码助手
开发团队需要提升编码效率:
- 代码自动补全
- Bug分析和修复建议
- 代码审查和优化建议
- 技术文档生成
1.2 为什么选择 OpenAI
OpenAI 提供了业界领先的大语言模型,具有以下优势:
- 强大的理解能力:GPT-4 能够理解复杂的上下文和意图
- 高质量输出:生成的内容自然流畅,符合人类表达习惯
- 丰富的API功能:支持对话、补全、嵌入等多种能力
- 持续更新:模型不断优化,性能持续提升
- 完善的文档:官方提供详细的API文档和最佳实践
1.3 技术挑战
在集成 OpenAI 时,我们需要解决以下问题:
挑战一:API密钥管理
- 如何安全地存储和使用API密钥?
- 如何在不同环境中管理不同的密钥?
挑战二:成本控制
- OpenAI按Token计费,如何控制成本?
- 如何选择合适的模型平衡性能和成本?
挑战三:性能优化
- API调用延迟如何优化?
- 如何处理高并发请求?
挑战四:错误处理
- API调用失败如何处理?
- 如何实现重试机制?
二、OpenAI API 基础
2.1 OpenAI API 概述
OpenAI API 是一个基于 REST 的 HTTP API,提供了访问 GPT 系列模型的能力。
核心概念:
用户请求 → Spring AI → OpenAI API → GPT模型 → 返回响应
↓ ↓ ↓ ↓ ↓
输入文本 封装请求 HTTP调用 模型推理 生成文本
主要端点:
| 端点 | 功能 | 说明 |
|---|---|---|
| /v1/chat/completions | 对话补全 | 用于聊天和对话场景 |
| /v1/completions | 文本补全 | 用于文本生成场景 |
| /v1/embeddings | 文本嵌入 | 用于语义搜索和相似度计算 |
| /v1/models | 模型列表 | 查询可用的模型 |
2.2 获取 OpenAI API 密钥
步骤一:注册 OpenAI 账号
- 访问 https://platform.openai.com/
- 点击 “Sign up” 注册账号
- 验证邮箱并完成注册
步骤二:创建 API 密钥
- 登录后访问 https://platform.openai.com/api-keys
- 点击 “Create new secret key”
- 为密钥命名(如:spring-ai-dev)
- 复制并安全保存密钥(只显示一次)
步骤三:充值账户
- 访问 https://platform.openai.com/account/billing
- 添加支付方式
- 充值账户余额(建议先充值少量测试)
重要提示:
⚠️ API密钥安全注意事项:
1. 不要将密钥提交到代码仓库
2. 不要在前端代码中暴露密钥
3. 使用环境变量或配置中心管理密钥
4. 定期轮换密钥
5. 为不同环境使用不同的密钥
2.3 OpenAI 模型对比
OpenAI 提供了多个模型,各有特点:
| 模型 | 上下文长度 | 训练数据截止 | 特点 | 适用场景 | 成本 |
|---|---|---|---|---|---|
| GPT-4 | 8K/32K | 2023-04 | 最强理解和生成能力 | 复杂任务、代码生成 | 高 |
| GPT-4-turbo | 128K | 2023-12 | 更长上下文、更快速度 | 长文档处理 | 中高 |
| GPT-3.5-turbo | 16K | 2021-09 | 性价比高、速度快 | 一般对话、简单任务 | 低 |
| GPT-3.5-turbo-16k | 16K | 2021-09 | 更长上下文 | 中等长度文档 | 中低 |
选择建议:
开发测试阶段:
├─ 使用 GPT-3.5-turbo(成本低、速度快)
└─ 验证基本功能和流程
生产环境:
├─ 简单任务:GPT-3.5-turbo(客服FAQ、简单对话)
├─ 复杂任务:GPT-4(代码生成、复杂推理)
└─ 长文档处理:GPT-4-turbo(文档分析、长对话)
三、Spring AI 集成 OpenAI
3.1 项目依赖配置
完整的 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
http://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-openai-demo</artifactId>
<version>1.0.0</version>
<name>Spring AI OpenAI Integration Demo</name>
<description>Spring AI OpenAI 集成示例项目</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.2 配置文件设置
application.yml 完整配置:
spring:
application:
name: spring-ai-openai-demo
# Spring AI OpenAI 配置
ai:
openai:
# API 密钥(从环境变量读取,不要硬编码)
api-key: ${OPENAI_API_KEY}
# API 基础URL(可选,默认为 https://api.openai.com)
base-url: https://api.openai.com
# Chat 模型配置
chat:
options:
# 模型名称
model: gpt-3.5-turbo
# 温度参数(0-2,越高越随机)
temperature: 0.7
# 最大生成token数
max-tokens: 1000
# Top P 采样参数
top-p: 1.0
# 频率惩罚(-2.0 到 2.0)
frequency-penalty: 0.0
# 存在惩罚(-2.0 到 2.0)
presence-penalty: 0.0
# Embedding 模型配置
embedding:
options:
model: text-embedding-ada-002
# 服务器配置
server:
port: 8080
# 日志配置
logging:
level:
root: INFO
com.example: DEBUG
org.springframework.ai: DEBUG
环境变量配置(.env 文件):
# OpenAI API 密钥
OPENAI_API_KEY=sk-your-api-key-here
# 可选:自定义 API 基础URL(用于代理)
# OPENAI_API_BASE_URL=https://your-proxy.com/v1
为什么使用环境变量?
安全性考虑:
├─ 不将密钥提交到代码仓库
├─ 不同环境使用不同密钥
├─ 便于密钥轮换
└─ 符合安全最佳实践
配置方式:
├─ 开发环境:.env 文件或 IDE 环境变量
├─ 测试环境:CI/CD 系统环境变量
└─ 生产环境:配置中心或 K8s Secret
3.3 基础集成代码
项目结构:
spring-ai-openai-demo/
├── src/main/java/com/example/springai/
│ ├── SpringAiOpenaiDemoApplication.java # 启动类
│ ├── controller/
│ │ └── ChatController.java # 控制器
│ ├── service/
│ │ ├── ChatService.java # 服务接口
│ │ └── impl/
│ │ └── ChatServiceImpl.java # 服务实现
│ ├── config/
│ │ └── OpenAIConfig.java # 配置类
│ └── dto/
│ ├── ChatRequest.java # 请求DTO
│ └── ChatResponse.java # 响应DTO
├── src/main/resources/
│ ├── application.yml # 配置文件
│ └── logback-spring.xml # 日志配置
└── pom.xml # Maven配置
1. 启动类:
package com.example.springai;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* Spring AI OpenAI 集成示例应用
*
* @author Your Name
* @since 1.0.0
*/
@SpringBootApplication
public class SpringAiOpenaiDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SpringAiOpenaiDemoApplication.class, args);
}
}
2. 数据传输对象(DTO):
package com.example.springai.dto;
import lombok.Data;
/**
* 聊天请求DTO
*/
@Data
public class ChatRequest {
/**
* 用户消息
*/
private String message;
/**
* 模型名称(可选)
*/
private String model;
/**
* 温度参数(可选,0-2)
*/
private Double temperature;
/**
* 最大token数(可选)
*/
private Integer maxTokens;
}
package com.example.springai.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 聊天响应DTO
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ChatResponse {
/**
* AI 回复内容
*/
private String content;
/**
* 使用的模型
*/
private String model;
/**
* 消耗的 token 数
*/
private Integer totalTokens;
/**
* 响应时间(毫秒)
*/
private Long responseTime;
/**
* 是否成功
*/
private Boolean success;
/**
* 错误信息(如果有)
*/
private String errorMessage;
}
3. 服务接口:
package com.example.springai.service;
import com.example.springai.dto.ChatRequest;
import com.example.springai.dto.ChatResponse;
/**
* 聊天服务接口
*
* @author Your Name
* @since 1.0.0
*/
public interface ChatService {
/**
* 简单对话
*
* @param message 用户消息
* @return AI 回复
*/
String simpleChat(String message);
/**
* 高级对话(支持参数配置)
*
* @param request 聊天请求
* @return 聊天响应
*/
ChatResponse advancedChat(ChatRequest request);
/**
* 流式对话
*
* @param message 用户消息
* @return 流式响应
*/
reactor.core.publisher.Flux<String> streamChat(String message);
}
4. 服务实现类:
package com.example.springai.service.impl;
import com.example.springai.dto.ChatRequest;
import com.example.springai.dto.ChatResponse;
import com.example.springai.service.ChatService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.ChatClient;
import org.springframework.ai.chat.ChatResponse as AiChatResponse;
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.OpenAiChatOptions;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;
/**
* 聊天服务实现类
* 项目场景:智能客服系统
* 功能:处理用户咨询,提供智能回复
*
* @author Your Name
* @since 1.0.0
*/
@Slf4j
@Service
public class ChatServiceImpl implements ChatService {
private final ChatClient chatClient;
/**
* 构造函数注入 ChatClient
* Spring AI 会自动配置并注入 ChatClient Bean
*/
public ChatServiceImpl(ChatClient chatClient) {
this.chatClient = chatClient;
log.info("ChatService 初始化完成");
}
/**
* 简单对话实现
* 适用场景:快速问答、简单咨询
*
* @param message 用户消息
* @return AI 回复
*/
@Override
public String simpleChat(String message) {
log.info("收到简单对话请求: {}", message);
try {
// 1. 创建用户消息
Message userMessage = new UserMessage(message);
// 2. 创建提示词
Prompt prompt = new Prompt(userMessage);
// 3. 调用 OpenAI API
AiChatResponse response = chatClient.call(prompt);
// 4. 提取回复内容
String content = response.getResult().getOutput().getContent();
log.info("AI 回复: {}", content);
return content;
} catch (Exception e) {
log.error("简单对话失败", e);
return "抱歉,我现在无法回答您的问题,请稍后再试。";
}
}
/**
* 高级对话实现
* 适用场景:需要自定义参数的复杂对话
*
* @param request 聊天请求
* @return 聊天响应
*/
@Override
public ChatResponse advancedChat(ChatRequest request) {
log.info("收到高级对话请求: {}", request);
long startTime = System.currentTimeMillis();
try {
// 1. 构建 OpenAI 选项
OpenAiChatOptions.Builder optionsBuilder = OpenAiChatOptions.builder();
// 设置模型(如果指定)
if (request.getModel() != null) {
optionsBuilder.withModel(request.getModel());
}
// 设置温度参数(如果指定)
if (request.getTemperature() != null) {
optionsBuilder.withTemperature(request.getTemperature());
}
// 设置最大token数(如果指定)
if (request.getMaxTokens() != null) {
optionsBuilder.withMaxTokens(request.getMaxTokens());
}
OpenAiChatOptions options = optionsBuilder.build();
// 2. 创建提示词
Message userMessage = new UserMessage(request.getMessage());
Prompt prompt = new Prompt(userMessage, options);
// 3. 调用 OpenAI API
AiChatResponse aiResponse = chatClient.call(prompt);
// 4. 计算响应时间
long responseTime = System.currentTimeMillis() - startTime;
// 5. 构建响应对象
ChatResponse response = ChatResponse.builder()
.content(aiResponse.getResult().getOutput().getContent())
.model(aiResponse.getMetadata().getModel())
.totalTokens(aiResponse.getMetadata().getUsage().getTotalTokens())
.responseTime(responseTime)
.success(true)
.build();
log.info("高级对话成功,耗时: {}ms, tokens: {}",
responseTime, response.getTotalTokens());
return response;
} catch (Exception e) {
log.error("高级对话失败", e);
long responseTime = System.currentTimeMillis() - startTime;
return ChatResponse.builder()
.success(false)
.errorMessage(e.getMessage())
.responseTime(responseTime)
.build();
}
}
/**
* 流式对话实现
* 适用场景:需要实时显示生成过程的场景
*
* @param message 用户消息
* @return 流式响应
*/
@Override
public Flux<String> streamChat(String message) {
log.info("收到流式对话请求: {}", message);
try {
// 1. 创建提示词
Prompt prompt = new Prompt(new UserMessage(message));
// 2. 调用流式API
Flux<AiChatResponse> responseFlux = chatClient.stream(prompt);
// 3. 提取内容流
return responseFlux
.map(response -> response.getResult().getOutput().getContent())
.doOnNext(content -> log.debug("流式内容: {}", content))
.doOnComplete(() -> log.info("流式对话完成"))
.doOnError(error -> log.error("流式对话失败", error));
} catch (Exception e) {
log.error("流式对话启动失败", e);
return Flux.error(e);
}
}
}
5. 控制器:
package com.example.springai.controller;
import com.example.springai.dto.ChatRequest;
import com.example.springai.dto.ChatResponse;
import com.example.springai.service.ChatService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
/**
* 聊天控制器
* 提供 RESTful API 接口
*
* @author Your Name
* @since 1.0.0
*/
@Slf4j
@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) {
log.info("简单对话请求: {}", message);
return chatService.simpleChat(message);
}
/**
* 高级对话接口
*
* POST /api/chat/advanced
* Content-Type: application/json
*
* {
* "message": "解释一下什么是Spring AI",
* "model": "gpt-4",
* "temperature": 0.7,
* "maxTokens": 1000
* }
*
* @param request 聊天请求
* @return 聊天响应
*/
@PostMapping("/advanced")
public ChatResponse advancedChat(@RequestBody ChatRequest request) {
log.info("高级对话请求: {}", request);
return chatService.advancedChat(request);
}
/**
* 流式对话接口
*
* GET /api/chat/stream?message=讲个故事
*
* @param message 用户消息
* @return 流式响应
*/
@GetMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> streamChat(@RequestParam String message) {
log.info("流式对话请求: {}", message);
return chatService.streamChat(message);
}
/**
* 健康检查接口
*
* GET /api/chat/health
*
* @return 健康状态
*/
@GetMapping("/health")
public String health() {
return "OK";
}
}
3.4 测试集成
启动应用并测试:
# 1. 设置环境变量
export OPENAI_API_KEY=sk-your-api-key-here
# 2. 启动应用
mvn spring-boot:run
# 3. 测试简单对话
curl "http://localhost:8080/api/chat/simple?message=你好"
# 4. 测试高级对话
curl -X POST http://localhost:8080/api/chat/advanced \
-H "Content-Type: application/json" \
-d '{
"message": "解释一下什么是Spring AI",
"model": "gpt-3.5-turbo",
"temperature": 0.7,
"maxTokens": 500
}'
# 5. 测试流式对话
curl "http://localhost:8080/api/chat/stream?message=讲个短故事"
预期输出:
# 简单对话响应
你好!我是AI助手,很高兴为您服务。有什么我可以帮助您的吗?
# 高级对话响应
{
"content": "Spring AI 是 Spring 生态系统中的一个新框架...",
"model": "gpt-3.5-turbo",
"totalTokens": 245,
"responseTime": 1523,
"success": true,
"errorMessage": null
}
# 流式对话响应(逐字输出)
从前
有一个
小村庄
...
四、实战应用场景
4.1 场景一:智能客服系统
业务需求:
构建一个电商平台的智能客服系统,能够:
- 回答常见问题(订单查询、退换货政策等)
- 理解用户意图并提供准确答案
- 支持多轮对话
- 记录对话历史
完整实现代码:
package com.example.springai.service.impl;
import com.example.springai.dto.ChatMessage;
import com.example.springai.dto.CustomerServiceRequest;
import com.example.springai.dto.CustomerServiceResponse;
import lombok.extern.slf4j.Slf4j;
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.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.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* 智能客服服务
* 项目场景:电商平台客服系统
* 功能:处理用户咨询、订单查询、退换货等业务
*
* @author Your Name
* @since 1.0.0
*/
@Slf4j
@Service
public class CustomerServiceImpl {
private final ChatClient chatClient;
// 存储用户对话历史(实际项目中应使用 Redis 或数据库)
private final Map<String, List<ChatMessage>> conversationHistory =
new ConcurrentHashMap<>();
public CustomerServiceImpl(ChatClient chatClient) {
this.chatClient = chatClient;
}
/**
* 处理客服咨询
*
* @param request 客服请求
* @return 客服响应
*/
public CustomerServiceResponse handleCustomerQuery(CustomerServiceRequest request) {
log.info("处理客服咨询 - 用户ID: {}, 消息: {}",
request.getUserId(), request.getMessage());
try {
// 1. 获取或创建对话历史
List<ChatMessage> history = conversationHistory.computeIfAbsent(
request.getUserId(), k -> new ArrayList<>());
// 2. 构建系统提示词(定义客服角色和规则)
String systemPrompt = buildSystemPrompt();
// 3. 构建完整的对话上下文
List<Message> messages = new ArrayList<>();
messages.add(new SystemMessage(systemPrompt));
// 添加历史对话(最近5轮)
int historySize = Math.min(history.size(), 5);
for (int i = history.size() - historySize; i < history.size(); i++) {
ChatMessage msg = history.get(i);
if ("user".equals(msg.getRole())) {
messages.add(new UserMessage(msg.getContent()));
} else {
messages.add(new SystemMessage(msg.getContent()));
}
}
// 添加当前用户消息
messages.add(new UserMessage(request.getMessage()));
// 4. 配置 OpenAI 选项
OpenAiChatOptions options = OpenAiChatOptions.builder()
.withModel("gpt-3.5-turbo")
.withTemperature(0.7)
.withMaxTokens(500)
.build();
// 5. 调用 OpenAI API
Prompt prompt = new Prompt(messages, options);
ChatResponse response = chatClient.call(prompt);
String aiReply = response.getResult().getOutput().getContent();
// 6. 保存对话历史
history.add(new ChatMessage("user", request.getMessage()));
history.add(new ChatMessage("assistant", aiReply));
// 7. 构建响应
return CustomerServiceResponse.builder()
.userId(request.getUserId())
.reply(aiReply)
.conversationId(request.getUserId())
.timestamp(System.currentTimeMillis())
.success(true)
.build();
} catch (Exception e) {
log.error("处理客服咨询失败", e);
return CustomerServiceResponse.builder()
.userId(request.getUserId())
.reply("抱歉,系统繁忙,请稍后再试。")
.success(false)
.errorMessage(e.getMessage())
.build();
}
}
/**
* 构建系统提示词
* 定义客服的角色、能力和规则
*/
private String buildSystemPrompt() {
return """
你是一个专业的电商平台客服助手,名字叫"小智"。
你的职责:
1. 友好、耐心地回答用户问题
2. 提供准确的订单、物流、退换货信息
3. 解决用户的疑问和投诉
4. 引导用户完成购物流程
回答规则:
1. 使用礼貌、专业的语言
2. 回答要简洁明了,不超过200字
3. 如果不确定答案,建议用户联系人工客服
4. 对于订单查询,提示用户提供订单号
5. 对于退换货,说明需要在7天内申请
常见问题参考:
- 订单查询:需要订单号,可在"我的订单"中查看
- 物流查询:订单发货后可在订单详情查看物流信息
- 退换货:7天无理由退换货,商品需保持完好
- 支付问题:支持支付宝、微信、银行卡支付
- 优惠券:在结算时自动抵扣,注意使用期限
""";
}
/**
* 清除用户对话历史
*
* @param userId 用户ID
*/
public void clearConversationHistory(String userId) {
conversationHistory.remove(userId);
log.info("清除用户对话历史: {}", userId);
}
}
DTO 定义:
package com.example.springai.dto;
import lombok.Data;
/**
* 客服请求DTO
*/
@Data
public class CustomerServiceRequest {
private String userId;
private String message;
private String sessionId;
}
/**
* 客服响应DTO
*/
@Data
@Builder
public class CustomerServiceResponse {
private String userId;
private String reply;
private String conversationId;
private Long timestamp;
private Boolean success;
private String errorMessage;
}
/**
* 对话消息DTO
*/
@Data
@AllArgsConstructor
public class ChatMessage {
private String role; // user 或 assistant
private String content;
}
控制器:
package com.example.springai.controller;
import com.example.springai.dto.CustomerServiceRequest;
import com.example.springai.dto.CustomerServiceResponse;
import com.example.springai.service.impl.CustomerServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
/**
* 客服控制器
*/
@Slf4j
@RestController
@RequestMapping("/api/customer-service")
public class CustomerServiceController {
private final CustomerServiceImpl customerService;
public CustomerServiceController(CustomerServiceImpl customerService) {
this.customerService = customerService;
}
@PostMapping("/query")
public CustomerServiceResponse handleQuery(
@RequestBody CustomerServiceRequest request) {
return customerService.handleCustomerQuery(request);
}
@DeleteMapping("/history/{userId}")
public void clearHistory(@PathVariable String userId) {
customerService.clearConversationHistory(userId);
}
}
测试示例:
# 第一轮对话
curl -X POST http://localhost:8080/api/customer-service/query \
-H "Content-Type: application/json" \
-d '{
"userId": "user123",
"message": "我想查询订单"
}'
# 响应
{
"userId": "user123",
"reply": "您好!我可以帮您查询订单。请提供您的订单号,订单号可以在"我的订单"页面找到,格式类似:202401010001。",
"conversationId": "user123",
"timestamp": 1704067200000,
"success": true
}
# 第二轮对话(带上下文)
curl -X POST http://localhost:8080/api/customer-service/query \
-H "Content-Type: application/json" \
-d '{
"userId": "user123",
"message": "订单号是202401010001"
}'
# 响应
{
"userId": "user123",
"reply": "好的,我帮您查询订单202401010001。根据系统显示,您的订单已发货,预计3-5天送达。您可以在订单详情页面查看实时物流信息。",
"conversationId": "user123",
"timestamp": 1704067260000,
"success": true
}
4.2 场景二:内容生成系统
业务需求:
为内容创作平台提供AI辅助功能:
- 生成商品描述
- 撰写营销文案
- 优化SEO标题
- 生成社交媒体内容
完整实现代码:
package com.example.springai.service.impl;
import com.example.springai.dto.ContentGenerationRequest;
import com.example.springai.dto.ContentGenerationResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.ChatClient;
import org.springframework.ai.chat.ChatResponse;
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;
/**
* 内容生成服务
* 项目场景:内容创作平台
* 功能:AI辅助内容生成
*
* @author Your Name
* @since 1.0.0
*/
@Slf4j
@Service
public class ContentGenerationService {
private final ChatClient chatClient;
public ContentGenerationService(ChatClient chatClient) {
this.chatClient = chatClient;
}
/**
* 生成商品描述
*
* @param request 内容生成请求
* @return 生成的内容
*/
public ContentGenerationResponse generateProductDescription(
ContentGenerationRequest request) {
log.info("生成商品描述: {}", request.getProductName());
try {
// 1. 构建系统提示词
String systemPrompt = """
你是一个专业的电商文案撰写专家。
你的任务是根据商品信息生成吸引人的商品描述。
要求:
1. 突出商品的核心卖点和优势
2. 使用生动、具体的语言描述
3. 包含使用场景和用户收益
4. 字数控制在200-300字
5. 语言要专业但易懂
""";
// 2. 构建用户提示词
String userPrompt = String.format("""
请为以下商品生成描述:
商品名称:%s
商品类别:%s
主要特点:%s
目标用户:%s
价格区间:%s
请生成一段吸引人的商品描述。
""",
request.getProductName(),
request.getCategory(),
String.join("、", request.getFeatures()),
request.getTargetAudience(),
request.getPriceRange());
// 3. 配置选项
OpenAiChatOptions options = OpenAiChatOptions.builder()
.withModel("gpt-3.5-turbo")
.withTemperature(0.8) // 较高的创造性
.withMaxTokens(500)
.build();
// 4. 调用 API
Prompt prompt = new Prompt(
List.of(new SystemMessage(systemPrompt),
new UserMessage(userPrompt)),
options);
ChatResponse response = chatClient.call(prompt);
String content = response.getResult().getOutput().getContent();
// 5. 构建响应
return ContentGenerationResponse.builder()
.content(content)
.contentType("product_description")
.wordCount(content.length())
.success(true)
.build();
} catch (Exception e) {
log.error("生成商品描述失败", e);
return ContentGenerationResponse.builder()
.success(false)
.errorMessage(e.getMessage())
.build();
}
}
/**
* 生成营销文案
*
* @param request 内容生成请求
* @return 生成的文案
*/
public ContentGenerationResponse generateMarketingCopy(
ContentGenerationRequest request) {
log.info("生成营销文案: {}", request.getCampaignName());
try {
String systemPrompt = """
你是一个资深的营销文案策划师。
你擅长创作有感染力、能激发购买欲望的营销文案。
要求:
1. 标题要吸引眼球,激发好奇心
2. 正文要突出产品价值和用户收益
3. 使用情感化的语言建立连接
4. 包含明确的行动号召(CTA)
5. 整体字数控制在150-200字
""";
String userPrompt = String.format("""
请为以下营销活动创作文案:
活动名称:%s
活动主题:%s
目标用户:%s
核心卖点:%s
优惠信息:%s
请生成包含标题和正文的营销文案。
""",
request.getCampaignName(),
request.getTheme(),
request.getTargetAudience(),
String.join("、", request.getSellingPoints()),
request.getPromotion());
OpenAiChatOptions options = OpenAiChatOptions.builder()
.withModel("gpt-3.5-turbo")
.withTemperature(0.9) // 更高的创造性
.withMaxTokens(400)
.build();
Prompt prompt = new Prompt(
List.of(new SystemMessage(systemPrompt),
new UserMessage(userPrompt)),
options);
ChatResponse response = chatClient.call(prompt);
String content = response.getResult().getOutput().getContent();
return ContentGenerationResponse.builder()
.content(content)
.contentType("marketing_copy")
.wordCount(content.length())
.success(true)
.build();
} catch (Exception e) {
log.error("生成营销文案失败", e);
return ContentGenerationResponse.builder()
.success(false)
.errorMessage(e.getMessage())
.build();
}
}
/**
* 优化SEO标题
*
* @param originalTitle 原始标题
* @param keywords 关键词列表
* @return 优化后的标题
*/
public List<String> optimizeSeoTitle(String originalTitle, List<String> keywords) {
log.info("优化SEO标题: {}", originalTitle);
try {
String systemPrompt = """
你是一个SEO优化专家。
你的任务是优化标题,提高搜索引擎排名和点击率。
要求:
1. 自然融入关键词
2. 标题长度控制在30-60字符
3. 吸引用户点击
4. 准确描述内容
5. 生成3个不同风格的标题供选择
""";
String userPrompt = String.format("""
原始标题:%s
目标关键词:%s
请生成3个优化后的SEO标题,每个标题单独一行。
""",
originalTitle,
String.join("、", keywords));
OpenAiChatOptions options = OpenAiChatOptions.builder()
.withModel("gpt-3.5-turbo")
.withTemperature(0.7)
.withMaxTokens(300)
.build();
Prompt prompt = new Prompt(
List.of(new SystemMessage(systemPrompt),
new UserMessage(userPrompt)),
options);
ChatResponse response = chatClient.call(prompt);
String content = response.getResult().getOutput().getContent();
// 分割成多个标题
return List.of(content.split("\n"))
.stream()
.map(String::trim)
.filter(s -> !s.isEmpty())
.toList();
} catch (Exception e) {
log.error("优化SEO标题失败", e);
return List.of(originalTitle);
}
}
}
DTO 定义:
package com.example.springai.dto;
import lombok.Data;
import lombok.Builder;
import java.util.List;
/**
* 内容生成请求DTO
*/
@Data
public class ContentGenerationRequest {
// 商品描述相关
private String productName;
private String category;
private List<String> features;
private String targetAudience;
private String priceRange;
// 营销文案相关
private String campaignName;
private String theme;
private List<String> sellingPoints;
private String promotion;
}
/**
* 内容生成响应DTO
*/
@Data
@Builder
public class ContentGenerationResponse {
private String content;
private String contentType;
private Integer wordCount;
private Boolean success;
private String errorMessage;
}
测试示例:
# 生成商品描述
curl -X POST http://localhost:8080/api/content/product-description \
-H "Content-Type: application/json" \
-d '{
"productName": "智能运动手表",
"category": "智能穿戴",
"features": ["心率监测", "GPS定位", "50米防水", "7天续航"],
"targetAudience": "运动爱好者",
"priceRange": "1000-2000元"
}'
# 响应示例
{
"content": "这款智能运动手表是运动爱好者的理想伴侣。配备专业级心率监测功能,实时追踪您的运动状态...",
"contentType": "product_description",
"wordCount": 256,
"success": true
}
4.3 场景三:代码助手
业务需求:
为开发团队提供AI代码助手:
- 代码审查和优化建议
- Bug分析和修复建议
- 代码注释生成
- 单元测试生成
完整实现代码:
package com.example.springai.service.impl;
import com.example.springai.dto.CodeReviewRequest;
import com.example.springai.dto.CodeReviewResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.ChatClient;
import org.springframework.ai.chat.ChatResponse;
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;
/**
* 代码助手服务
* 项目场景:开发团队协作平台
* 功能:代码审查、优化建议、Bug分析
*
* @author Your Name
* @since 1.0.0
*/
@Slf4j
@Service
public class CodeAssistantService {
private final ChatClient chatClient;
public CodeAssistantService(ChatClient chatClient) {
this.chatClient = chatClient;
}
/**
* 代码审查
*
* @param request 代码审查请求
* @return 审查结果
*/
public CodeReviewResponse reviewCode(CodeReviewRequest request) {
log.info("开始代码审查 - 语言: {}", request.getLanguage());
try {
// 1. 构建系统提示词
String systemPrompt = """
你是一个资深的代码审查专家,精通多种编程语言和最佳实践。
审查重点:
1. 代码质量:可读性、可维护性、复杂度
2. 性能问题:算法效率、资源使用
3. 安全隐患:SQL注入、XSS、敏感信息泄露
4. 最佳实践:设计模式、编码规范
5. 潜在Bug:空指针、边界条件、并发问题
输出格式:
1. 总体评价(1-2句话)
2. 发现的问题(按严重程度排序)
3. 优化建议(具体可行)
4. 改进后的代码示例(如果需要)
""";
// 2. 构建用户提示词
String userPrompt = String.format("""
请审查以下 %s 代码:
```%s
%s
```
代码说明:%s
请提供详细的审查意见。
""",
request.getLanguage(),
request.getLanguage(),
request.getCode(),
request.getDescription());
// 3. 配置选项(使用 GPT-4 获得更好的代码理解能力)
OpenAiChatOptions options = OpenAiChatOptions.builder()
.withModel("gpt-4")
.withTemperature(0.3) // 较低的温度,更准确
.withMaxTokens(2000)
.build();
// 4. 调用 API
Prompt prompt = new Prompt(
List.of(new SystemMessage(systemPrompt),
new UserMessage(userPrompt)),
options);
ChatResponse response = chatClient.call(prompt);
String reviewResult = response.getResult().getOutput().getContent();
// 5. 构建响应
return CodeReviewResponse.builder()
.reviewResult(reviewResult)
.language(request.getLanguage())
.success(true)
.build();
} catch (Exception e) {
log.error("代码审查失败", e);
return CodeReviewResponse.builder()
.success(false)
.errorMessage(e.getMessage())
.build();
}
}
/**
* Bug分析
*
* @param errorMessage 错误信息
* @param code 相关代码
* @return 分析结果和修复建议
*/
public String analyzeBug(String errorMessage, String code) {
log.info("分析Bug: {}", errorMessage);
try {
String systemPrompt = """
你是一个经验丰富的调试专家。
你的任务是分析错误信息和代码,找出问题根源并提供修复方案。
分析步骤:
1. 理解错误信息的含义
2. 定位问题代码位置
3. 分析问题产生的原因
4. 提供具体的修复方案
5. 给出修复后的代码示例
""";
String userPrompt = String.format("""
错误信息:
%s
相关代码:
```java
%s
```
请分析这个Bug并提供修复方案。
""",
errorMessage,
code);
OpenAiChatOptions options = OpenAiChatOptions.builder()
.withModel("gpt-4")
.withTemperature(0.2)
.withMaxTokens(1500)
.build();
Prompt prompt = new Prompt(
List.of(new SystemMessage(systemPrompt),
new UserMessage(userPrompt)),
options);
ChatResponse response = chatClient.call(prompt);
return response.getResult().getOutput().getContent();
} catch (Exception e) {
log.error("Bug分析失败", e);
return "分析失败:" + e.getMessage();
}
}
/**
* 生成代码注释
*
* @param code 代码
* @param language 编程语言
* @return 带注释的代码
*/
public String generateComments(String code, String language) {
log.info("生成代码注释 - 语言: {}", language);
try {
String systemPrompt = """
你是一个代码文档专家。
你的任务是为代码添加清晰、准确的注释。
注释要求:
1. 类和方法要有完整的文档注释
2. 复杂逻辑要有行内注释说明
3. 注释要简洁明了,不要废话
4. 使用标准的文档注释格式
5. 保持原有代码不变,只添加注释
""";
String userPrompt = String.format("""
请为以下 %s 代码添加注释:
```%s
%s
```
返回完整的带注释的代码。
""",
language,
language,
code);
OpenAiChatOptions options = OpenAiChatOptions.builder()
.withModel("gpt-3.5-turbo")
.withTemperature(0.3)
.withMaxTokens(2000)
.build();
Prompt prompt = new Prompt(
List.of(new SystemMessage(systemPrompt),
new UserMessage(userPrompt)),
options);
ChatResponse response = chatClient.call(prompt);
return response.getResult().getOutput().getContent();
} catch (Exception e) {
log.error("生成注释失败", e);
return code;
}
}
/**
* 生成单元测试
*
* @param code 要测试的代码
* @param language 编程语言
* @return 单元测试代码
*/
public String generateUnitTest(String code, String language) {
log.info("生成单元测试 - 语言: {}", language);
try {
String systemPrompt = """
你是一个测试工程师,擅长编写高质量的单元测试。
测试要求:
1. 覆盖正常情况和边界情况
2. 测试异常处理逻辑
3. 使用合适的测试框架(JUnit、Mockito等)
4. 测试方法命名清晰,表达测试意图
5. 包含必要的断言和验证
""";
String userPrompt = String.format("""
请为以下 %s 代码生成单元测试:
```%s
%s
```
返回完整的测试类代码。
""",
language,
language,
code);
OpenAiChatOptions options = OpenAiChatOptions.builder()
.withModel("gpt-4")
.withTemperature(0.3)
.withMaxTokens(2000)
.build();
Prompt prompt = new Prompt(
List.of(new SystemMessage(systemPrompt),
new UserMessage(userPrompt)),
options);
ChatResponse response = chatClient.call(prompt);
return response.getResult().getOutput().getContent();
} catch (Exception e) {
log.error("生成单元测试失败", e);
return "// 生成失败:" + e.getMessage();
}
}
}
DTO 定义:
package com.example.springai.dto;
import lombok.Data;
import lombok.Builder;
/**
* 代码审查请求DTO
*/
@Data
public class CodeReviewRequest {
private String code;
private String language;
private String description;
}
/**
* 代码审查响应DTO
*/
@Data
@Builder
public class CodeReviewResponse {
private String reviewResult;
private String language;
private Boolean success;
private String errorMessage;
}
测试示例:
# 代码审查
curl -X POST http://localhost:8080/api/code-assistant/review \
-H "Content-Type: application/json" \
-d '{
"code": "public String getUserName(User user) { return user.getName(); }",
"language": "java",
"description": "获取用户名称的方法"
}'
# Bug分析
curl -X POST http://localhost:8080/api/code-assistant/analyze-bug \
-H "Content-Type: application/json" \
-d '{
"errorMessage": "NullPointerException at line 15",
"code": "String name = user.getName().toUpperCase();"
}'
五、高级配置与优化
5.1 动态模型切换
在实际项目中,我们可能需要根据不同场景动态切换模型。
配置类:
package com.example.springai.config;
import org.springframework.ai.openai.OpenAiChatClient;
import org.springframework.ai.openai.OpenAiChatOptions;
import org.springframework.ai.openai.api.OpenAiApi;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* OpenAI 配置类
* 支持多模型配置和动态切换
*
* @author Your Name
* @since 1.0.0
*/
@Configuration
public class OpenAIConfig {
@Value("${spring.ai.openai.api-key}")
private String apiKey;
@Value("${spring.ai.openai.base-url:https://api.openai.com}")
private String baseUrl;
/**
* 配置 OpenAI API 客户端
*/
@Bean
public OpenAiApi openAiApi() {
return new OpenAiApi(baseUrl, apiKey);
}
/**
* 配置默认的 ChatClient(使用 GPT-3.5-turbo)
*/
@Bean
public OpenAiChatClient defaultChatClient(OpenAiApi openAiApi) {
OpenAiChatOptions options = OpenAiChatOptions.builder()
.withModel("gpt-3.5-turbo")
.withTemperature(0.7)
.withMaxTokens(1000)
.build();
return new OpenAiChatClient(openAiApi, options);
}
/**
* 配置高级 ChatClient(使用 GPT-4)
*/
@Bean("gpt4ChatClient")
public OpenAiChatClient gpt4ChatClient(OpenAiApi openAiApi) {
OpenAiChatOptions options = OpenAiChatOptions.builder()
.withModel("gpt-4")
.withTemperature(0.7)
.withMaxTokens(2000)
.build();
return new OpenAiChatClient(openAiApi, options);
}
/**
* 配置快速 ChatClient(使用 GPT-3.5-turbo,更低延迟)
*/
@Bean("fastChatClient")
public OpenAiChatClient fastChatClient(OpenAiApi openAiApi) {
OpenAiChatOptions options = OpenAiChatOptions.builder()
.withModel("gpt-3.5-turbo")
.withTemperature(0.5)
.withMaxTokens(500)
.build();
return new OpenAiChatClient(openAiApi, options);
}
}
模型选择服务:
package com.example.springai.service;
import org.springframework.ai.chat.ChatClient;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
/**
* 模型选择服务
* 根据任务类型选择合适的模型
*
* @author Your Name
* @since 1.0.0
*/
@Service
public class ModelSelectorService {
private final ChatClient defaultClient;
private final ChatClient gpt4Client;
private final ChatClient fastClient;
public ModelSelectorService(
ChatClient defaultClient,
@Qualifier("gpt4ChatClient") ChatClient gpt4Client,
@Qualifier("fastChatClient") ChatClient fastClient) {
this.defaultClient = defaultClient;
this.gpt4Client = gpt4Client;
this.fastClient = fastClient;
}
/**
* 根据任务类型选择模型
*
* @param taskType 任务类型
* @return 对应的 ChatClient
*/
public ChatClient selectModel(TaskType taskType) {
return switch (taskType) {
case SIMPLE_QA -> fastClient; // 简单问答用快速模型
case CODE_REVIEW -> gpt4Client; // 代码审查用GPT-4
case CONTENT_GENERATION -> defaultClient; // 内容生成用默认模型
case COMPLEX_REASONING -> gpt4Client; // 复杂推理用GPT-4
default -> defaultClient;
};
}
/**
* 任务类型枚举
*/
public enum TaskType {
SIMPLE_QA, // 简单问答
CODE_REVIEW, // 代码审查
CONTENT_GENERATION, // 内容生成
COMPLEX_REASONING // 复杂推理
}
}
5.2 请求重试机制
为了提高系统的可靠性,我们需要实现请求重试机制。
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.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;
/**
* 带重试机制的 Chat 服务
*
* @author Your Name
* @since 1.0.0
*/
@Slf4j
@Service
public class RetryableChatService {
private final ChatClient chatClient;
public RetryableChatService(ChatClient chatClient) {
this.chatClient = chatClient;
}
/**
* 带重试的 API 调用
*
* @param prompt 提示词
* @return 响应
*/
@Retryable(
value = {Exception.class},
maxAttempts = 3,
backoff = @Backoff(delay = 1000, multiplier = 2)
)
public ChatResponse callWithRetry(Prompt prompt) {
log.info("调用 OpenAI API(支持重试)");
try {
return chatClient.call(prompt);
} catch (Exception e) {
log.warn("API 调用失败,准备重试: {}", e.getMessage());
throw e;
}
}
}
启用重试配置:
package com.example.springai.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.retry.annotation.EnableRetry;
/**
* 重试配置
*/
@Configuration
@EnableRetry
public class RetryConfig {
}
pom.xml 添加依赖:
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</dependency>
5.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.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
/**
* 带缓存的 Chat 服务
*
* @author Your Name
* @since 1.0.0
*/
@Slf4j
@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 chatWithCache(String message) {
log.info("调用 OpenAI API(未命中缓存): {}", message);
Prompt prompt = new Prompt(message);
ChatResponse response = chatClient.call(prompt);
return response.getResult().getOutput().getContent();
}
}
缓存配置:
package com.example.springai.config;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 缓存配置
*/
@Configuration
@EnableCaching
public class CacheConfig {
@Bean
public CacheManager cacheManager() {
return new ConcurrentMapCacheManager("chatResponses");
}
}
使用 Redis 缓存(生产环境推荐):
<!-- pom.xml -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
# application.yml
spring:
redis:
host: localhost
port: 6379
password: ${REDIS_PASSWORD}
cache:
type: redis
redis:
time-to-live: 3600000 # 缓存1小时
package com.example.springai.config;
import org.springframework.cache.CacheManager;
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 org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.time.Duration;
/**
* Redis 缓存配置
*/
@Configuration
@EnableCaching
public class RedisCacheConfig {
@Bean
public CacheManager cacheManager(RedisConnectionFactory connectionFactory) {
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofHours(1)) // 缓存1小时
.serializeKeysWith(
RedisSerializationContext.SerializationPair.fromSerializer(
new StringRedisSerializer()))
.serializeValuesWith(
RedisSerializationContext.SerializationPair.fromSerializer(
new GenericJackson2JsonRedisSerializer()));
return RedisCacheManager.builder(connectionFactory)
.cacheDefaults(config)
.build();
}
}
5.4 Token 使用监控
监控 Token 使用情况对于成本控制至关重要。
package com.example.springai.service;
import lombok.Data;
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;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
/**
* Token 使用监控服务
*
* @author Your Name
* @since 1.0.0
*/
@Slf4j
@Service
public class TokenMonitorService {
private final ChatClient chatClient;
private final TokenUsageStats stats = new TokenUsageStats();
public TokenMonitorService(ChatClient chatClient) {
this.chatClient = chatClient;
}
/**
* 带监控的 API 调用
*
* @param prompt 提示词
* @return 响应
*/
public ChatResponse callWithMonitoring(Prompt prompt) {
long startTime = System.currentTimeMillis();
try {
ChatResponse response = chatClient.call(prompt);
// 记录 Token 使用情况
int promptTokens = response.getMetadata().getUsage().getPromptTokens();
int completionTokens = response.getMetadata().getUsage().getCompletionTokens();
int totalTokens = response.getMetadata().getUsage().getTotalTokens();
stats.addRequest(promptTokens, completionTokens, totalTokens);
long duration = System.currentTimeMillis() - startTime;
log.info("API调用完成 - Prompt Tokens: {}, Completion Tokens: {}, " +
"Total Tokens: {}, 耗时: {}ms",
promptTokens, completionTokens, totalTokens, duration);
return response;
} catch (Exception e) {
stats.incrementFailures();
log.error("API调用失败", e);
throw e;
}
}
/**
* 获取使用统计
*
* @return 统计信息
*/
public TokenUsageStats getStats() {
return stats;
}
/**
* 重置统计
*/
public void resetStats() {
stats.reset();
log.info("Token使用统计已重置");
}
/**
* Token 使用统计
*/
@Data
public static class TokenUsageStats {
private final AtomicInteger totalRequests = new AtomicInteger(0);
private final AtomicInteger failedRequests = new AtomicInteger(0);
private final AtomicLong totalPromptTokens = new AtomicLong(0);
private final AtomicLong totalCompletionTokens = new AtomicLong(0);
private final AtomicLong totalTokens = new AtomicLong(0);
public void addRequest(int promptTokens, int completionTokens, int total) {
totalRequests.incrementAndGet();
totalPromptTokens.addAndGet(promptTokens);
totalCompletionTokens.addAndGet(completionTokens);
totalTokens.addAndGet(total);
}
public void incrementFailures() {
failedRequests.incrementAndGet();
}
public void reset() {
totalRequests.set(0);
failedRequests.set(0);
totalPromptTokens.set(0);
totalCompletionTokens.set(0);
totalTokens.set(0);
}
/**
* 计算预估成本(基于 GPT-3.5-turbo 定价)
* 输入:$0.0015 / 1K tokens
* 输出:$0.002 / 1K tokens
*/
public double getEstimatedCost() {
double promptCost = (totalPromptTokens.get() / 1000.0) * 0.0015;
double completionCost = (totalCompletionTokens.get() / 1000.0) * 0.002;
return promptCost + completionCost;
}
@Override
public String toString() {
return String.format(
"总请求数: %d, 失败数: %d, 总Tokens: %d, " +
"Prompt Tokens: %d, Completion Tokens: %d, 预估成本: $%.4f",
totalRequests.get(),
failedRequests.get(),
totalTokens.get(),
totalPromptTokens.get(),
totalCompletionTokens.get(),
getEstimatedCost()
);
}
}
}
监控端点:
package com.example.springai.controller;
import com.example.springai.service.TokenMonitorService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
/**
* 监控控制器
*/
@Slf4j
@RestController
@RequestMapping("/api/monitor")
public class MonitorController {
private final TokenMonitorService monitorService;
public MonitorController(TokenMonitorService monitorService) {
this.monitorService = monitorService;
}
/**
* 获取 Token 使用统计
*/
@GetMapping("/token-usage")
public TokenMonitorService.TokenUsageStats getTokenUsage() {
return monitorService.getStats();
}
/**
* 重置统计
*/
@PostMapping("/reset-stats")
public String resetStats() {
monitorService.resetStats();
return "统计已重置";
}
}
六、成本优化策略
6.1 Token 计算与优化
Token 计算规则:
Token 计算:
├─ 英文:约 4 个字符 = 1 token
├─ 中文:约 1.5-2 个字符 = 1 token
├─ 代码:约 3-4 个字符 = 1 token
└─ 特殊字符:通常 1 个字符 = 1 token
成本计算(GPT-3.5-turbo):
├─ 输入:$0.0015 / 1K tokens
├─ 输出:$0.002 / 1K tokens
└─ 示例:1000次对话,平均500 tokens = $0.75-$1.00
成本计算(GPT-4):
├─ 输入:$0.03 / 1K tokens
├─ 输出:$0.06 / 1K tokens
└─ 示例:1000次对话,平均500 tokens = $15-$30
优化策略:
package com.example.springai.service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* Token 优化服务
*
* @author Your Name
* @since 1.0.0
*/
@Slf4j
@Service
public class TokenOptimizationService {
/**
* 优化提示词,减少 Token 使用
*
* @param prompt 原始提示词
* @return 优化后的提示词
*/
public String optimizePrompt(String prompt) {
// 1. 移除多余的空格和换行
String optimized = prompt.replaceAll("\\s+", " ").trim();
// 2. 简化重复的说明
optimized = optimized.replaceAll("请你|麻烦你|能否", "");
// 3. 使用简洁的表达
optimized = optimized.replace("非常感谢", "谢谢");
optimized = optimized.replace("尽可能", "尽量");
log.debug("提示词优化 - 原始长度: {}, 优化后长度: {}",
prompt.length(), optimized.length());
return optimized;
}
/**
* 截断对话历史,保留最近的N轮对话
*
* @param history 完整历史
* @param maxRounds 最大轮数
* @return 截断后的历史
*/
public <T> List<T> truncateHistory(List<T> history, int maxRounds) {
if (history.size() <= maxRounds * 2) {
return history;
}
// 保留最近的 N 轮对话(每轮包含用户消息和AI回复)
int startIndex = history.size() - (maxRounds * 2);
List<T> truncated = history.subList(startIndex, history.size());
log.debug("对话历史截断 - 原始: {} 条, 保留: {} 条",
history.size(), truncated.size());
return truncated;
}
/**
* 估算文本的 Token 数量
*
* @param text 文本
* @return 估算的 Token 数
*/
public int estimateTokens(String text) {
// 简单估算:中文按2字符/token,英文按4字符/token
int chineseChars = text.replaceAll("[^\\u4e00-\\u9fa5]", "").length();
int otherChars = text.length() - chineseChars;
int tokens = (chineseChars / 2) + (otherChars / 4);
log.debug("Token估算 - 文本长度: {}, 估算Tokens: {}", text.length(), tokens);
return tokens;
}
}
6.2 成本控制最佳实践
1. 选择合适的模型
/**
* 根据任务复杂度选择模型
*/
public String selectModelByComplexity(String task) {
// 简单任务:FAQ、简单对话
if (isSimpleTask(task)) {
return "gpt-3.5-turbo"; // 成本低
}
// 中等任务:内容生成、翻译
if (isMediumTask(task)) {
return "gpt-3.5-turbo"; // 性价比高
}
// 复杂任务:代码生成、复杂推理
if (isComplexTask(task)) {
return "gpt-4"; // 质量高
}
return "gpt-3.5-turbo"; // 默认
}
2. 实施缓存策略
缓存策略:
├─ 常见问题缓存(FAQ)
├─ 相似问题合并
├─ 结果复用
└─ 设置合理的过期时间
预期效果:
├─ 缓存命中率 30-50%
├─ 成本降低 30-50%
└─ 响应速度提升 80-90%
3. 限流和配额管理
package com.example.springai.service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 配额管理服务
*
* @author Your Name
* @since 1.0.0
*/
@Slf4j
@Service
public class QuotaManagementService {
// 用户每日配额(Token数)
private static final int DAILY_QUOTA = 100000;
// 用户使用记录
private final Map<String, AtomicInteger> userUsage = new ConcurrentHashMap<>();
/**
* 检查用户配额
*
* @param userId 用户ID
* @param estimatedTokens 预估Token数
* @return 是否允许请求
*/
public boolean checkQuota(String userId, int estimatedTokens) {
AtomicInteger usage = userUsage.computeIfAbsent(
userId, k -> new AtomicInteger(0));
int currentUsage = usage.get();
if (currentUsage + estimatedTokens > DAILY_QUOTA) {
log.warn("用户 {} 超出每日配额 - 当前: {}, 配额: {}",
userId, currentUsage, DAILY_QUOTA);
return false;
}
return true;
}
/**
* 记录使用量
*
* @param userId 用户ID
* @param tokens 使用的Token数
*/
public void recordUsage(String userId, int tokens) {
AtomicInteger usage = userUsage.computeIfAbsent(
userId, k -> new AtomicInteger(0));
usage.addAndGet(tokens);
log.info("用户 {} Token使用记录 - 本次: {}, 累计: {}",
userId, tokens, usage.get());
}
/**
* 重置用户配额(每日定时任务)
*/
public void resetDailyQuota() {
userUsage.clear();
log.info("每日配额已重置");
}
}
七、常见问题与解决方案
7.1 API 密钥相关问题
Q1: API 密钥无效或过期
错误信息:
Incorrect API key provided or API key has been revoked
解决方案:
1. 检查密钥是否正确复制(注意空格)
2. 确认密钥未被删除或撤销
3. 在 OpenAI 平台重新生成密钥
4. 检查环境变量是否正确设置
代码示例:
// 验证 API 密钥
@Component
public class ApiKeyValidator {
@Value("${spring.ai.openai.api-key}")
private String apiKey;
@PostConstruct
public void validateApiKey() {
if (apiKey == null || apiKey.isBlank()) {
throw new IllegalStateException("OpenAI API密钥未配置");
}
if (!apiKey.startsWith("sk-")) {
throw new IllegalStateException("OpenAI API密钥格式不正确");
}
log.info("API密钥验证通过");
}
}
Q2: 配额不足
错误信息:
You exceeded your current quota, please check your plan and billing details
解决方案:
1. 登录 OpenAI 平台检查账户余额
2. 充值账户或升级套餐
3. 检查是否有未支付的账单
4. 实施配额管理和限流策略
7.2 网络连接问题
Q3: 连接超时
错误信息:
Connection timeout / Read timeout
解决方案:
1. 检查网络连接
2. 配置代理(如果需要)
3. 增加超时时间
4. 实施重试机制
配置超时时间:
spring:
ai:
openai:
api-key: ${OPENAI_API_KEY}
# 配置超时时间(毫秒)
connect-timeout: 30000
read-timeout: 60000
配置代理:
@Configuration
public class ProxyConfig {
@Bean
public RestTemplate restTemplate() {
SimpleClientHttpRequestFactory factory =
new SimpleClientHttpRequestFactory();
// 配置代理
Proxy proxy = new Proxy(
Proxy.Type.HTTP,
new InetSocketAddress("proxy.example.com", 8080)
);
factory.setProxy(proxy);
// 配置超时
factory.setConnectTimeout(30000);
factory.setReadTimeout(60000);
return new RestTemplate(factory);
}
}
7.3 响应质量问题
Q4: 响应不准确或不相关
问题:AI 回复偏离主题或不准确
解决方案:
1. 优化提示词,提供更清晰的上下文
2. 使用 System Message 定义角色和规则
3. 调整 temperature 参数(降低随机性)
4. 提供示例(Few-shot Learning)
5. 考虑使用 GPT-4 获得更好的理解能力
示例:优化提示词
// ❌ 不好的提示词
String badPrompt = "翻译这个";
// ✅ 好的提示词
String goodPrompt = """
请将以下英文翻译成中文:
原文:%s
要求:
1. 保持原文的语气和风格
2. 使用地道的中文表达
3. 专业术语保持准确
""".formatted(englishText);
Q5: 响应被截断
问题:AI 回复不完整,突然结束
原因:超过 max_tokens 限制
解决方案:
1. 增加 max_tokens 参数
2. 分段处理长文本
3. 使用流式响应
// 配置更大的 max_tokens
OpenAiChatOptions options = OpenAiChatOptions.builder()
.withModel("gpt-3.5-turbo")
.withMaxTokens(2000) // 增加到 2000
.build();
7.4 性能问题
Q6: 响应速度慢
问题:API 调用耗时过长
解决方案:
1. 使用流式响应提升用户体验
2. 实施缓存策略
3. 选择更快的模型(gpt-3.5-turbo)
4. 减少提示词长度
5. 使用异步调用
异步调用示例:
@Service
public class AsyncChatService {
private final ChatClient chatClient;
@Async
public CompletableFuture<String> chatAsync(String message) {
Prompt prompt = new Prompt(message);
ChatResponse response = chatClient.call(prompt);
return CompletableFuture.completedFuture(
response.getResult().getOutput().getContent());
}
}
启用异步:
@Configuration
@EnableAsync
public class AsyncConfig {
@Bean
public Executor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(10);
executor.setQueueCapacity(100);
executor.setThreadNamePrefix("async-chat-");
executor.initialize();
return executor;
}
}
八、最佳实践
8.1 提示词工程最佳实践
1. 清晰的角色定义
String systemPrompt = """
你是一个专业的Java开发工程师,拥有10年以上的开发经验。
你擅长Spring Boot、微服务架构和性能优化。
你的回答要专业、准确、简洁。
""";
2. 结构化的输出格式
String prompt = """
请分析以下代码的问题,并按以下格式输出:
## 问题列表
1. [问题描述]
2. [问题描述]
## 优化建议
1. [建议内容]
2. [建议内容]
## 改进后的代码
```java
[代码]
```
""";
3. Few-shot Learning
String prompt = """
请将商品名称转换为SEO友好的URL。
示例:
输入:iPhone 15 Pro Max 256GB 深空黑
输出:iphone-15-pro-max-256gb-deep-space-black
输入:小米13 Ultra 12GB+256GB 黑色
输出:xiaomi-13-ultra-12gb-256gb-black
现在请转换:%s
""".formatted(productName);
8.2 错误处理最佳实践
1. 统一异常处理
package com.example.springai.exception;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
/**
* 全局异常处理器
*/
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
/**
* 处理 OpenAI API 异常
*/
@ExceptionHandler(OpenAiApiException.class)
public ResponseEntity<ErrorResponse> handleOpenAiException(
OpenAiApiException e) {
log.error("OpenAI API 异常", e);
ErrorResponse response = ErrorResponse.builder()
.code("OPENAI_API_ERROR")
.message("AI服务暂时不可用,请稍后再试")
.details(e.getMessage())
.build();
return ResponseEntity
.status(HttpStatus.SERVICE_UNAVAILABLE)
.body(response);
}
/**
* 处理配额超限异常
*/
@ExceptionHandler(QuotaExceededException.class)
public ResponseEntity<ErrorResponse> handleQuotaException(
QuotaExceededException e) {
log.warn("配额超限", e);
ErrorResponse response = ErrorResponse.builder()
.code("QUOTA_EXCEEDED")
.message("您的使用配额已用完,请明天再试")
.details(e.getMessage())
.build();
return ResponseEntity
.status(HttpStatus.TOO_MANY_REQUESTS)
.body(response);
}
}
@Data
@Builder
class ErrorResponse {
private String code;
private String message;
private String details;
}
2. 优雅降级
@Service
public class ResilientChatService {
private final ChatClient chatClient;
private final String fallbackResponse =
"抱歉,AI服务暂时不可用。您可以:\n" +
"1. 稍后再试\n" +
"2. 联系人工客服\n" +
"3. 查看帮助文档";
public String chatWithFallback(String message) {
try {
return chatClient.call(new Prompt(message))
.getResult()
.getOutput()
.getContent();
} catch (Exception e) {
log.error("AI调用失败,返回降级响应", e);
return fallbackResponse;
}
}
}
8.3 安全最佳实践
1. 输入验证和清理
@Service
public class InputValidationService {
private static final int MAX_INPUT_LENGTH = 4000;
private static final Pattern SENSITIVE_PATTERN =
Pattern.compile("(password|token|secret|key)\\s*[:=]\\s*\\S+",
Pattern.CASE_INSENSITIVE);
/**
* 验证和清理用户输入
*/
public String validateAndClean(String input) {
// 1. 检查长度
if (input == null || input.isBlank()) {
throw new IllegalArgumentException("输入不能为空");
}
if (input.length() > MAX_INPUT_LENGTH) {
throw new IllegalArgumentException(
"输入过长,最多" + MAX_INPUT_LENGTH + "字符");
}
// 2. 移除敏感信息
String cleaned = SENSITIVE_PATTERN.matcher(input)
.replaceAll("[REDACTED]");
// 3. 移除特殊字符
cleaned = cleaned.replaceAll("[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F]", "");
return cleaned;
}
}
2. 输出过滤
@Service
public class OutputFilterService {
/**
* 过滤AI响应中的敏感内容
*/
public String filterOutput(String output) {
// 1. 移除可能的API密钥
output = output.replaceAll("sk-[a-zA-Z0-9]{48}", "[API_KEY_REDACTED]");
// 2. 移除邮箱地址(可选)
// output = output.replaceAll("\\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Z|a-z]{2,}\\b", "[EMAIL_REDACTED]");
// 3. 移除电话号码(可选)
// output = output.replaceAll("\\d{3}-\\d{4}-\\d{4}", "[PHONE_REDACTED]");
return output;
}
}
3. 速率限制
@Service
public class RateLimitService {
private final Map<String, RateLimiter> limiters = new ConcurrentHashMap<>();
/**
* 检查速率限制
*
* @param userId 用户ID
* @return 是否允许请求
*/
public boolean checkRateLimit(String userId) {
RateLimiter limiter = limiters.computeIfAbsent(
userId,
k -> RateLimiter.create(10.0) // 每秒10个请求
);
return limiter.tryAcquire();
}
}
8.4 监控和日志最佳实践
1. 结构化日志
@Slf4j
@Service
public class StructuredLoggingService {
public void logApiCall(String userId, String model,
int tokens, long duration) {
// 使用结构化日志格式
log.info("API调用 - userId={}, model={}, tokens={}, duration={}ms",
userId, model, tokens, duration);
}
public void logError(String userId, String operation, Exception e) {
log.error("操作失败 - userId={}, operation={}, error={}",
userId, operation, e.getMessage(), e);
}
}
2. 指标收集
@Service
public class MetricsService {
private final MeterRegistry meterRegistry;
public MetricsService(MeterRegistry meterRegistry) {
this.meterRegistry = meterRegistry;
}
public void recordApiCall(String model, boolean success, long duration) {
// 记录API调用次数
meterRegistry.counter("openai.api.calls",
"model", model,
"success", String.valueOf(success))
.increment();
// 记录响应时间
meterRegistry.timer("openai.api.duration",
"model", model)
.record(duration, TimeUnit.MILLISECONDS);
}
public void recordTokenUsage(String model, int tokens) {
// 记录Token使用量
meterRegistry.counter("openai.tokens.used",
"model", model)
.increment(tokens);
}
}
九、练习题
基础练习
练习1:简单集成
创建一个 Spring Boot 项目,集成 OpenAI API,实现一个简单的问答接口。
要求:
- 配置 OpenAI API 密钥
- 创建 REST API 接口
- 实现简单对话功能
- 添加错误处理
练习2:参数配置
扩展练习1,支持动态配置模型参数。
要求:
- 支持设置 temperature
- 支持设置 max_tokens
- 支持选择不同的模型
- 返回 Token 使用情况
进阶练习
练习3:多轮对话
实现一个支持上下文的多轮对话系统。
要求:
- 保存对话历史
- 支持上下文理解
- 实现对话清除功能
- 限制历史长度(最近5轮)
练习4:流式响应
实现流式响应功能,提升用户体验。
要求:
- 使用 Server-Sent Events (SSE)
- 实时返回生成的内容
- 处理流式错误
- 前端实时显示
练习5:缓存优化
实现响应缓存,降低成本。
要求:
- 使用 Redis 缓存
- 设置合理的过期时间
- 实现缓存命中率统计
- 支持缓存清除
综合练习
练习6:智能客服系统
开发一个完整的智能客服系统。
要求:
- 支持多轮对话
- 实现意图识别
- 集成知识库
- 提供管理后台
- 统计对话数据
练习7:内容生成平台
开发一个AI内容生成平台。
要求:
- 支持多种内容类型(文章、标题、摘要)
- 实现模板管理
- 支持批量生成
- 提供内容评分
- 导出功能
练习8:代码助手
开发一个代码审查和优化助手。
要求:
- 支持多种编程语言
- 实现代码审查
- 生成优化建议
- 自动生成注释
- 生成单元测试
十、学习检查清单
基础知识
- 理解 OpenAI API 的基本概念
- 掌握 API 密钥的获取和管理
- 了解不同模型的特点和适用场景
- 理解 Token 的计算方式
- 掌握基本的 API 调用方法
集成开发
- 能够配置 Spring AI OpenAI 依赖
- 能够正确配置 application.yml
- 能够创建基本的 ChatClient
- 能够实现简单对话功能
- 能够处理 API 调用异常
高级功能
- 能够实现多轮对话
- 能够使用流式响应
- 能够动态切换模型
- 能够配置重试机制
- 能够实现响应缓存
实战应用
- 能够开发智能客服系统
- 能够实现内容生成功能
- 能够开发代码助手
- 能够集成到实际项目
- 能够处理生产环境问题
优化和监控
- 能够优化 Token 使用
- 能够实施成本控制
- 能够监控 API 使用情况
- 能够实现配额管理
- 能够分析和优化性能
安全和最佳实践
- 能够安全管理 API 密钥
- 能够实现输入验证
- 能够实现输出过滤
- 能够实施速率限制
- 能够遵循最佳实践
十一、扩展阅读
官方文档
-
OpenAI API 文档
- https://platform.openai.com/docs/api-reference
- 完整的 API 参考文档
-
Spring AI 文档
- https://docs.spring.io/spring-ai/reference/
- Spring AI 官方文档
-
OpenAI 最佳实践
- https://platform.openai.com/docs/guides/best-practices
- 官方最佳实践指南
技术博客
-
OpenAI 博客
- https://openai.com/blog
- 最新功能和案例分享
-
Spring 官方博客
- https://spring.io/blog
- Spring AI 相关文章
开源项目
-
Spring AI Examples
- https://github.com/spring-projects/spring-ai-examples
- 官方示例项目
-
ChatGPT 集成案例
- GitHub 搜索 “spring-ai openai”
- 社区优秀项目
学习资源
-
视频教程
- YouTube: “Spring AI Tutorial”
- B站: “Spring AI 教程”
-
在线课程
- Udemy: Spring AI 相关课程
- Coursera: AI 应用开发
社区资源
-
Stack Overflow
- 标签: spring-ai, openai-api
- 问题讨论和解答
-
GitHub Discussions
- Spring AI 项目讨论区
- 功能请求和问题反馈
-
Discord/Slack
- Spring 社区频道
- OpenAI 开发者社区
十二、总结
核心要点回顾
1. OpenAI 集成基础
- OpenAI 提供强大的 AI 能力
- Spring AI 简化了集成过程
- 正确配置是成功的关键
2. 实战应用场景
- 智能客服:提升服务效率
- 内容生成:提高创作效率
- 代码助手:辅助开发工作
3. 成本优化策略
- 选择合适的模型
- 实施缓存策略
- 优化 Token 使用
- 配额管理和限流
4. 最佳实践
- 安全管理 API 密钥
- 实现错误处理和重试
- 监控和日志记录
- 输入验证和输出过滤
下一步学习建议
短期目标(1-2周)
- 完成所有基础练习
- 搭建本地开发环境
- 实现简单的应用场景
- 熟悉常见问题的解决方法
中期目标(1个月)
- 完成进阶练习
- 开发一个完整的项目
- 掌握性能优化技巧
- 学习成本控制策略
长期目标(3个月)
- 完成综合练习
- 在生产环境部署应用
- 积累实战经验
- 探索更多应用场景
常见误区
误区1:过度依赖 AI
- AI 是辅助工具,不是万能的
- 需要人工审核和优化
- 关键业务逻辑不能完全依赖 AI
误区2:忽视成本控制
- Token 使用会快速累积
- 需要实施配额管理
- 选择合适的模型很重要
误区3:不重视安全
- API 密钥需要妥善保管
- 用户输入需要验证
- 输出内容需要过滤
误区4:缺少错误处理
- API 调用可能失败
- 需要实现重试机制
- 要有降级方案
成功案例分享
案例1:电商客服系统
- 场景:处理大量重复咨询
- 方案:AI 客服 + 人工兜底
- 效果:响应速度提升 80%,人工成本降低 60%
案例2:内容创作平台
- 场景:批量生成商品描述
- 方案:模板 + AI 生成 + 人工审核
- 效果:创作效率提升 10倍,质量稳定
案例3:代码审查工具
- 场景:提升代码质量
- 方案:AI 自动审查 + 人工复核
- 效果:发现问题数量提升 40%,审查时间减少 50%
持续学习资源
每日学习
- 关注 OpenAI 官方博客
- 阅读 Spring AI 更新日志
- 参与社区讨论
每周实践
- 尝试新的应用场景
- 优化现有代码
- 分享学习心得
每月总结
- 回顾学习进度
- 整理最佳实践
- 规划下月目标
恭喜你完成了 OpenAI 模型集成的学习!
现在你已经掌握了:
- ✅ OpenAI API 的基本使用
- ✅ Spring AI 的集成方法
- ✅ 实战应用场景的开发
- ✅ 成本优化和性能调优
- ✅ 安全和最佳实践
继续学习下一章节:Azure OpenAI 集成,探索企业级 AI 解决方案!
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)