Spring AI框架快速入门

​前言:在经历了八个里程碑式的版本之后(M1~M8),Spring AI 1.0 正式版本,终于在 2025 年 5 月 20 日正式发布,这是另一个新高度的里程碑式的版本,标志着 Spring 生态系统正式全面拥抱人工智能技术,并且意味着 Spring AI 将会给企业带来稳定 API 支持。Spring AI​​ 是 Spring 生态中一个新兴的子项目,旨在简化人工智能(尤其是生成式 AI)在 Java 应用中的集成。它提供了一套标准化 API 和工具,帮助开发者快速接入LLM大语言模型、向量数据库等 AI 组件,同时与 Spring 的核心特性(如依赖注入、响应式编程)无缝结合。


一、​​Spring AI 主要解决哪些痛点?

Spring AI 新架构设计主要旨在解决以下3个关键问题:

1.1、 统一的 API 抽象,隐藏底层复杂性

SpringAI 的核心价值在于统一不同 AI 供应商的差异化 API。无论是 OpenAI、Qwen还是 DeepSeek,开发者都通过同一套 ChatClient 接口进行操作。这种设计完美契合六边形架构思想,将 AI 能力作为可插拔的端口(Port)接入系统,业务核心逻辑则通过适配器(Adapter)与具体实现解耦。

public interface ChatClient { ChatResponse call(ChatRequest request); 
Flux<ChatResponse> stream(ChatRequest request); }

 Spring AI 支持市面上几乎所有主流的大模型提供商(包括聊天模型和图像生成模型)以及向量数据库。统一接口支持多种 AI 服务无论你使用的是 OpenAI 的 GPT、深度求索的 DeepSeek、谷歌的 Gemini、Anthropic 的 Claude,还是 Hugging Face 上的开源模型,Spring AI 都旨在提供一套统一且可移植的 API,让你能够轻松调用。对于向量数据库,比如:Milvus、Pinecone、Redis、PGVector 等,它同样提供了统一的 API 和查询方法。这样,你的代码就可以更灵活地在不同的 AI 服务和数据库之间切换,不会被某个特定供应商锁定。

1.2、简化 AI 应用开发,广泛支持模型、向量数据库、RAG和MCP等

构建一个稍微复杂的 AI 应用,集成向量数据库(如 Pinecone、Milvus),支持 RAG(检索增强生成)场景。比如:RAG(检索增强生成),通常需要涉及数据加载、分割、向量化、存储、检索、调用大语言模型(LLM)等多个步骤。Spring AI 提供了 ETL 框架、ChatClient、VectorStore 等组件和抽象,大大简化了这些流程的实现。对话管理​,封装 ChatClient 和 ChatModel,管理上下文、消息历史、提示词模板。

1.3、配置即连接,深度集成 Spring 生态

这是 Spring 的强项,支持 Spring Boot 自动配置、Spring WebFlux 响应式调用。Spring AI 提供了各种 Spring Boot Starter,使得配置和集成 AI 模型、向量数据库变得非常简单,遵循“约定优于配置”的原则,即开箱即用,无需复杂的配置。

通过 Spring Boot 的 application.yaml,特别适合需要动态切换大模型供应商的企业场景。:

spring:ai:openai:api-key: xxxbase-url: xxxchat:options:model: xxx
#  completions-path 属性用于指定调用 OpenAI 聊天补全接口的具体路径,默认值:/v1/chat/completions(对应 OpenAI 官方接口路径)
#        completions-path: /v1/chat/completionstemperature: 0.7

二、Spring AI 涉及的基础概念

  • 模型(Model)

就是接收用户行为,以及根据用户行为生成内容的算法,本质还是算法,这些算法可以接收文本、图片、音视频,生成满足用户需要的文本、图片、音频视频等内容,其中有一种输入文本叫嵌入文本(embedding text),输出多维度的数组,表示AI模型使用的内部数据结构,用来判断多个样本之间的相似性。

  • 提示词(Prompt)

prompt是引导AI模型生成特定输出的输入,它的设计会显著影响模型的响应,一开始prompt是简单的文本输入,就好比是智能对话中的问题,随着事件的推移,prompt演变成了包含多个”角色“的结构体,这些角色对消息进行分类,明确了上下文,可以实现历史问答等的相关功能等。角色有:系统角色(System Role)、用户角色(User Role)、助手角色(Assistant  Role)、工具/功能角色(Tool/Function Role)。

  • 提示词模板(Prompt Template)

就是模板格式,在实际运用中可以提供占位符的格式,使用用户的输入替换占位符,增加灵活性。Spring AI采用开源库StringTemplate来实现。

  • 嵌入(Embedding)

原理就是把输入的文本、图像和视频转换为称为向量(Vector)的浮点数数组来表示,数组长度就是向量的维度,可以把多维度的向量数组映射到空间坐标轴中,依次找到他们之间的接近性,这种接近性有助于文本分类、语义搜索,甚至产品推荐等任务。也可以把数组存入到向量数据库中,提供给RAG使用。

  • Token

token是 AI 模型工作原理的基石。输入时,模型将单词转换为token。输出时,它们将token转换回单词。在英语中,一个token大约对应一个单词的 75%,实际使用第三方大模型的过程中,也是根据token进行收费的,具体收费情况根据模型和输入输出类型而定。

  • 结构化输出(Structured Output)

就是把从大模型输出的结果转换成我们想要类型,可以是json格式、xml格式、或者是java类,这对于我们应用开发者比较重要,可以自定义实体类来接收结果,在应用中使用。

  • 检索增强生成(RAG)

我理解是一种方法,目的是为大模型提供额外的知识输入,辅助模型更好的回答问题,当用户输入问题时,RAG技术从矢量数据库查询出所有“类似”的文档片段,连同用户的问题,一起放入发送给 AI 模型的提示中。该方法涉及到:从文档中读取非结构化数据、对其进行转换、然后将其写入矢量数据库。

  • 函数调用(Function Calling)

大型语言模型 (LLM) 在训练后即被冻结,导致知识陈旧,并且无法访问或修改外部数据。该方式提供了一种方法,解决大模型训练后知识陈旧的问题,可以引入自定义的功能函数,函数中可以调取外部的API来获取最新的数据返回给大模型,并最终向用户提供响应。


三、​​Spring AI 的核心组件​

3.1、​ChatModel(模型抽象)​

  • ​作用​​:定义生成式 AI 模型的统一接口(如 generate(prompt))。
  • ​实现示例​​:
    // 配置 OpenAI 模型
    @Bean
    OpenAiChatModel openAiModel() {return new OpenAiChatModel("sk-xxx");
    }
  • ​调用​​:
    String reply = chatModel.generate("Hello, how are you?");

3.2、ChatClient(客户端封装)​

  • ​作用​​:简化与模型的交互,支持流式响应和上下文管理。
  • ​示例​​:
    @Autowired
    private ChatClient chatClient;// 发送消息并获取流式响应
    Flux<String> response = chatClient.stream("Explain quantum computing.");

3.3、PromptTemplate(提示词模板)​

  • ​作用​​:动态生成结构化提示词,支持变量插值。
  • ​示例​​:
    PromptTemplate template = new PromptTemplate("Translate '{text}' to French.");
    Prompt prompt = template.create(Map.of("text", "Hello world"));
    String translation = chatModel.generate(prompt);

四、​​与 WebFlux 的集成(响应式 AI 服务)​

Spring AI 天然支持与 ​​Spring WebFlux​​ 结合,构建非阻塞的高并发 AI 服务。

示例:实时聊天 API
@RestController
public class ChatController {@Autowiredprivate ChatClient chatClient;// 流式聊天接口(SSE 协议)@GetMapping(value = "/chat/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)public Flux<String> streamChat(@RequestParam String message) {return chatClient.stream(message);}// 同步聊天接口@PostMapping("/chat")public Mono<String> chat(@RequestBody String message) {return chatClient.generate(message);}
}

​五、快速入门 Spring AI​

5.1、添加Maven依赖​

   <!-- Spring AI --><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-openai-spring-boot-starter</artifactId><version>1.0.0-M6</version></dependency>

    5.2、​​配置 API 密钥​​(application.yml

    spring:ai:openai:api-key: xxxbase-url: xxxchat:options:model: xxx
    #  completions-path 属性用于指定调用 OpenAI 聊天补全接口的具体路径,默认值:/v1/chat/completions(对应 OpenAI 官方接口路径)
    #        completions-path: /v1/chat/completionstemperature: 0.7

      5.3、OpenAiChatClientController实现流式调用和同步调用

      package com.hs.demo.controller;import io.swagger.v3.oas.annotations.Operation;
      import io.swagger.v3.oas.annotations.tags.Tag;
      import jakarta.servlet.http.HttpServletResponse;
      import org.springframework.ai.chat.client.ChatClient;
      import org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor;
      import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
      import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
      import org.springframework.ai.chat.memory.InMemoryChatMemory;
      import org.springframework.ai.openai.OpenAiChatOptions;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.http.MediaType;
      import org.springframework.http.codec.ServerSentEvent;
      import org.springframework.validation.annotation.Validated;
      import org.springframework.web.bind.annotation.GetMapping;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.RequestParam;
      import org.springframework.web.bind.annotation.RestController;
      import reactor.core.publisher.Flux;/*** 实现调用逻辑,可以设置默认的系统Prompt,定义模型的参数** 使用InMemoryChatMemory聊天记录的存储,可以让模型记住对话记录,结合上下文去回答,chatId就是会话窗口的id,在这个id不变的情况下,它会自定义的去在总结100条对话记录,然后再回答你的问题*/
      @RestController
      @RequestMapping("/openai/chat")
      @Tag(name = "AI对话")
      public class OpenAiChatClientController {private final ChatClient openAiChatClient;private static final String DEFAULT_PROMPT = "你是一个聊天助手,请根据用户提问回答!";public OpenAiChatClientController(ChatClient.Builder chatClientBuilder) {this.openAiChatClient = chatClientBuilder.defaultSystem(DEFAULT_PROMPT)// 实现 Chat Memory 的 Advisor              // 在使用 Chat Memory 时,需要指定对话 ID,以便 Spring AI 处理上下文。.defaultAdvisors(new MessageChatMemoryAdvisor(new InMemoryChatMemory()))// 实现 Logger 的 Advisor.defaultAdvisors(new SimpleLoggerAdvisor())// 设置 ChatClient 中 ChatModel 的 Options 参数.defaultOptions(OpenAiChatOptions.builder().topP(0.7).build()).build();}/*** ChatClient 简单调用*/@GetMapping("/simple/chat")@Operation(summary = "ChatClient 简单调用")public String simpleChat(@RequestParam String message) {String str = openAiChatClient.prompt(message).advisors(new SimpleLoggerAdvisor()).call().content();System.out.println("输出结果"+str);return str;}/*** ChatClient 简单调用* 默认使用 InMemoryChatMemory** @param message 消息* @param chatId  会话ID*/@GetMapping("/simple/chat/conversaion")@Operation(summary = "ChatClient 简单调用附带会话")public String simpleChat(@RequestParam String message, @RequestParam String chatId) {return openAiChatClient.prompt(message).advisors(a -> a.param(AbstractChatMemoryAdvisor.CHAT_MEMORY_CONVERSATION_ID_KEY, chatId) // 设置聊天会话ID.param(AbstractChatMemoryAdvisor.CHAT_MEMORY_RETRIEVE_SIZE_KEY, 100)) // 设置聊天记录检索数量.call().content();}/*** ChatClient 流式调用*/@GetMapping("/stream/chat")@Operation(summary = "ChatClient 流式调用")public Flux<String> streamChat(@RequestParam String message,HttpServletResponse response) {response.setCharacterEncoding("UTF-8");return openAiChatClient.prompt(message).stream().content();}/*** ChatClient 流式响应*/@GetMapping(value = "/stream/response", produces = MediaType.TEXT_EVENT_STREAM_VALUE)@Operation(summary = "ChatClient 流式调用1")public Flux<ServerSentEvent<String>> streamChat(@RequestParam String message) {return openAiChatClient.prompt().user(message).stream().content().map(content -> ServerSentEvent.<String>builder().data(content).build());}}

        总结​​:Spring AI 通过标准化接口和 Spring 原生集成,显著降低了 Java 应用中集成 AI 能力的门槛。开发者可以更专注于业务逻辑,而非底层协议实现。对于需要快速迭代且依赖 Spring 生态的项目,它是比手动封装 ChatClient/ChatModel 更高效的选择。


        参考链接:

        Spring AI 1.0.0 发布!支持 MCP 很炸裂!!

        SpringAI实践(一)

        接入SpringAI实现流式对话

        Spring AI 1.0 正式发布!AI 开发从未如此简单,不懂它的三层开发模式你就输麻了!

        Spring AI 1.0 正式发布!AI 开发从未如此简单,不懂它的三层开发模式你就输麻了!

        本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/pingmian/82586.shtml

        如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

        相关文章

        Python实战:打造高效通讯录管理系统

        &#x1f4cb; 编程基础第一期《8-30》–通讯录管理系统 &#x1f4d1; 项目介绍 在信息化时代&#xff0c;高效管理个人或团队联系人信息变得尤为重要。本文将带您实现一个基于Python的通讯录管理系统&#xff0c;该系统采用字典数据结构和JSON文件存储&#xff0c;实现了联系…

        89. Java 数字和字符串 - Math 类深入解析

        文章目录 89. Java 数字和字符串 - Math 类深入解析一、引言二、常量与基本方法2.1 Math 类常量2.2 绝对值和舍入绝对值方法舍入方法最小值和最大值 三、指数与对数方法四、三角函数方法五、总结 89. Java 数字和字符串 - Math 类深入解析 一、引言 在 Java 中&#xff0c;除…

        STM32之SG90舵机控制(附视频讲解)

        目录 前言&#xff1a; 一、硬件准备与接线 1.1 硬件清单 1.2 接线 二、 SG90舵机简介 1.1 外观 1.2 基本参数 1.3 引脚说明 1.4 控制原理 1.5 特点 1.6 常见问题 三、 单片机简介 四、 程序设计 4.1 定时器配置 4.2 角度控制函数 4.3 主函数调用 五、 总结 …

        netstat命令Windows与Linux双平台

        深入解析netstat命令:Windows与Linux双平台实战指南 netstat(Network Statistics)是网络诊断中最经典的工具之一,能够帮助用户查看网络连接、端口监听状态、路由表等信息。然而,Windows和Linux系统下的netstat在参数和输出格式上存在差异,容易让人混淆。本文将详细对比两…

        攻防世界-ics-07

        进入环境 进入项目管理 点击进行访问 是一堆代码进行审计 <?php session_start();if (!isset($_GET[page])) {show_source(__FILE__);die(); }if (isset($_GET[page]) && $_GET[page] ! index.php) {include(flag.php); }else {header(Location: ?pageflag.php);…

        基于 Node.js 的 Express 服务是什么?

        Express 是基于 ‌Node.js‌ 的一个轻量级、灵活的 Web 应用框架&#xff0c;用于快速构建 ‌HTTP 服务‌&#xff08;如网站、API 接口等&#xff09;&#xff0c;以下是详细解析&#xff1a; ‌一、Express 的核心作用‌ ‌简化 Node.js 原生开发‌ Node.js 原生 http 模块虽…

        linux安装vscode以及配置vscode

        vscode配置 1&#xff0c;准备工作2&#xff0c;VsCode安装插件3&#xff0c;cmake Tools 的使用 1&#xff0c;准备工作 所谓的准备工作&#xff0c;就是要让linux具备 vim gcc g编译器&#xff0c;可使用cmake&#xff0c;makefile等开发的条件。 首先我么以及有一个以安装好…

        基于AI的智能农业病虫害识别系统实战指南

        引言 在农业现代化进程中&#xff0c;病虫害防治始终是保障粮食安全的核心挑战。传统人工识别方式存在效率低、误判率高、响应滞后等问题。本文将通过完整的技术实现流程&#xff0c;展示如何利用Python生态构建智能病虫害识别系统&#xff0c;实现从图像采集到防治建议输出的…

        【MySQL】第11节|MySQL 8.0 主从复制原理分析与实战(一)

        一、MySQL主从复制基础 1. 核心概念 定义&#xff1a; MySQL主从复制是将主库&#xff08;Source/Master&#xff09;的数据变更同步到一个或多个从库&#xff08;Replica/Slave&#xff09;的机制&#xff0c;默认采用异步复制&#xff0c;支持全库、指定库或表的同步。 角…

        【RabbitMQ】记录 InvalidDefinitionException: Java 8 date/time type

        目录 1. 添加必要依赖 2. 配置全局序列化方案&#xff08;推荐&#xff09; 3. 配置RabbitMQ消息转换器 关键点说明 1. 添加必要依赖 首先确保项目中包含JSR-310支持模块&#xff1a; <dependency><groupId>com.fasterxml.jackson.datatype</groupId>&l…

        【机器学习基础】机器学习入门核心算法:K-近邻算法(K-Nearest Neighbors, KNN)

        机器学习入门核心算法&#xff1a;K-近邻算法&#xff08;K-Nearest Neighbors, KNN&#xff09; 一、算法逻辑1.1 基本概念1.2 关键要素距离度量K值选择 二、算法原理与数学推导2.1 分类任务2.2 回归任务2.3 时间复杂度分析 三、模型评估3.1 评估指标3.2 交叉验证调参 四、应用…

        在h5端实现录音发送功能(兼容内嵌微信小程序) recorder-core

        本文将通过一个实际的 Vue3 组件示例&#xff0c;带你一步步实现“按住录音&#xff0c;松开发送&#xff0c;上滑取消”的语音录制功能。 我们将使用强大且小巧的开源库 recorder-core&#xff0c;支持 MP3、WAV、AAC 等编码格式&#xff0c;兼容性较好。 &#x1f527; 项目…

        深入掌握Node.js HTTP模块:从开始到放弃

        文章目录 一、HTTP模块入门&#xff1a;从零搭建第一个服务器1.1 基础概念解析1.2 手把手创建服务器 二、核心功能深入解析2.1 处理不同请求类型2.2 实现文件下载功能 三、常见问题解决方案3.1 跨域问题处理3.2 防止服务崩溃3.3 调试技巧 四、安全最佳实践4.1 请求头安全设置4.…

        SSM整合:Spring+SpringMVC+MyBatis完美融合实战指南

        前言 在Java企业级开发领域&#xff0c;SSM&#xff08;SpringSpringMVCMyBatis&#xff09;框架组合一直占据着重要地位。这三个轻量级框架各司其职又相互配合&#xff0c;为开发者提供了高效、灵活的开发体验。本文将深入探讨SSM框架的整合过程&#xff0c;揭示整合背后的原…

        [AI]大模型MCP快速入门及智能体执行模式介绍

        [AI]大模型MCP快速入门及智能体执行模式介绍 一、MCP入门 介绍 MCP&#xff08;Model Context Protocol&#xff0c;模型上下文协议&#xff09;是一种由Anthropic公司于2024年提出的开放标准协议&#xff0c;旨在为大型语言模型&#xff08;LLM&#xff09;提供统一接口&am…

        Mac M1 安装 ffmpeg

        1.前言 官网那货没有准备m系列的静态包&#xff0c;然后我呢&#xff0c;不知道怎么想的就从maven项目中的 javacv-platform&#xff0c;且版本为1.5.11依赖里面将这个静态包把了出来&#xff0c;亲测能用&#xff0c;感觉比那些网上说的用什么wget编译安装、brew安装快多了。…

        unity控制相机围绕物体旋转移动

        记录一下控制相机围绕物体旋转与移动的脚本&#xff0c;相机操作思路分为两块&#xff0c;一部分为旋转&#xff0c;一部分为移动&#xff0c;旋转是根据当前center中心点的坐标&#xff0c;根据距离设置与默认的旋转进行位置移动&#xff0c;移动是根据相机的左右和前后进行计…

        python打卡day38@浙大疏锦行

        知识点回顾&#xff1a; Dataset类的__getitem__和__len__方法&#xff08;本质是python的特殊方法&#xff09;Dataloader类minist手写数据集的了解 作业&#xff1a;了解下cifar数据集&#xff0c;尝试获取其中一张图片 一、首先加载CIFAR数据集 import torch import torchvi…

        用户配置文件(Profile)

        2.4.5 用户配置文件&#xff08;Profile&#xff09; 用户配置文件由以下组件构成&#xff1a; 一个运营商安全域&#xff08;MNO-SD&#xff09; 辅助安全域&#xff08;SSD&#xff09;和CASD Applets 应用程序&#xff08;如NFC应用&#xff09; 网络接入应用&#xff…

        如何给自研MCP加上安全验证

        前言 刚过去两个月,市面的 MCP 服务,如雨后春笋一般不断涌现出来,包括;百度、高德、网盘、支付宝。这些 MCP 服务,可以让我们基于 Spring AI 框架构建的 Agent 具备非常丰富的使用功能。同时这也说明,程序员👨🏻‍💻,应该具备开发 MCP 服务的能力,Spring AI 让 J…