Spring AI:Java 开发者的AI 应用开发利器

Spring AI:Java 开发者的AI 应用开发利器

在生成式 AI 席卷行业的今天,Java 开发者常常面临一个尴尬的困境:想给现有 Spring 项目集成 AI 能力,却要被迫学习 Python 生态的 LangChain、LlamaIndex,还要反复适配 OpenAI、通义千问等不同模型的 API 格式——这就像用熟悉的工具拧陌生的螺丝,效率低下且容易出错。

Spring AI 的出现,彻底改变了这一现状。作为 Spring 生态官方推出的企业级 AI 框架,它将 Spring 一贯的“抽象解耦”“开箱即用”设计哲学延伸到 AI 领域,让 Java 开发者无需切换技术栈,就能用熟悉的 Spring 风格快速构建稳定、可扩展的 AI 应用。本文将从核心认知、实战案例到企业级实践,带您全面掌握 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 层,每一层都解决特定问题:

层级核心组件职责描述
外部服务层OpenAI/通义千问/Ollama 等实际提供 AI 能力的模型或向量数据库(如 Pinecone、Milvus)
数据支撑层VectorStore、DocumentReader处理企业数据:向量存储(存嵌入向量)、文档读取器(解析 PDF/Word)、文本分块器
模型抽象层ChatClient、EmbeddingModel统一 AI 能力接口:屏蔽不同模型的 API 差异,提供同步/流式调用能力
功能增强层PromptTemplate、RAG 编排提升 AI 效果:结构化提示、检索增强生成、工具调用(如调用企业 API)
应用层智能客服、文档问答等基于上述组件构建的业务应用

用一张简单的架构图理解:

在这里插入图片描述

1.3 与主流 AI 框架的对比

很多开发者会问:Spring AI 和 LangChain 有什么区别?下表清晰对比了核心差异:

框架语言支持Spring 集成度企业级特性适用场景
Spring AIJava★★★★★(原生)★★★★★(内置)Java 企业级 AI 应用、现有 Spring 项目升级
LangChainPython★★☆☆☆(需胶水代码)★★★☆☆(需扩展)Python 生态的 AI 原型开发、个人项目
LangChain4jJava★★★☆☆(部分支持)★★★☆☆(基础)简单 Java AI 应用,无需复杂企业特性
Dify低代码★★☆☆☆(API 对接)★★★★☆(部分)非技术人员快速搭建 AI 应用

结论:如果您是 Java 开发者,或需要将 AI 集成到 Spring 生态的企业级项目中,Spring AI 是最优选择。

二、实战上手:从 0 到 1 构建 Spring AI 应用

接下来,我们通过 3 个实战案例,从基础到进阶掌握 Spring AI:

  1. 基础案例:普通聊天(对接 OpenAI/通义千问)
  2. 进阶案例:流式聊天(实时输出,如 ChatGPT 打字效果)
  3. 企业级案例: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 依赖:

<<dependencies><!-- Spring AI OpenAI starter(自动配置 ChatClient) --><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-openai-spring-boot-starter</artifactId><version>1.0.0-M1</version><!-- 最新稳定版可查官网 --></dependency><!-- Spring Web(提供 HTTP 接口) --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency> </</dependencies>
步骤 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:测试接口
  1. 启动 Spring Boot 应用(主类加 @SpringBootApplication 即可)。
  2. 用浏览器或 Postman 访问:http://localhost:8080/ai/chat?question=用Java写HelloWorld

预期返回:

publicclassHelloWorld{publicstaticvoidmain(String[] args){System.out.println("Hello, World!");}}
拓展:切换到国内模型(通义千问)

如果无法访问 OpenAI,只需修改依赖和配置,无需改业务代码:

  1. 重新启动,访问相同接口,即可得到通义千问的回答——这就是 Spring AI 统一 API 的魅力!

修改配置文件:

# 通义千问配置 spring.ai.tongyi.api-key=your-tongyi-api-key # 替换成你的通义千问密钥 spring.ai.tongyi.chat.model=qwen-turbo # 通义千问的模型名称 

替换依赖为通义千问 starter:

<dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-tongyi-spring-boot-starter</artifactId><version>1.0.0-M1</version></dependency>

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{// 省略已有代码.../** * 流式聊天接口:实时输出 AI 回答 * 访问示例:http://localhost:8080/ai/chat/stream?question=解释Spring Boot自动配置原理 */@GetMapping( value ="/ai/chat/stream", produces =MediaType.TEXT_EVENT_STREAM_VALUE // 启用 SSE 流式输出)publicFlux<String>streamChat(@RequestParamString question){// 关键:用 stream() 替代 call(),返回 Flux<ChatResponse>return chatClient.prompt().user(question).stream()// 开启流式调用.map(response ->{// 提取每一段生成的内容return response.getResult().getOutput().getContent();});}}
步骤 2:测试流式效果
  1. 启动应用后,用浏览器访问 http://localhost:8080/ai/chat/stream?question=解释Spring Boot自动配置原理
  2. 你会看到页面上文字“逐字逐句”出现,就像 ChatGPT 的实时输出效果。

前端集成提示:如果要在前端页面展示,只需用 JavaScript 监听 SSE 事件:

<!DOCTYPEhtml><html><body><divid="answer"></div><script>// 建立 SSE 连接const eventSource =newEventSource("http://localhost:8080/ai/chat/stream?question=解释Spring Boot自动配置原理");// 监听消息推送 eventSource.onmessage=function(event){ document.getElementById("answer").innerText += event.data;};// 监听连接关闭 eventSource.onclose=function(){ console.log("流式连接已关闭");};</script></body></html>

2.4 企业级案例 3:RAG 文档问答(让 AI 读你的文档)

普通聊天的问题是 AI 知识可能过时,且无法回答企业内部文档(如产品手册、API 文档)的问题。RAG(检索增强生成) 则通过“先检索企业文档,再让 AI 基于文档回答”,解决了这一问题。

我们以“PDF 文档问答”为例,用 Spring AI + Pinecone(向量数据库)实现 RAG:

步骤 1:核心流程理解

RAG 分为“数据准备”和“问答”两个阶段:

  1. 数据准备阶段
    • 读取 PDF 文档 → 分割成小文本块(避免超过模型上下文限制)→ 用嵌入模型生成向量 → 存储到 Pinecone。
  2. 问答阶段
    • 用户提问 → 生成问题向量 → 从 Pinecone 检索相似文本块 → 把“相似文本块+用户问题”作为提示给 AI → AI 生成基于文档的回答。
步骤 2:添加依赖

除了之前的依赖,还需引入 PDF 解析和 Pinecone 向量存储依赖:

<<dependencies><!-- 省略已有依赖... --><!-- PDF 文档解析 --><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-pdf-document-reader</artifactId><version>1.0.0-M1</version></dependency><!-- Pinecone 向量存储 --><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-pinecone-store-spring-boot-starter</artifactId><version>1.0.0-M1</version></dependency> </</dependencies>
步骤 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<Document> documents = pdfReader.read();// 2. 分割文本块(每块 500 个token,重叠 50 个token,避免语义断裂)TextSplitter textSplitter =newTokenTextSplitter(500,50);List<Document> 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){// 1. 检索相似文本块(取 top3 最相关的)List<Document> similarDocs = vectorStore.similaritySearch(question,3);// 2. 构建提示:将相似文档内容和用户问题组合String prompt =String.format(""" 基于以下文档内容回答用户问题,不要编造信息: 文档内容:%s 用户问题:%s """, similarDocs.stream().map(Document::getContent).reduce((a, b)-> a +"\n"+ b).orElse(""), question);// 3. 调用 AI 生成回答return chatClient.prompt().user(prompt).call().content();}}
步骤 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 效果
  1. 先调用初始化接口:http://localhost:8080/ai/rag/init,等待 PDF 处理完成。
  2. 再调用问答接口:http://localhost:8080/ai/rag/chat?question=Spring AI 如何集成向量存储
  3. 预期返回:AI 会基于你上传的 PDF 文档内容,准确回答问题,而不是依赖通用知识。

三、企业级实践:让 Spring AI 应用更稳定、更安全

完成基础开发后,还需要考虑生产环境的关键问题:

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 调用的次数、响应时间、错误率:

  1. 启动后访问 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 依赖:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><groupId>io.micrometer</groupId><artifactId>micrometer-registry-prometheus</artifactId></dependency>

3.3 性能优化:向量缓存与批量处理

  • 向量缓存:频繁查询相同问题时,缓存检索结果(用 Redis),避免重复调用向量数据库。
  • 批量处理:若需处理大量文档,用 vectorStore.addAll() 批量添加文本块,减少网络请求次数。
  • 模型选择:非关键场景用轻量模型(如 gpt-3.5-turbo、qwen-turbo),降低延迟和成本。

四、总结:Spring AI 开启 Java 开发者的 AI 新时代

Spring AI 不是简单地“封装 AI API”,而是将 AI 能力与 Spring 生态深度融合,让 Java 开发者能以最低成本拥抱生成式 AI。它的核心价值在于:

  • 降低门槛:用熟悉的 Spring 风格开发 AI 应用,无需学习新语言或框架。
  • 提升效率:统一 API 抽象、自动配置、内置企业级特性,减少重复开发。
  • 保障稳定:支持可观测性、安全、降级,满足生产环境要求。

对于 Java 开发者而言,Spring AI 就像一把“瑞士军刀”——无论是简单的聊天功能,还是复杂的 RAG 文档问答,都能快速实现。未来,随着 Spring AI 对多模态(图像、语音)、Agent 能力的进一步增强,它将成为企业级 AI 应用开发的事实标准。

现在就动手吧:从一个简单的聊天接口开始,逐步探索 RAG、工具调用等高级特性,让你的 Spring 项目拥有智能大脑!

Read more

Apache IoTDB(5):深度解析时序数据库 IoTDB 在 AINode 模式单机和集群的部署与实践

Apache IoTDB(5):深度解析时序数据库 IoTDB 在 AINode 模式单机和集群的部署与实践

引言 Apache IoTDB 设计之初就专为物联网(IoT)场景而生,旨在提供一个集高性能数据写入、海量数据存储、低延迟分析查询于一体的一站式解决方案。 Apache IoTDB 时序数据库【系列篇章】: No.文章地址(点击进入)1Apache IoTDB(1):时序数据库介绍与单机版安装部署指南2Apache IoTDB(2):时序数据库 IoTDB 集群安装部署的技术优势与适用场景分析3Apache IoTDB(3):时序数据库 IoTDB Docker部署从单机到集群的全场景部署与实践指南4Apache IoTDB(4):深度解析时序数据库 IoTDB 在Kubernetes 集群中的部署与实践指南 一、IoTDB——AINode介绍 AINode 是 IoTDB 在 ConfigNode、DataNode 后提供的第三种内生节点,通过与 IoTDB 集群的 DataNode、

By Ne0inhk
wsl2下Ubuntu获得完整桌面体验(WSLg+KDE)

wsl2下Ubuntu获得完整桌面体验(WSLg+KDE)

wsl2下Ubuntu获得完整桌面体验(WSLg+KDE) 不使用Xvnc或Xorg,本教程参考 Full desktop shell in WSL2 using WSLg (XWayland)-github 无需安装其他软件,全程在wsl2中实现 环境 windows10专业版22H2 wsl:2.6.3.0 Ubuntu:24.04.3 LTS KDE:5(XWayland只支持这个) 前言 很久以前就在想要是能同时操作Windows和Linux而不用双系统就好了,现在通过WSL2实现了体验不错的双桌面系统,至少在我的笔记本上,wsl的体验要比在VBox或者VM强,还有显卡直通,要舒服的多。 参考了Github上的教程,但是他只做了GNOME桌面的教程,由于我的电脑分辨率是非整数倍缩放,而GNOME对于非整数倍缩放的支持异常糟糕,而且打开设置竟然要10秒以上,太臃肿了,所以我换成了KDE,写下这篇文章。 需要注意的是一旦使用了这个教程,WSLg将全权被桌面接管,无法体验Windows与linux那种无缝交互的感觉,即应用直接投影到桌面,

By Ne0inhk
Ubuntu_24.04 安装OpenClaw教程

Ubuntu_24.04 安装OpenClaw教程

认识OpenClaw 官网:https://openclaw.ai/ https://docs.openclaw.ai/start/getting-started 安装OpenClaw curl -fsSL https://openclaw.ai/install.sh | bash 安装完成 配置命令 在终端输入: openclaw onboard 选择Yes 选择QuickStart 因为前面配置过,所以提示是否用原来的配置信息,可以使用Reset进行重置 选择模型: 根据自己的需要进行选择, 这里要特别注意一个问题,openClaw对上下文有要求,默认最小是16000Token,要不然后面安装的时候会报下图的错误信息 选择Qwen一直在waiting 如果要使用其他的模型,选择Custom Provider 如果选择DeepSeek,baseURL输入:https://api.deepseek.com/v1 然后输入API-KEY:sk-******* model输入:

By Ne0inhk
20-OpenClaw定时任务与自动化工作流

20-OpenClaw定时任务与自动化工作流

OpenClaw 定时任务与自动化工作流 ✦ 免费专栏|全套教程: OpenClaw 从入门到精通 ✦ 开篇总览|最新目录: 最新 OpenClaw 教程|从入门到精通|AI 智能助手 / 自动化 / Skills 实战(原 Clawdbot/Moltbot) 本文档详细介绍 OpenClaw 的定时任务和自动化功能,包括 Cron 配置、Heartbeat 心跳机制以及自动化工作流的设计与实践。 目录 1. 概述 2. Cron 定时任务配置 3. Heartbeat 心跳机制 4. 自动化工作流设计 5. 实战案例 6. 最佳实践与注意事项 1. 概述 OpenClaw 提供了强大的定时任务和自动化能力,让 AI 助手能够主动执行任务,

By Ne0inhk