前言
随着人工智能技术的快速发展,将AI能力集成到企业级应用中变得越来越重要。Spring AI作为Spring生态系统中的新成员,为Java开发者提供了标准化、开箱即用的AI集成方案。本教程将详细介绍如何使用Spring Boot集成Spring AI OpenAI Starter,快速为您的应用添加智能对话功能。
一、环境准备
1. 技术要求
- JDK: 17 或更高版本
- 构建工具: Maven 3.6+ 或 Gradle
- Spring Boot: 3.2+ (推荐最新稳定版)
- OpenAI账号 : 需要在OpenAI平台注册并获取API Key
2. 创建Spring Boot项目
您可以通过以下两种方式之一创建项目:
方式一:使用start.spring.io
- 访问 start.spring.io
- 选择以下依赖:
- Spring Web
- Spring AI (选择对应版本)
- 其他您可能需要的依赖(如Spring Security等)
方式二:手动添加依赖
如果您已有Spring Boot项目,直接在pom.xml
中添加以下依赖:
XML
<!-- Spring AI OpenAI Starter -->
<dependency>
<groupId>io.springboot.ai</groupId>
<artifactId>spring-ai-openai-spring-boot-starter</artifactId>
<version>1.0.0</version> <!-- 请使用最新版本 -->
</dependency>
<!-- Spring Boot Web Starter (如果尚未添加) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
二、配置OpenAI API
1. 获取OpenAI API Key
- 登录OpenAI平台
- 进入"API Keys"页面
- 创建新的API Key并妥善保存
2. 配置application.yml
在src/main/resources/application.yml
文件中添加以下配置:
javascript
spring:
ai:
openai:
api-key: "sk-your-openai-api-key-here" # 替换为您的实际OpenAI API Key
base-url: "https://api.openai.com/v1" # 默认值,通常无需修改
chat:
options:
model: "gpt-4-turbo" # 您想使用的模型,如gpt-3.5-turbo, gpt-4等
temperature: 0.7 # 控制生成文本的随机性(0-2)
max-tokens: 500 # 生成的最大token数
安全建议 :
为了安全起见,建议不要将API Key直接硬编码在配置文件中,而是使用环境变量:
javascript
spring:
ai:
openai:
api-key: ${OPENAI_API_KEY} # 从环境变量读取
然后,在运行应用前设置环境变量:
javascript
export OPENAI_API_KEY=sk-your-openai-api-key-here
或者在Windows命令提示符中:
javascript
set OPENAI_API_KEY=sk-your-openai-api-key-here
三、核心功能实现
1. 基础对话功能
创建AI控制器
创建一个REST控制器来处理AI对话请求:
java
import org.springframework.ai.chat.ChatClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/ai")
public class AIController {
private final ChatClient chatClient;
@Autowired
public AIController(ChatClient chatClient) {
this.chatClient = chatClient;
}
/**
* 基础对话接口
* @param message 用户输入的消息
* @return AI的回复
*/
@GetMapping("/chat")
public String chat(@RequestParam String message) {
return chatClient.call(message);
}
/**
* 基础对话接口(POST方式)
* @param userInput 用户输入
* @return AI的回复
*/
@PostMapping("/chat")
public String generateText(@RequestBody String userInput) {
return chatClient.call(userInput);
}
}
测试基础对话
启动Spring Boot应用后,您可以通过以下方式测试:
方式一:浏览器访问
javascript
http://localhost:8080/ai/chat?message=你好,请介绍一下你自己
方式二:使用cURL测试
javascript
curl -X GET "http://localhost:8080/ai/chat?message=请写一个简单的Java Hello World程序"
方式三:使用Postman等工具发送POST请求
- URL:
http://localhost:8080/ai/chat
- Method: POST
- Body: raw, text/plain
- 内容: "请解释Spring Boot的核心特性"
2. 带上下文的对话
为了让对话更有连续性,我们可以实现带上下文的对话功能:
java
import org.springframework.ai.chat.ChatClient;
import org.springframework.ai.chat.message.Message;
import org.springframework.ai.chat.message.SystemMessage;
import org.springframework.ai.chat.message.UserMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
@RestController
@RequestMapping("/ai")
public class AIContextController {
private final ChatClient chatClient;
// 简单的上下文存储(生产环境应使用更可靠的存储方案)
private List<Message> conversationHistory = new ArrayList<>();
@Autowired
public AIContextController(ChatClient chatClient) {
this.chatClient = chatClient;
// 初始化系统消息
conversationHistory.add(new SystemMessage("你是一个专业的技术助手,擅长Java开发和人工智能相关知识。"));
}
/**
* 带上下文的对话
* @param userInput 用户输入
* @return AI的回复
*/
@PostMapping("/chat/context")
public String chatWithContext(@RequestBody String userInput) {
// 添加用户消息到历史记录
conversationHistory.add(new UserMessage(userInput));
// 创建包含历史记录的Prompt
Prompt prompt = new Prompt(conversationHistory);
// 调用AI服务
String response = chatClient.call(prompt).getResult().getOutput().getContent();
// 添加AI回复到历史记录
conversationHistory.add(new UserMessage(response)); // 注意:这里应该是AssistantMessage,但Spring AI可能没有这个类
return response;
}
/**
* 清除对话上下文
*/
@PostMapping("/chat/context/clear")
public String clearContext() {
conversationHistory.clear();
conversationHistory.add(new SystemMessage("你是一个专业的技术助手,擅长Java开发和人工智能相关知识。"));
return "对话上下文已清除";
}
}
注意 :上面的代码中使用了UserMessage
来表示AI的回复,这在实际情况中可能不太准确。Spring AI可能提供了专门的AssistantMessage
类,如果没有,您可能需要自己创建或考虑使用其他方式管理上下文。
3. 高级参数控制
您可以通过自定义OpenAiChatOptions
来更精细地控制AI的行为:
java
import org.springframework.ai.chat.ChatClient;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.openai.OpenAiChatOptions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/ai")
public class AIAdvancedController {
private final ChatClient chatClient;
@Autowired
public AIAdvancedController(ChatClient chatClient) {
this.chatClient = chatClient;
}
/**
* 高级参数控制的对话
* @param message 用户输入
* @return AI的回复
*/
@PostMapping("/chat/advanced")
public String advancedChat(@RequestBody String message) {
// 自定义参数
OpenAiChatOptions options = OpenAiChatOptions.builder()
.withModel("gpt-4") // 指定模型
.withTemperature(0.3) // 较低的随机性,回复更确定
.withMaxTokens(1000) // 最大生成token数
// 可以添加更多选项,如topP, frequencyPenalty, presencePenalty等
.build();
// 构建 Prompt
Prompt request = new Prompt(message, options);
return chatClient.call(request).getResult().getOutput().getContent();
}
/**
* 使用不同模型的对话
* @param message 用户输入
* @param modelName 模型名称
* @return AI的回复
*/
@PostMapping("/chat/model/{modelName}")
public String chatWithSpecificModel(@RequestBody String message, @PathVariable String modelName) {
OpenAiChatOptions options = OpenAiChatOptions.builder()
.withModel(modelName) // 动态指定模型
.withTemperature(0.7)
.withMaxTokens(800)
.build();
Prompt request = new Prompt(message, options);
return chatClient.call(request).getResult().getOutput().getContent();
}
}
4. 流式响应(Server-Sent Events)
对于长时间运行的请求,流式响应可以提供更好的用户体验:
java
import org.springframework.ai.chat.StreamingChatClient;
import org.springframework.ai.chat.message.UserMessage;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
@RestController
@RequestMapping("/ai")
public class AIStreamingController {
private final StreamingChatClient streamingChatClient;
@Autowired
public AIStreamingController(StreamingChatClient streamingChatClient) {
this.streamingChatClient = streamingChatClient;
}
/**
* 流式对话接口
* @param message 用户输入的消息
* @return 流式的AI回复
*/
@GetMapping(value = "/chat/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> streamChat(@RequestParam String message) {
Prompt prompt = new Prompt(new UserMessage(message));
return streamingChatClient.stream(prompt)
.map(content -> content.toString());
}
/**
* 流式对话接口(POST方式)
* @param message 用户输入
* @return 流式的AI回复
*/
@PostMapping(value = "/chat/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> streamChatPost(@RequestBody String message) {
Prompt prompt = new Prompt(new UserMessage(message));
return streamingChatClient.stream(prompt)
.map(content -> content.toString());
}
}
测试流式响应 :
您可以使用支持SSE的客户端(如Postman或专门的SSE客户端)来测试流式接口,或者创建一个简单的前端页面来展示流式效果。
四、进阶功能:提示词工程
提示词工程(Prompt Engineering)是通过精心设计提示词来引导AI生成更准确、更有用内容的技术。
1. 创建自定义提示词模板
java
import org.springframework.ai.chat.ChatClient;
import org.springframework.ai.chat.prompt.PromptTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
// 假设有一个DTO类用于封装翻译请求
record TranslationRequest(String sourceLang, String targetLang, String text) {}
@RestController
@RequestMapping("/ai")
public class AIPromptTemplateController {
private final ChatClient chatClient;
@Autowired
public AIPromptTemplateController(ChatClient chatClient) {
this.chatClient = chatClient;
}
/**
* 翻译功能 - 使用提示词模板
* @param request 翻译请求
* @return 翻译结果
*/
@PostMapping("/translate")
public String translate(@RequestBody TranslationRequest request) {
// 创建提示词模板
PromptTemplate promptTemplate = new PromptTemplate("""
将以下{sourceLang}文本翻译成{targetLang}:
{text}
翻译结果:
""");
// 设置模板变量
promptTemplate.add("sourceLang", request.sourceLang());
promptTemplate.add("targetLang", request.targetLang());
promptTemplate.add("text", request.text());
// 渲染提示词并调用AI
return chatClient.call(promptTemplate.render()).getResult().getOutput().getContent();
}
/**
* 代码生成 - 使用提示词模板
* @param language 编程语言
* @param description 功能描述
* @return 生成的代码
*/
@PostMapping("/generate-code")
public String generateCode(@RequestParam String language, @RequestParam String description) {
PromptTemplate promptTemplate = new PromptTemplate("""
用{language}编写一个程序,实现以下功能: {description}
请提供完整的可运行代码,包括必要的导入语句和主函数。
代码应该有良好的注释和结构。
生成的代码:
""");
promptTemplate.add("language", language);
promptTemplate.add("description", description);
return chatClient.call(promptTemplate.render()).getResult().getOutput().getContent();
}
}
2. 测试提示词模板
测试翻译功能:
javascript
curl -X POST -H "Content-Type: application/json" \
-d '{"sourceLang":"English","targetLang":"Chinese","text":"Hello, how are you today?"}' \
http://localhost:8080/ai/translate
测试代码生成功能:
javascript
curl -X POST "http://localhost:8080/ai/generate-code?language=Java&description=一个简单的计算器,能够进行加减乘除运算" \
-H "Content-Type: application/x-www-form-urlencoded"
五、完整示例项目结构
javascript
src/
├── main/
│ ├── java/
│ │ └── com/
│ │ └── example/
│ │ └── aiintegration/
│ │ ├── AiIntegrationApplication.java
│ │ ├── controller/
│ │ │ ├── AIController.java
│ │ │ ├── AIContextController.java
│ │ │ ├── AIAdvancedController.java
│ │ │ └── AIStreamingController.java
│ │ └── dto/
│ │ └── TranslationRequest.java
│ └── resources/
│ ├── application.yml
│ └── static/ # 可选:前端文件
└── test/
└── java/
└── com/
└── example/
└── aiintegration/
└── AiIntegrationApplicationTests.java
主应用类
java
package com.example.aiintegration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class AiIntegrationApplication {
public static void main(String[] args) {
SpringApplication.run(AiIntegrationApplication.class, args);
}
}
六、测试与验证
1. 启动应用
使用您的IDE或命令行启动Spring Boot应用:
bash
mvn spring-boot:run
# 或
gradle bootRun
2. 测试接口
基础对话测试:
- GET请求:
http://localhost:8080/ai/chat?message=你好,介绍一下Spring Boot
- 或POST请求到
http://localhost:8080/ai/chat
,body为"你好,介绍一下Spring Boot"
高级参数测试:
- POST请求到
http://localhost:8080/ai/chat/advanced
,body为"解释微服务架构的优缺点"
流式响应测试:
- GET请求:
http://localhost:8080/ai/chat/stream?message=给我讲一个笑话
- 使用支持SSE的客户端查看流式效果
翻译功能测试:
curl -X POST -H "Content-Type: application/json" \
-d '{"sourceLang":"English","targetLang":"Chinese","text":"The quick brown fox jumps over the lazy dog."}' \
http://localhost:8080/ai/translate
3. 单元测试
创建测试类验证ChatClient的基本功能:
java
package com.example.aiintegration;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.ai.chat.ChatClient;
import static org.junit.jupiter.api.Assertions.assertNotNull;
@SpringBootTest
class AiIntegrationApplicationTests {
@Autowired
private ChatClient chatClient;
@Test
void contextLoads() {
}
@Test
void testChatClient() {
String response = chatClient.call("你好,你能做什么?");
System.out.println("AI 回复: " + response);
assertNotNull(response);
}
}
七、生产环境建议
1. 安全最佳实践
- API密钥管理:永远不要将API密钥硬编码在代码中,使用环境变量或密钥管理服务
- 访问控制:为AI接口添加适当的认证和授权
- 输入验证:验证所有用户输入,防止滥用和注入攻击
- 速率限制:实现API速率限制,防止滥用和超额费用
2. 性能优化
- 连接池:配置适当的网络连接池参数
- 缓存:对常见问题的AI响应实现缓存机制
- 异步处理:对复杂的AI请求考虑使用异步处理
- 监控:监控AI接口的性能和使用情况
3. 错误处理与重试
- 实现健壮的错误处理机制
- 对暂时性错误实现重试逻辑
- 监控API使用配额和限制
八、总结
通过本教程,您已经学会了如何使用Spring Boot集成Spring AI OpenAI Starter,为您的应用添加强大的AI能力。从基础对话功能到高级的流式响应和提示词工程,Spring AI提供了丰富的功能来满足各种AI集成需求。
Spring AI的优势在于其标准化的API设计,使得您可以轻松切换不同的AI供应商而无需大幅修改业务代码。随着AI技术的不断发展,这种抽象层将为您的应用提供更大的灵活性和未来保障。