在生成式 AI 席卷行业的今天,Java 开发者常常面临一个尴尬的困境:想给现有 Spring 项目集成 AI 能力,却要被迫学习 Python 生态的 LangChain、LlamaIndex,还要反复适配 OpenAI、通义千问等不同模型的 API 格式——这就像用熟悉的工具拧陌生的螺丝,效率低下且容易出错。
而 Spring AI 的出现,彻底改变了这一现状。作为 Spring 生态官方推出的企业级 AI 框架,它将 Spring 一贯的“抽象解耦”“开箱即用”设计哲学延伸到 AI 领域,让 Java 开发者无需切换技术栈,就能用熟悉的 Spring 风格快速构建稳定、可扩展的 AI 应用。本文将从核心认知、实战案例到企业级实践,带您全面掌握 Spring AI。
在动手之前,我们先搞懂一个关键问题:Spring AI 不是“另一个 AI 模型”,而是“连接企业系统与 AI 模型的桥梁”。它的核心价值,就是解决 Java 开发者集成 AI 时的三大痛点:
1.1 为什么需要 Spring AI?
- 痛点1:模型API碎片化:OpenAI 的 ChatCompletion、通义千问的 ChatCompletions、Gemini 的 GenerateContent,每个模型的 API 格式、参数名、返回结构都不同,切换模型就要重构代码。
- 痛点2:与 Spring 生态脱节:传统 AI 框架(如 LangChain)是 Python 生态的产物,集成到 Spring Boot 项目中需要大量“胶水代码”,无法利用 Spring 的依赖注入、自动配置、安全等特性。
- 痛点3:企业级能力缺失:生产环境需要的 API 密钥安全管理、调用监控、重试降级、向量存储集成等,传统框架要么不支持,要么需要手动实现。
Spring AI 则针对性解决这些问题:
- 统一 API 抽象:用
ChatClient 对接所有聊天模型,EmbeddingModel 对接所有嵌入模型,切换模型只需改配置。
- 原生 Spring 体验:支持自动配置(
@EnableAutoConfiguration)、依赖注入,与 Spring Boot、Spring Cloud 无缝集成。
- 企业级特性内置:提供可观测性(Micrometer 监控)、安全(密钥加密)、工具调用、RAG 流程编排等生产级能力。
1.2 核心组件与分层架构
Spring AI 的架构遵循“分层职责分离”原则,从下到上可分为 4 层,每一层都解决特定问题:
1.3 与主流 AI 框架的对比
很多开发者会问:Spring AI 和 LangChain 有什么区别?下表清晰对比了核心差异:
结论:如果您是 Java 开发者,或需要将 AI 集成到 Spring 生态的企业级项目中,Spring AI 是最优选择。
接下来,我们通过 3 个实战案例,从基础到进阶掌握 Spring AI:
- 基础案例:普通聊天(对接 OpenAI/通义千问)
- 进阶案例:流式聊天(实时输出,如 ChatGPT 打字效果)
- 企业级案例:RAG 文档问答(结合向量存储,让 AI 读你的文档)
2.1 环境准备
首先确认开发环境满足以下要求:
- JDK 17+(Spring AI 最低要求,推荐 JDK 17)
- Spring Boot 3.2+(需与 Spring AI 版本兼容,本文用 3.2.5)
- Maven 3.8+ 或 Gradle 8.0+
- 一个 AI 模型的 API 密钥(如 OpenAI API Key、通义千问 API Key)
2.2 基础案例 1:普通聊天(对接 OpenAI)
需求:构建一个 HTTP 接口,接收用户问题,返回 AI 的回答。
步骤 1:添加依赖
在 pom.xml 中引入 Spring AI OpenAI starter 和 Spring Web 依赖:
<
org.springframework.ai
spring-ai-openai-spring-boot-starter
1.0.0-M1
org.springframework.boot
spring-boot-starter-web
步骤 2:配置 API 密钥
在 src/main/resources/application.properties 中配置 OpenAI 密钥和模型:
# OpenAI API 配置 spring.ai.openai.api-key=sk-your-openai-api-key # 替换成你的密钥 spring.ai.openai.chat.model=gpt-3.5-turbo # 模型名称 spring.ai.openai.chat.temperature=0.7 # 创造性:0(严谨)~1(灵活)
步骤 3:编写 Controller
利用 Spring AI 自动注入的 ChatClient,编写一个简单的 HTTP 接口:
importorg.springframework.ai.chat.client.ChatClient;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.RequestParam;importorg.springframework.web.bind.annotation.RestController;@RestControllerpublicclassAIChatController{// Spring AI 自动注入 ChatClient,无需手动创建privatefinalChatClient chatClient;// 构造函数注入(Spring 推荐方式)publicAIChatController(ChatClient chatClient){this.chatClient = chatClient;}/ * 普通聊天接口:接收问题,返回 AI 回答 * 访问示例:http://localhost:8080/ai/chat?question=用Java写HelloWorld */@GetMapping(“/ai/chat”)publicStringchat(@RequestParamString question){// 调用 AI:链式调用,简洁明了return chatClient.prompt()// 开始构建提示.user(question)// 设置用户问题.call()// 同步调用 AI.content();// 获取回答内容}}
步骤 4:测试接口
- 启动 Spring Boot 应用(主类加
@SpringBootApplication即可)。 - 用浏览器或 Postman 访问:
http://localhost:8080/ai/chat?question=用Java写HelloWorld。
预期返回:
publicclassHelloWorld{publicstaticvoidmain(String[] args){System.out.println(“Hello, World!”);}}
拓展:切换到国内模型(通义千问)
如果无法访问 OpenAI,只需修改依赖和配置,无需改业务代码:
- 重新启动,访问相同接口,即可得到通义千问的回答——这就是 Spring AI 统一 API 的魅力!
修改配置文件:
# 通义千问配置 spring.ai.tongyi.api-key=your-tongyi-api-key # 替换成你的通义千问密钥 spring.ai.tongyi.chat.model=qwen-turbo # 通义千问的模型名称
替换依赖为通义千问 starter:
org.springframework.ai
spring-ai-tongyi-spring-boot-starter
1.0.0-M1
2.3 进阶案例 2:流式聊天(实时输出)
普通聊天需要等待 AI 生成完整回答后才返回,体验不佳。流式聊天则像 ChatGPT 一样,AI 生成一句就输出一句,响应更快。
Spring AI 用 响应式编程(Flux) 实现流式输出,步骤如下:
步骤 1:修改 Controller 接口
在原有 Controller 中添加流式接口,注意设置 produces = MediaType.TEXT_EVENT_STREAM_VALUE(SSE 协议,支持服务器实时推送):
importorg.springframework.http.MediaType;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.RequestParam;importreactor.core.publisher.Flux;@RestControllerpublicclassAIChatController);}}
步骤 2:测试流式效果
- 启动应用后,用浏览器访问
http://localhost:8080/ai/chat/stream?question=解释Spring Boot自动配置原理。 - 你会看到页面上文字“逐字逐句”出现,就像 ChatGPT 的实时输出效果。
前端集成提示:如果要在前端页面展示,只需用 JavaScript 监听 SSE 事件:
2.4 企业级案例 3:RAG 文档问答(让 AI 读你的文档)
普通聊天的问题是 AI 知识可能过时,且无法回答企业内部文档(如产品手册、API 文档)的问题。RAG(检索增强生成) 则通过“先检索企业文档,再让 AI 基于文档回答”,解决了这一问题。
我们以“PDF 文档问答”为例,用 Spring AI + Pinecone(向量数据库)实现 RAG:
步骤 1:核心流程理解
RAG 分为“数据准备”和“问答”两个阶段:
- 数据准备阶段:
- 读取 PDF 文档 → 分割成小文本块(避免超过模型上下文限制)→ 用嵌入模型生成向量 → 存储到 Pinecone。
- 问答阶段:
- 用户提问 → 生成问题向量 → 从 Pinecone 检索相似文本块 → 把“相似文本块+用户问题”作为提示给 AI → AI 生成基于文档的回答。
步骤 2:添加依赖
除了之前的依赖,还需引入 PDF 解析和 Pinecone 向量存储依赖:
<
org.springframework.ai
spring-ai-pdf-document-reader
1.0.0-M1
org.springframework.ai
spring-ai-pinecone-store-spring-boot-starter
1.0.0-M1
步骤 3:配置 Pinecone
在 application.properties 中添加 Pinecone 配置(需先在 Pinecone 官网创建索引):
# Pinecone 配置 spring.ai.pinecone.api-key=your-pinecone-api-key # 你的 Pinecone 密钥 spring.ai.pinecone.environment=gcp-starter # Pinecone 环境(如 gcp-starter) spring.ai.pinecone.index-name=spring-ai-demo # 你的 Pinecone 索引名 # 嵌入模型配置(用 OpenAI 的嵌入模型生成向量) spring.ai.openai.embedding.model=text-embedding-3-small spring.ai.openai.embedding.dimensions=1536 # 向量维度(需与 Pinecone 索引一致)
步骤 4:编写 RAG 服务类
创建 RagService,封装“数据准备”和“问答”逻辑:
importorg.springframework.ai.document.Document;importorg.springframework.ai.embedding.EmbeddingClient;importorg.springframework.ai.openai.OpenAiEmbeddingClient;importorg.springframework.ai.pinecone.PineconeVectorStore;importorg.springframework.ai.reader.pdf.PdfDocumentReader;importorg.springframework.ai.transformer.splitter.TextSplitter;importorg.springframework.ai.transformer.splitter.TokenTextSplitter;importorg.springframework.ai.chat.client.ChatClient;importorg.springframework.beans.factory.annotation.Value;importorg.springframework.core.io.Resource;importorg.springframework.stereotype.Service;importjava.util.List;@ServicepublicclassRagService{privatefinalPineconeVectorStore vectorStore;privatefinalChatClient chatClient;privatefinalEmbeddingClient embeddingClient;// 注入 PDF 资源(将你的 PDF 放在 src/main/resources/docs/ 目录下)@Value(“classpath:docs/spring-ai-manual.pdf”)privateResource pdfResource;// 构造函数注入依赖publicRagService(PineconeVectorStore vectorStore,ChatClient chatClient,EmbeddingClient embeddingClient){this.vectorStore = vectorStore;this.chatClient = chatClient;this.embeddingClient = embeddingClient;}/ * 数据准备:读取 PDF → 分块 → 生成向量 → 存入 Pinecone */publicvoidprepareDocumentData(){try{// 1. 读取 PDF 文档PdfDocumentReader pdfReader =newPdfDocumentReader(pdfResource);List
documents = pdfReader.read();// 2. 分割文本块(每块 500 个token,重叠 50 个token,避免语义断裂)TextSplitter textSplitter =newTokenTextSplitter(500,50);List
splitDocuments = textSplitter.split(documents);// 3. 将文本块存入 Pinecone(自动生成向量) vectorStore.add(splitDocuments);System.out.println(“PDF 文档处理完成,共存入 “+ splitDocuments.size()+” 个文本块”);}catch(Exception e){thrownewRuntimeException(“PDF 文档处理失败”, e);}}/ * RAG 问答:基于 Pinecone 检索的文档回答问题
/publicStringragChat(String question)}
步骤 5:编写 RAG 接口
在 Controller 中添加 RAG 相关接口:
importorg.springframework.web.bind.annotation.;@RestController@RequestMapping(“/ai/rag”)publicclassRagController{privatefinalRagService ragService;publicRagController(RagService ragService){this.ragService = ragService;}/ * 初始化文档数据:仅需调用一次 * 访问示例:http://localhost:8080/ai/rag/init */@GetMapping(“/init”)publicStringinitDocument(){ ragService.prepareDocumentData();return”文档初始化完成!”;}/ * RAG 问答接口:基于 PDF 文档回答问题 * 访问示例:http://localhost:8080/ai/rag/chat?question=Spring AI 如何集成向量存储 */@GetMapping(“/chat”)publicStringragChat(@RequestParamString question){return ragService.ragChat(question);}}
步骤 6:测试 RAG 效果
- 先调用初始化接口:
http://localhost:8080/ai/rag/init,等待 PDF 处理完成。 - 再调用问答接口:
http://localhost:8080/ai/rag/chat?question=Spring AI 如何集成向量存储。 - 预期返回:AI 会基于你上传的 PDF 文档内容,准确回答问题,而不是依赖通用知识。
完成基础开发后,还需要考虑生产环境的关键问题:
3.1 API 密钥安全管理
硬编码 API 密钥(如 spring.ai.openai.api-key=xxx)存在泄露风险,企业级项目建议:
- 方式2:Spring Cloud Config 集中管理:将密钥存储在配置中心(如 Nacos、Apollo),动态刷新配置。
- 方式3:加密存储:用 Spring Cloud Config Server + JCE 加密配置文件中的敏感信息。
方式1:环境变量注入:在服务器上设置环境变量 OPENAI_API_KEY,配置文件中引用:
spring.ai.openai.api-key=${OPENAI_API_KEY:default-key} # 冒号后是默认值(可选)
3.2 可观测性:监控 AI 调用
Spring AI 内置了 Micrometer 监控支持,可跟踪 AI 调用的次数、响应时间、错误率:
- 启动后访问
http://localhost:8080/actuator/prometheus,即可看到 AI 调用的监控指标(如spring_ai_chat_client_calls_seconds_count)。
配置监控端点:
# 暴露 Prometheus 端点 management.endpoints.web.exposure.include=prometheus,health,info management.metrics.export.prometheus.enabled=true
添加 Actuator 依赖:
org.springframework.boot
spring-boot-starter-actuator
io.micrometer
micrometer-registry-prometheus
3.3 性能优化:向量缓存与批量处理
- 向量缓存:频繁查询相同问题时,缓存检索结果(用 Redis),避免重复调用向量数据库。
- 批量处理:若需处理大量文档,用
vectorStore.addAll()批量添加文本块,减少网络请求次数。 - 模型选择:非关键场景用轻量模型(如 gpt-3.5-turbo、qwen-turbo),降低延迟和成本。
Spring AI 不是简单地“封装 AI API”,而是将 AI 能力与 Spring 生态深度融合,让 Java 开发者能以最低成本拥抱生成式 AI。它的核心价值在于:
- 降低门槛:用熟悉的 Spring 风格开发 AI 应用,无需学习新语言或框架。
- 提升效率:统一 API 抽象、自动配置、内置企业级特性,减少重复开发。
- 保障稳定:支持可观测性、安全、降级,满足生产环境要求。
对于 Java 开发者而言,Spring AI 就像一把“瑞士军刀”——无论是简单的聊天功能,还是复杂的 RAG 文档问答,都能快速实现。未来,随着 Spring AI 对多模态(图像、语音)、Agent 能力的进一步增强,它将成为企业级 AI 应用开发的事实标准。
现在就动手吧:从一个简单的聊天接口开始,逐步探索 RAG、工具调用等高级特性,让你的 Spring 项目拥有智能大脑!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/259613.html