Spring AI 是 Spring 生态系统中用于简化 AI 服务集成的框架,它提供了统一的 API 抽象层,让 Java 开发者能够轻松连接各种 AI 模型(如 OpenAI、Azure OpenAI、Hugging Face 等),而无需关注底层实现细节。本文将深入解析 Spring AI 的核心功能、使用场景及示例代码,帮助你快速上手构建智能应用。
Spring AI 框架概述
核心特性
- 多模型支持:无缝集成主流 AI 服务提供商,如 OpenAI、Azure OpenAI、Hugging Face 等。
- 统一抽象层:通过标准化接口(如
ChatClient
、EmbeddingClient
)简化模型交互。 - 提示工程支持:提供模板管理、参数绑定和提示优化功能。
- 流式响应处理:支持实时处理 AI 生成的文本流。
- 依赖注入:与 Spring 生态无缝集成,支持自动配置和依赖注入。
核心组件
ChatClient
:处理对话式 AI 请求(如 GPT 模型)。EmbeddingClient
:生成文本嵌入向量(用于语义搜索、相似度计算)。PromptTemplate
:管理和参数化提示模板。Message
:封装 AI 交互中的消息(用户输入、系统指令、助手回复)。
快速上手:构建第一个 Spring AI 应用
步骤 1:添加 Maven 依赖
首先,创建一个 Spring Boot 项目,并添加 Spring AI 相关依赖:
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.2</version>
<relativePath/>
</parent>
<groupId>com.example</groupId>
<artifactId>spring-ai-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<java.version>17</java.version>
<!-- Spring AI 版本 -->
<spring-ai.version>0.8.0</spring-ai.version>
</properties>
<dependencies>
<!-- Spring Boot 基础依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- Spring AI 核心依赖 -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-core</artifactId>
<version>${spring-ai.version}</version>
</dependency>
<!-- OpenAI 集成 -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-openai</artifactId>
<version>${spring-ai.version}</version>
</dependency>
<!-- 开发工具 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</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>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
步骤 2:配置 API 密钥
在 src/main/resources/application.properties
中添加 OpenAI API 密钥:
properties
# OpenAI API 密钥(需替换为你的实际密钥)
spring.ai.openai.api-key=${OPENAI_API_KEY:your-api-key-here}
# 可选配置:模型、温度等
spring.ai.openai.chat.model=gpt-3.5-turbo
spring.ai.openai.chat.temperature=0.7
步骤 3:创建聊天服务
创建一个服务类,用于处理 AI 对话:
java
package com.example.demo;
import org.springframework.ai.chat.ChatClient;
import org.springframework.ai.chat.ChatResponse;
import org.springframework.ai.chat.Generation;
import org.springframework.ai.prompt.Prompt;
import org.springframework.ai.prompt.PromptTemplate;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
@Service
public class ChatService {
private final ChatClient chatClient;
public ChatService(ChatClient chatClient) {
this.chatClient = chatClient;
}
/**
* 发送简单文本请求并获取回复
*/
public String chat(String prompt) {
// 创建提示模板
Map<String, Object> model = new HashMap<>();
model.put("question", prompt);
PromptTemplate promptTemplate = new PromptTemplate("{{question}}");
Prompt aiPrompt = promptTemplate.create(model);
// 调用 AI 服务
ChatResponse response = chatClient.generate(aiPrompt);
return response.getGeneration().getText();
}
/**
* 流式处理 AI 回复
*/
public void chatStream(String prompt, Consumer<String> responseConsumer) {
// 创建提示模板
Map<String, Object> model = new HashMap<>();
model.put("question", prompt);
PromptTemplate promptTemplate = new PromptTemplate("{{question}}");
Prompt aiPrompt = promptTemplate.create(model);
// 流式调用 AI 服务
chatClient.generateStream(aiPrompt)
.forEach(response -> {
for (Generation generation : response.getGenerations()) {
responseConsumer.accept(generation.getText());
}
});
}
// 函数式接口,用于流式响应处理
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
}
}
步骤 4:创建 REST API 控制器
添加一个控制器,提供 HTTP 接口:
java
package com.example.demo.controller;
import com.example.demo.ChatService;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/chat")
public class ChatController {
private final ChatService chatService;
public ChatController(ChatService chatService) {
this.chatService = chatService;
}
@PostMapping
public String chat(@RequestBody String prompt) {
return chatService.chat(prompt);
}
}
步骤 5:启动应用
创建应用启动类:
java
package com.example.demo;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
public class SpringAiDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SpringAiDemoApplication.class, args);
}
@Bean
public CommandLineRunner demo(ChatService chatService) {
return args -> {
// 简单对话示例
String response = chatService.chat("解释一下什么是量子计算");
System.out.println("AI 回复: " + response);
// 流式响应示例
chatService.chatStream("写一首关于春天的短诗",
chunk -> System.out.print(chunk));
};
}
}
核心功能解析
1. ChatClient:对话式 AI 交互
ChatClient
是 Spring AI 的核心接口,用于发送请求并接收 AI 回复。Spring 会根据配置自动创建对应的实现(如 OpenAiChatClient
)。
java
// 自动注入 ChatClient
@Service
public class ChatService {
private final ChatClient chatClient;
public ChatService(ChatClient chatClient) {
this.chatClient = chatClient;
}
public String chat(String prompt) {
// 创建提示并发送请求
Prompt aiPrompt = new PromptTemplate("{{question}}").create(Map.of("question", prompt));
return chatClient.generate(aiPrompt).getGeneration().getText();
}
}
2. PromptTemplate:提示工程
提示工程是优化 AI 输出质量的关键。Spring AI 通过 PromptTemplate
支持参数化模板:
java
// 复杂提示模板示例
String template = """
你是一个专业的{role},请回答以下问题:
{question}
请用{language}回答,保持{tone}的语气。
""";
Map<String, Object> model = Map.of(
"role", "技术专家",
"question", "什么是微服务架构?",
"language", "中文",
"tone", "简洁明了"
);
Prompt aiPrompt = new PromptTemplate(template).create(model);
3. 流式响应处理
对于长文本生成,流式响应能提供更好的用户体验:
java
public void chatStream(String prompt) {
Prompt aiPrompt = new PromptTemplate("{{question}}").create(Map.of("question", prompt));
// 订阅流式响应
chatClient.generateStream(aiPrompt)
.forEach(response -> {
for (Generation gen : response.getGenerations()) {
System.out.print(gen.getText()); // 实时输出每个文本片段
}
});
}
4. 多轮对话支持
Spring AI 支持维护对话上下文,实现连贯的多轮交互:
java
public String multiTurnChat() {
List<Message> messages = new ArrayList<>();
// 添加系统提示(影响 AI 行为)
messages.add(new SystemMessage("你是一个简洁的助手,只回答问题,不添加额外解释。"));
// 第一轮对话
messages.add(new UserMessage("介绍一下 Spring 框架"));
String firstReply = chatClient.generate(new Prompt(messages)).getGeneration().getText();
messages.add(new AssistantMessage(firstReply));
// 第二轮对话(带上下文)
messages.add(new UserMessage("Spring 和 Spring Boot 有什么区别?"));
return chatClient.generate(new Prompt(messages)).getGeneration().getText();
}
高级应用场景
1. 嵌入向量生成与语义搜索
使用 EmbeddingClient
生成文本嵌入向量,可用于语义搜索、相似度计算等:
java
@Service
public class SemanticSearchService {
private final EmbeddingClient embeddingClient;
public SemanticSearchService(EmbeddingClient embeddingClient) {
this.embeddingClient = embeddingClient;
}
// 计算文本相似度
public double calculateSimilarity(String text1, String text2) {
List<Double> embedding1 = embeddingClient.embed(text1);
List<Double> embedding2 = embeddingClient.embed(text2);
// 计算余弦相似度
double dotProduct = 0.0;
double norm1 = 0.0;
double norm2 = 0.0;
for (int i = 0; i < embedding1.size(); i++) {
dotProduct += embedding1.get(i) * embedding2.get(i);
norm1 += Math.pow(embedding1.get(i), 2);
norm2 += Math.pow(embedding2.get(i), 2);
}
return dotProduct / (Math.sqrt(norm1) * Math.sqrt(norm2));
}
}
2. 自定义 AI 服务
如果需要使用非官方支持的模型,可以自定义 ChatClient
实现:
java
@Configuration
public class CustomAIClientConfig {
@Bean
public ChatClient customChatClient() {
return new ChatClient() {
@Override
public ChatResponse generate(Prompt prompt) {
// 实现自定义 AI 服务调用逻辑
String responseText = callCustomAIService(prompt);
return new ChatResponse(new Generation(responseText));
}
@Override
public Flux<ChatResponse> generateStream(Prompt prompt) {
// 实现流式响应逻辑
return Flux.empty(); // 简化示例
}
};
}
private String callCustomAIService(Prompt prompt) {
// 调用自定义 AI API
return "自定义 AI 回复";
}
}
部署与最佳实践
1. 安全配置
- 使用环境变量或配置中心管理 API 密钥,避免硬编码。
- 在生产环境中启用 HTTPS。
2. 性能优化
- 使用连接池减少 API 调用延迟。
- 对高频问题实现缓存机制:
java
@Service
public class CachedChatService {
private final ChatClient chatClient;
private final Cache<String, String> chatCache;
public CachedChatService(ChatClient chatClient, CacheManager cacheManager) {
this.chatClient = chatClient;
this.chatCache = cacheManager.getCache("chatCache");
}
public String chat(String prompt) {
return chatCache.get(prompt, () -> {
// 缓存未命中时调用 AI 服务
return chatClient.generate(
new PromptTemplate("{{question}}").create(Map.of("question", prompt))
).getGeneration().getText();
});
}
}
3. 错误处理
- 捕获
AIException
处理 API 调用失败。 - 添加重试机制(如使用 Spring Retry):
java
@Service
public class ResilientChatService {
private final ChatClient chatClient;
public ResilientChatService(ChatClient chatClient) {
this.chatClient = chatClient;
}
@Retryable(value = {AIException.class}, maxAttempts = 3, backoff = @Backoff(delay = 1000))
public String chat(String prompt) {
try {
return chatClient.generate(
new PromptTemplate("{{question}}").create(Map.of("question", prompt))
).getGeneration().getText();
} catch (AIException e) {
// 可添加自定义日志或降级策略
throw e;
}
}
}
总结与展望
Spring AI 框架通过标准化接口和依赖注入,极大简化了 AI 服务集成,让 Java 开发者可以专注于业务逻辑。它支持多模型、多服务提供商,适合构建企业级 AI 应用(如智能客服、内容生成、数据分析助手等)。
随着 AI 技术的快速发展,Spring AI 也在持续迭代,未来可能会支持更多模型(如开源大模型)、增强提示工程工具、提供更完善的企业级功能(如审计日志、权限控制)等。
如果需要扩展功能,可以通过自定义 ChatClient
或实现 MessageProcessor
接口来处理消息预处理和后处理。
参考资源
通过本文的示例,你已经掌握了 Spring AI 的核心用法。现在,你可以尝试将 AI 能力集成到你的 Spring 应用中,创造更智能的用户体验!
Comments NOTHING