1. SpringAI 框架概述
SpringAI是Spring官方推出的AI应用开发框架,它将大模型能力封装成Spring Boot风格,让Java开发者能够像使用其他Spring组件一样轻松集成AI功能。SpringAI的核心价值在于提供统一API抽象层,支持多种主流AI模型和服务,同时保持Spring生态的简洁性和一致性。
核心定位与优势:
- 标准化接入:提供类似JdbcTemplate的模板方法调用LLM(大语言模型),降低学习成本
- 多模型支持:统一接口支持OpenAI、Azure OpenAI、Ollama(本地模型)、Hugging Face等20+种AI服务
- 企业级特性:内置重试机制、限流策略、监控指标等生产就绪功能
- Spring生态集成:完美继承Spring Boot的自动配置特性,配置驱动,开箱即用
与Python生态的LangChain相对应,SpringAI为Java开发者提供了同等级别的AI应用开发体验,支持从简单的文本生成到复杂的RAG(检索增强生成)应用场景。
2. 环境准备与项目配置
2.1 开发环境要求
在开始使用SpringAI前,需确保您的开发环境满足以下要求:
- JDK版本:JDK 17或更高版本(推荐JDK 21)
- Spring Boot:3.0.0或更高版本(推荐3.2.x)
- 构建工具:Maven 3.6+ 或 Gradle 8.5+
- IDE:IntelliJ IDEA、Eclipse或VS Code等
2.2 项目初始化与依赖配置
使用Spring Initializr创建项目时,选择以下依赖:
- Spring Web
- Spring AI Starter(根据需要的模型选择具体starter)
- Lombok(可选,简化代码)
Maven依赖配置(以OpenAI为例):
xml
<dependencyManagement>
<dependencies>
<!-- Spring AI BOM -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>1.0.0-M2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- Spring Boot BOM -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>3.2.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- Spring AI OpenAI Starter -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-openai-spring-boot-starter</artifactId>
</dependency>
<!-- Spring Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
如需使用本地模型(如通过Ollama),可替换为:
xml
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-ollama-spring-boot-starter</artifactId>
<version>1.0.0-M2</version>
</dependency>
由于Spring AI版本迭代较快,可能需要添加相应的仓库配置:
xml
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots><enabled>false</enabled></snapshots>
</repository>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<releases><enabled>false</enabled></releases>
</repository>
</repositories>
2.3 应用配置
在application.yml
中配置模型参数(以OpenAI为例):
yaml
spring:
ai:
openai:
api-key: sk-your-api-key-here # 替换为您的API密钥
base-url: https://api.openai.com/v1
chat:
options:
model: gpt-4 # 或 gpt-3.5-turbo
temperature: 0.7
timeout: 60s
如果使用本地Ollama模型,配置如下:
yaml
spring:
ai:
ollama:
base-url: http://localhost:11434 # Ollama服务地址
chat:
model: qwen2.5:7b # 本地部署的模型名称
3. 基础功能与快速入门
3.1 创建第一个AI接口
SpringAI的核心入口是ChatClient
接口,它提供了简化的大模型调用方法。
基础控制器实现:
java
@RestController
@RequiredArgsConstructor
public class ChatController {
private final ChatClient chatClient;
@GetMapping("/chat")
public String chat(@RequestParam String message) {
return chatClient.prompt()
.user(message)
.call()
.content();
}
}
启动应用后,访问http://localhost:8080/chat?message=介绍一下Spring Boot
即可获得AI响应。
3.2 使用专用模型客户端
除了通用的ChatClient
,SpringAI还为不同模型提供了专用客户端,如OpenAIChatModel
、OllamaChatModel
等,这些客户端提供更丰富的模型特定功能。
使用专用客户端的示例:
java
@RestController
public class TextGenerationController {
private final OllamaChatModel ollamaChatModel;
public TextGenerationController(OllamaChatModel ollamaChatModel) {
this.ollamaChatModel = ollamaChatModel;
}
// 普通输出
@GetMapping("/generate")
public String generate(@RequestParam String prompt) {
return ollamaChatModel.call(prompt);
}
// 流式输出(SSE)
@GetMapping(value = "/generateStream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> generateStream(@RequestParam String prompt) {
return ollamaChatModel.stream(prompt);
}
}
3.3 流式响应与实时输出
对于生成较长内容的场景,流式响应可以显著提升用户体验,避免长时间等待:
java
@GetMapping(value = "/stream-chat", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> streamChat(@RequestParam String prompt) {
return chatClient.prompt()
.user(prompt)
.stream()
.content();
}
前端可通过Server-Sent Events (SSE)或WebSocket接收流式响应,实现打字机效果。
4. 核心功能深入解析
4.1 提示工程与模板化
Prompt工程是AI应用的核心,SpringAI通过PromptTemplate
支持模板化提示,提升输出质量与一致性。
基础提示模板使用:
java
@GetMapping("/summary")
public String summarize(@RequestParam String text) {
String template = "请用一句话总结以下文本: {input}";
return chatClient.prompt()
.user(template, Map.of("input", text))
.call()
.content();
}
多角色提示模板: 对于复杂场景,可以定义系统角色和用户角色,实现更精确的控制:
java
@GetMapping("/translation")
public String translation(@RequestParam String text) {
String systemPrompt = """
你是一名专业的翻译专家,擅长技术文档翻译。
你的名字是TranslatePro,翻译时应保持专业性和准确性。
""";
String userPrompt = "将以下英文技术文档翻译成中文: {query}";
// 系统提示词
SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(systemPrompt);
Message systemMessage = systemPromptTemplate.createMessage();
// 用户提示词
PromptTemplate userPromptTemplate = new PromptTemplate(userPrompt);
Message userMessage = userPromptTemplate.createMessage(Map.of("query", text));
// 组合提示词
Prompt prompt = new Prompt(Arrays.asList(systemMessage, userMessage));
return chatClient.generate(prompt).content();
}
4.2 结构化输出
SpringAI支持将AI输出自动转换为Java对象,极大简化了数据处理流程:
定义数据结构:
java
@Data
public class WeatherInfo {
private String location;
private String forecast;
private int temperature;
private String advice;
}
获取结构化响应:
java
@GetMapping("/weather")
public WeatherInfo getWeather(@RequestParam String place) {
return chatClient.prompt()
.user("请提供{place}的天气情况,并返回结构化数据",
Map.of("place", place))
.call()
.entity(WeatherInfo.class);
}
4.3 上下文管理与多轮对话
实现多轮对话需要维护对话历史,SpringAI提供了ChatMemory
组件来管理对话上下文。
配置对话记忆:
java
@Configuration
public class AiConfig {
@Bean
public ChatMemory chatMemory() {
return new InMemoryChatMemory(50); // 保留最近50轮对话
}
}
使用记忆功能的对话服务:
java
@Service
public class AIService {
private final ChatClient chatClient;
private final ChatMemory chatMemory;
public AIService(ChatClient chatClient, ChatMemory chatMemory) {
this.chatClient = chatClient;
this.chatMemory = chatMemory;
}
public String chatWithMemory(String userInput, String sessionId) {
// 获取当前会话的对话历史
List<Message> history = chatMemory.get(sessionId);
// 构建新消息
Message userMessage = new UserMessage(userInput);
List<Message> messages = new ArrayList<>();
// 添加历史对话
if (history != null) {
messages.addAll(history);
}
messages.add(userMessage);
// 调用AI
Prompt prompt = new Prompt(messages);
ChatResponse response = chatClient.generate(prompt);
Message aiMessage = response.getResult().getOutput();
// 更新对话历史
messages.add(aiMessage);
chatMemory.put(sessionId, messages);
return aiMessage.getContent();
}
}
5. 高级应用场景
5.1 RAG(检索增强生成)
RAG技术结合本地知识库与大模型能力,实现基于私有数据的智能问答。SpringAI内置了向量数据库支持,可轻松实现RAG应用。
向量存储与检索配置:
java
@Configuration
public class RagConfig {
@Bean
public VectorStore vectorStore(EmbeddingModel embeddingModel) {
// 可使用多种向量存储:Milvus、PgVector、Redis等
InMemoryVectorStore vectorStore = new InMemoryVectorStore(embeddingModel);
return vectorStore;
}
@Bean
@DependsOn("vectorStore")
public VectorStoreRetriever vectorStoreRetriever(VectorStore vectorStore) {
return new VectorStoreRetriever(vectorStore);
}
}
知识库初始化与RAG查询:
java
@Service
public class KnowledgeBaseService {
private final VectorStore vectorStore;
private final ChatClient chatClient;
private final VectorStoreRetriever retriever;
public KnowledgeBaseService(VectorStore vectorStore, ChatClient chatClient,
VectorStoreRetriever retriever) {
this.vectorStore = vectorStore;
this.chatClient = chatClient;
this.retriever = retriever;
}
@PostConstruct
public void initKnowledgeBase() {
// 初始化知识库文档
List<Document> documents = List.of(
new Document("Spring是一个流行的Java开发框架,提供了依赖注入功能。"),
new Document("Spring AI支持OpenAI、Ollama等多种大语言模型。"),
new Document("Spring Boot简化了Spring应用的初始搭建和开发过程。")
);
vectorStore.add(documents);
}
public String askQuestion(String question) {
// 1. 检索相关文档
List<Document> relatedDocs = retriever.retrieve(question);
// 2. 构建增强提示
String context = relatedDocs.stream()
.map(Document::getContent)
.collect(Collectors.joining("\n\n"));
String enhancedPrompt = """
请根据以下上下文信息回答问题。如果上下文没有提供足够信息,请说明。
上下文:
{context}
问题:{question}
""";
return chatClient.prompt()
.user(enhancedPrompt,
Map.of("context", context, "question", question))
.call()
.content();
}
}
5.2 文档处理与ETL
SpringAI支持处理多种格式的文档(PDF、Word、HTML等),可提取文本内容供AI分析。
文档读取示例:
java
@Service
public class DocumentService {
public List<Document> processPdf(String filePath) {
// 使用Tika解析PDF文档
DocumentReader reader = new TikaDocumentReader();
return reader.read("file://" + filePath);
}
public String analyzeDocument(String filePath, String question) {
// 读取文档
List<Document> docs = processPdf(filePath);
// 组合文档内容
String content = docs.stream()
.map(Document::getContent)
.collect(Collectors.joining("\n"));
// 基于文档内容提问
return chatClient.prompt()
.user("根据以下文档内容回答问题:{question}\n\n文档内容:{content}",
Map.of("question", question, "content", content))
.call()
.content();
}
}
5.3 多模型混合调用
在企业级应用中,可能需要根据场景切换不同模型,SpringAI通过@Qualifier
注解支持多模型配置。
多模型配置:
yaml
spring:
ai:
openai:
api-key: ${OPENAI_API_KEY}
chat:
options:
model: gpt-4
azure:
openai:
api-key: ${AZURE_OPENAI_KEY}
endpoint: ${AZURE_OPENAI_ENDPOINT}
chat:
options:
model: gpt-35-turbo
ollama:
base-url: http://localhost:11434
chat:
model: qwen2.5:7b
模型路由服务:
java
@Service
public class ModelRouterService {
private final ChatClient openAIClient;
private final ChatClient azureClient;
private final ChatClient ollamaClient;
public ModelRouterService(@Qualifier("openAiChatClient") ChatClient openAIClient,
@Qualifier("azureChatClient") ChatClient azureClient,
@Qualifier("ollamaChatClient") ChatClient ollamaClient) {
this.openAIClient = openAIClient;
this.azureClient = azureClient;
this.ollamaClient = ollamaClient;
}
public String routeRequest(String query, ModelType modelType) {
ChatClient targetClient = switch (modelType) {
case OPENAI -> openAIClient;
case AZURE -> azureClient;
case OLLAMA -> ollamaClient;
};
return targetClient.prompt()
.user(query)
.call()
.content();
}
public enum ModelType {
OPENAI, AZURE, OLLAMA
}
}
6. 生产环境最佳实践
6.1 性能优化与监控
超时与重试配置:
yaml
spring:
ai:
openai:
chat:
options:
timeout: 30s
# 重试配置
spring:
cloud:
circuitbreaker:
retry:
instances:
ai-service:
maxAttempts: 3
backoff:
delay: 1000
multiplier: 2
监控与日志:
yaml
logging:
level:
org.springframework.ai: DEBUG
com.example.ai: INFO
6.2 异常处理与容错
java
@RestControllerAdvice
public class AiExceptionHandler {
@ExceptionHandler(AiClientException.class)
public ResponseEntity<ErrorResponse> handleAiException(AiClientException ex) {
ErrorResponse error = new ErrorResponse("AI_SERVICE_ERROR",
"AI服务暂时不可用,请稍后重试");
return ResponseEntity.status(503).body(error);
}
@ExceptionHandler(TimeoutException.class)
public ResponseEntity<ErrorResponse> handleTimeoutException(TimeoutException ex) {
ErrorResponse error = new ErrorResponse("REQUEST_TIMEOUT",
"请求超时,请稍后重试");
return ResponseEntity.status(504).body(error);
}
}
6.3 安全与隐私考虑
- API密钥管理:使用Vault或Kubernetes Secrets管理敏感信息
- 数据脱敏:在处理用户数据前进行脱敏处理
- 访问控制:实现基于角色的AI服务访问权限控制
- 审计日志:记录所有AI调用详情以满足合规要求
7. 总结与展望
SpringAI为Java开发者提供了强大而灵活的AI集成能力,大大降低了在Spring应用中添加智能功能的门槛。通过本文的介绍,您应该已经掌握了:
- 环境配置:如何正确配置SpringAI依赖和模型参数
- 基础用法:使用ChatClient进行简单的AI对话
- 高级特性:提示工程、结构化输出、上下文管理等核心功能
- 企业级应用:RAG、文档处理、多模型路由等实战场景