SpringAI的使用
Spring AI 是 Spring 官方推出的 AI 应用开发框架,旨在简化 AI 模型(如大语言模型、嵌入模型等)与 Spring 生态的集成,提供统一的 API 抽象,支持多类 AI 服务(如 OpenAI、Azure OpenAI、Hugging Face 等)和向量存储(如 Redis、Milvus 等),让开发者更专注于业务逻辑而非 AI 服务的底层调用细节。
一、核心概念
在使用 Spring AI 前,需理解几个核心概念:
- 模型(Model):AI 服务的抽象(如大语言模型、嵌入模型),Spring AI 提供统一接口,屏蔽不同厂商(如 OpenAI、Anthropic)的差异。
- 提示(Prompt):输入给模型的指令或问题,由提示文本(Prompt Text) 和系统消息(System Message) 组成(系统消息用于定义模型的行为)。
- 响应(Response):模型返回的结果,包含生成的文本、元数据(如令牌数、耗时)等。
- 提示模板(Prompt Template):动态生成提示的模板,支持变量填充(类似模板引擎),适用于需要动态参数的场景。
- 函数调用(Function Calling):模型根据问题自动调用外部工具(如数据库查询、API 调用)的能力,Spring AI 提供工具注册和调用机制。
- 向量存储(Vector Store):存储嵌入向量(文本的数值表示)的组件,用于相似性检索(核心用于 RAG 场景)。
二、环境搭建
Spring AI 基于 Spring Boot,需通过 starters 引入依赖。目前最新稳定版为 0.8.1
(需注意版本兼容性)。
1. 依赖配置(Maven)
以集成 OpenAI 为例,在 pom.xml
中添加:
<!-- Spring Boot 基础依赖 -->
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.2.0</version><relativePath/>
</parent><dependencies><!-- Spring AI OpenAI 集成 --><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-openai-spring-boot-starter</artifactId><version>0.8.1</version></dependency><!-- Web 依赖(可选,用于接口暴露) --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
</dependencies><!-- Spring AI 仓库(部分版本需指定) -->
<repositories><repository><id>spring-milestones</id><name>Spring Milestones</name><url>https://repo.spring.io/milestone</url><snapshots><enabled>false</enabled></snapshots></repository>
</repositories>
2. 配置 AI 服务密钥
在 application.yml
中配置 OpenAI 的 API 密钥(其他服务如 Azure OpenAI、Hugging Face 配置类似):
spring:ai:openai:api-key: "你的OpenAI API密钥" # 从 OpenAI 控制台获取# 可选:指定模型(默认使用 gpt-3.5-turbo)chat:model: gpt-3.5-turbo# 超时配置timeout: 30000
三、基础使用:调用大语言模型(LLM)
Spring AI 对大语言模型的调用封装在 ChatClient
接口中,通过注入即可使用。
1. 简单文本对话
import org.springframework.ai.chat.ChatClient;
import org.springframework.ai.chat.ChatResponse;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.chat.prompt.SystemMessage;
import org.springframework.ai.chat.prompt.UserMessage;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;@RestController
public class ChatController {// 注入 ChatClient(由 Spring AI 自动配置,基于 openai starter)private final ChatClient chatClient;public ChatController(ChatClient chatClient) {this.chatClient = chatClient;}@GetMapping("/chat")public String chat(@RequestParam String question) {// 1. 构建提示(系统消息 + 用户问题)Prompt prompt = new Prompt(new SystemMessage("你是一个友好的助手,用简洁的语言回答问题。"),new UserMessage(question));// 2. 调用模型ChatResponse response = chatClient.call(prompt);// 3. 返回生成的内容return response.getResult().getOutput().getContent();}
}
启动应用后,访问 http://localhost:8080/chat?question=Spring AI 是什么
,即可得到模型的回答。
2. 使用提示模板(动态生成提示)
当提示需要动态参数(如用户输入、数据库查询结果)时,可使用 PromptTemplate
:
import org.springframework.ai.chat.prompt.PromptTemplate;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.chat.ChatClient;
import org.springframework.stereotype.Service;import java.util.HashMap;
import java.util.Map;@Service
public class RecommendService {private final ChatClient chatClient;public RecommendService(ChatClient chatClient) {this.chatClient = chatClient;}// 根据用户兴趣推荐书籍public String recommendBooks(String userInterest) {// 1. 定义提示模板(使用 {variable} 作为占位符)String template = "用户喜欢 {interest},请推荐 3 本相关的经典书籍,每本简要说明理由。";// 2. 填充变量Map<String, Object> variables = new HashMap<>();variables.put("interest", userInterest);// 3. 生成 PromptPromptTemplate promptTemplate = new PromptTemplate(template, variables);Prompt prompt = promptTemplate.create();// 4. 调用模型return chatClient.call(prompt).getResult().getOutput().getContent();}
}
四、高级特性:函数调用(Function Calling)
函数调用允许模型根据问题自动触发外部工具(如查询数据库、调用天气 API),适用于需要模型结合外部数据回答的场景。
1. 定义工具函数
首先定义一个工具类,用 @Tool
注解标记可被模型调用的方法:
import org.springframework.ai.core.Tool;
import org.springframework.stereotype.Component;import java.time.LocalDate;
import java.time.format.DateTimeFormatter;@Component
public class WeatherTool {// 模拟查询天气的工具函数@Tool("查询指定城市的天气,参数为城市名称(如北京)")public String getWeather(String city) {// 实际场景中可调用第三方天气 APIString date = LocalDate.now().format(DateTimeFormatter.ISO_DATE);return String.format("城市:%s,日期:%s,天气:晴朗,温度:25℃", city, date);}
}
2. 配置函数调用客户端
需使用 FunctionCallingChatClient
替代基础 ChatClient
,并注册工具:
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.functions.FunctionCallingAdvisor;
import org.springframework.ai.openai.OpenAiChatModel;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class ChatConfig {// 注册工具并创建支持函数调用的 ChatClient@Beanpublic ChatClient chatClient(OpenAiChatModel openAiChatModel, WeatherTool weatherTool) {return ChatClient.builder(openAiChatModel).withAdvisor(new FunctionCallingAdvisor(weatherTool)) // 注册工具.build();}
}
3. 使用函数调用
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;@RestController
public class WeatherController {private final ChatClient chatClient;public WeatherController(ChatClient chatClient) {this.chatClient = chatClient;}@GetMapping("/weather")public String getWeatherAnswer(@RequestParam String question) {// 模型会自动判断是否需要调用工具String response = chatClient.prompt().user(question).call().content();return response;}
}
当访问 http://localhost:8080/weather?question=上海今天的天气怎么样
时,模型会自动调用 WeatherTool.getWeather("上海")
,并返回工具的结果。
五、向量存储与 RAG 应用
RAG(检索增强生成)是通过检索外部知识库(如文档、数据库)来增强模型回答准确性的技术,核心依赖向量存储。Spring AI 支持 Redis、Milvus、Pinecone 等向量存储。
1. 集成 Redis 向量存储
步骤 1:添加依赖
<dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-redis-spring-boot-starter</artifactId><version>0.8.1</version>
</dependency>
步骤 2:配置 Redis
spring:redis:host: localhostport: 6379ai:embedding:openai: # 使用 OpenAI 的嵌入模型生成向量api-key: "你的OpenAI API密钥"redis:vector-store:index-name: knowledge_index # 向量存储的索引名
2. 存储与检索向量
import org.springframework.ai.document.Document;
import org.springframework.ai.embedding.EmbeddingClient;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.stereotype.Service;import java.util.List;@Service
public class KnowledgeService {private final VectorStore vectorStore;private final EmbeddingClient embeddingClient;public KnowledgeService(VectorStore vectorStore, EmbeddingClient embeddingClient) {this.vectorStore = vectorStore;this.embeddingClient = embeddingClient;}// 向向量存储添加文档(如知识库内容)public void addKnowledge() {// 模拟知识库文档Document doc1 = new Document("Spring AI 是 Spring 生态的 AI 开发框架,简化了 AI 模型的集成。");Document doc2 = new Document("Spring AI 支持 OpenAI、Azure OpenAI 等多种 AI 服务,提供统一 API。");// 存储文档(内部会自动调用嵌入模型生成向量)vectorStore.add(List.of(doc1, doc2));}// 检索与问题相关的文档public List<Document> searchRelatedDocs(String question) {// 检索相似度最高的 2 个文档return vectorStore.similaritySearch(question, 2);}
}
3. 构建 RAG 应用
结合检索到的文档和模型生成回答:
import org.springframework.ai.chat.ChatClient;
import org.springframework.ai.document.Document;
import org.springframework.stereotype.Service;import java.util.List;
import java.util.stream.Collectors;@Service
public class RagService {private final KnowledgeService knowledgeService;private final ChatClient chatClient;public RagService(KnowledgeService knowledgeService, ChatClient chatClient) {this.knowledgeService = knowledgeService;this.chatClient = chatClient;}public String answerWithKnowledge(String question) {// 1. 检索相关文档List<Document> docs = knowledgeService.searchRelatedDocs(question);// 2. 构建提示(将文档作为上下文)String context = docs.stream().map(Document::getContent).collect(Collectors.joining("\n"));String promptText = String.format("基于以下上下文回答问题:\n%s\n问题:%s", context, question);// 3. 调用模型生成回答return chatClient.call(promptText);}
}
六、切换 AI 服务
Spring AI 的抽象层使切换不同 AI 服务非常简单,只需修改依赖和配置:
-
切换到 Azure OpenAI:
替换依赖为spring-ai-azure-openai-spring-boot-starter
,并修改配置:spring:ai:azure:openai:api-key: "你的Azure API密钥"endpoint: "你的Azure endpoint(如https://xxx.openai.azure.com/)"deployment-name: "你的部署名(如gpt-35-turbo)"
-
切换到 Hugging Face:
替换依赖为spring-ai-huggingface-spring-boot-starter
,配置 API 密钥和模型:spring:ai:huggingface:api-key: "你的Hugging Face API密钥"chat:model: "mistralai/Mistral-7B-Instruct-v0.1"
总结
Spring AI 核心价值在于:
- 统一抽象:屏蔽不同 AI 服务的差异,切换服务只需改配置;
- 简化集成:通过 Spring Boot starters 快速接入 AI 模型和向量存储;
- 增强能力:内置提示模板、函数调用、RAG 等高级特性,降低 AI 应用开发门槛。
更多细节可参考 Spring AI 官方文档,需注意其仍在快速迭代中,建议使用稳定版本。