在这里插入图片描述

前言

到目前为止,我们整个系列的旅程都是在功能强大的LangChain4j框架上构建的。它就像一个装备齐全的“瑞士军刀”,为我们提供了构建RAG和Agents所需的所有底层和高层工具。

然而,在Java企业级开发的世界里,有一个名字我们永远无法忽视——Spring。当AI浪潮来袭,Spring官方团队自然不会缺席。他们推出了自己的解决方案:Spring AI

那么,Spring AI是什么?它和我们已经熟练使用的LangChain4j是什么关系?是竞争者还是协作者?它能为我们带来什么新的价值?今天,我们将一起探索这个由Spring官方打造的AI框架,体验它所带来的“原生”开发感受。

第一部分:什么是Spring AI?

Spring AI是一个应用框架,旨在将AI功能(特别是基于大语言模型的功能)以一种**“Spring原生”**的方式,无缝集成到企业级应用中。

它的核心设计哲学不是从零开始创造一切,而是:

  1. 提供统一的顶层抽象:无论底层模型是来自OpenAI、Google、Azure还是HuggingFace,Spring AI都力求提供一套统一的、面向接口的API,如ChatClientEmbeddingClient
  2. 拥抱Spring生态:充分利用Spring Boot的自动配置、依赖注入和外部化配置等核心特性。你不需要手动创建客户端,只需要在application.properties中填写配置,相应的Bean就会被自动创建和注入。
  3. 可移植性:它的目标是让你的业务代码与具体的AI模型提供商解耦。理论上,你只需要修改配置文件,就能从OpenAI切换到Azure OpenAI,而无需改动Java代码。

Spring AI vs. LangChain4j:是什么关系?
它们并非严格的竞争关系,而是不同层面的抽象。Spring AI更侧重于简化集成和提升Spring开发者的体验。事实上,Spring AI的某些模块底层就是由LangChain4j驱动的!你可以把Spring AI看作是一个更高层次的“门面”,它为你整合了包括LangChain4j在内的多种AI库,并用一层标准的Spring接口将其包装起来。

第二部分:在Spring Boot中集成Spring AI

让我们在一个新的分支或项目中,体验一下Spring AI的配置过程。

  1. 修改pom.xml
    Spring AI有自己的BOM(Bill of Materials)来管理版本。我们需要先引入BOM,再添加具体的Starter。

      <properties><java.version>21</java.version><!-- 定义Spring AI的版本 --><spring-ai.version>1.0.0-M3</spring-ai.version></properties><dependencyManagement><dependencies><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-bom</artifactId><version>${spring-ai.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- Spring AI OpenAI Starter --><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-openai-spring-boot-starter</artifactId></dependency><!-- Spring AI Vector Store - Simple (内存向量存储) --><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-transformers-spring-boot-starter</artifactId></dependency><!-- JSON处理 --><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId></dependency><!-- Lombok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build><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>
    

    注意:请根据Spring AI的最新发布情况调整版本和仓库配置。

  2. 修改application.properties
    Spring AI有自己的一套配置属性,命名空间是spring.ai

    
    # ==========================================
    # Spring AI Demo 配置文件
    # ==========================================# 服务器端口配置
    server.port=8080# ==========================================
    # Spring AI OpenAI 配置
    # ==========================================# OpenAI API密钥 (请设置环境变量 OPENAI_API_KEY)
    spring.ai.openai.api-key=${OPENAI_API_KEY:your-api-key-here}# OpenAI API基础URL (支持代理服务)
    spring.ai.openai.base-url=${OPENAI_BASE_URL:https://yibuapi.com/}# 聊天模型配置
    spring.ai.openai.chat.options.model=${OPENAI_MODEL:gpt-4o-mini}
    spring.ai.openai.chat.options.temperature=${OPENAI_TEMPERATURE:0.7}
    spring.ai.openai.chat.options.max-tokens=${OPENAI_MAX_TOKENS:2000}# ==========================================
    # 应用程序配置
    # ==========================================# 应用名称
    spring.application.name=springboot-langchain4j-demo# 日志配置
    logging.level.org.springframework.ai=DEBUG
    logging.level.org.example.demo=DEBUG# ==========================================
    # Web配置
    # ==========================================# 静态资源配置
    spring.web.resources.static-locations=classpath:/static/
    spring.web.resources.cache.period=3600# 编码配置
    server.servlet.encoding.charset=UTF-8
    server.servlet.encoding.enabled=true
    server.servlet.encoding.force=true

    仅仅这样配置,Spring AI的Starter就会为我们自动创建一个配置好的ChatClient Bean。

第三部分:实战 - 使用ChatModel 进行聊天

现在,我们将创建一个新的Service和Controller,体验一下ChatModel 的流畅API。

  1. 创建SpringAiService.java

    package com.example.aidemoapp.service;import lombok.RequiredArgsConstructor;
    import org.springframework.ai.chat.model.ChatModel;
    import org.springframework.ai.chat.prompt.Prompt;
    import org.springframework.ai.chat.prompt.PromptTemplate;
    import org.springframework.stereotype.Service;@Service
    @RequiredArgsConstructor
    public class SpringAiService {private final ChatModel chatModel;/*** 简单聊天对话*/
    public String getSimpleChatResponse(String userPrompt) {return chatModel.call(userPrompt);
    }/*** 使用模板的聊天对话*/
    public String getChatResponseWithTemplate(String topic, String style) {String template = "请用{style}的风格来介绍{topic},内容要详细且有趣。";PromptTemplate promptTemplate = new PromptTemplate(template);Prompt prompt = promptTemplate.create(Map.of("topic", topic,"style", style));return chatModel.call(prompt).getResult().getOutput().getContent();
    }
    }
    

    代码解析

    • 我们没有看到任何OpenAi...相关的类,代码完全面向ChatModel 这个抽象接口。
    • API调用是链式的,非常清晰:定义提示 -> 发起调用 -> 获取内容。
  2. 创建SpringAiController.java

    package com.example.aidemoapp.controller;import com.example.aidemoapp.service.SpringAiService;
    import lombok.RequiredArgsConstructor;
    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;@RestController
    @RequestMapping("/api/spring-ai")
    @RequiredArgsConstructor
    public class SpringAiController {private final SpringAiService springAiService;/*** 简单聊天接口*/@GetMapping("/chat")public Map<String, Object> chat(@RequestParam("query") String query) {try {String response = springAiService.getSimpleChatResponse(query);return Map.of("success", true,"data", response,"message", "聊天成功");} catch (Exception e) {return Map.of("success", false,"data", "","message", "聊天失败: " + e.getMessage());}}/*** 模板聊天接口*/@PostMapping("/chat/template")public Map<String, Object> chatWithTemplate(@RequestBody Map<String, String> request) {try {String topic = request.get("topic");String style = request.get("style");String response = springAiService.getChatResponseWithTemplate(topic, style);return Map.of("success", true,"data", response,"message", "模板聊天成功");} catch (Exception e) {return Map.of("success", false,"data", "","message", "模板聊天失败: " + e.getMessage());}}
    }
    
第四步:对比与思考

现在我们可以清楚地看到Spring AI和LangChain4j在设计哲学上的异同:

  • 配置方式:两者都支持外部化配置,但命名空间不同。Spring AI的spring.ai.*对于Spring开发者来说更具辨识度。
  • 核心抽象
    • Spring AI:核心是ChatModel ,一个非常直接、面向任务的客户端。它的目标是让你用最少的代码完成最常见的任务。
    • LangChain4j:核心是ChatLanguageModel接口和AiServices工厂/注解。它更侧重于将一个Java接口映射为一个AI服务,提供了更灵活的、声明式的编程模型。
  • 易用性
    • 对于简单的聊天或嵌入任务,Spring AI的ChatClient极其简单直接,学习成本几乎为零。
    • 对于构建复杂的RAG或Agent流,LangChain4j通过RetrievalAugmentor@Tool等组件提供了更结构化、更专门的解决方案。

我应该用哪个?

  • 如果你是Spring重度用户,且需求是快速将聊天、RAG等标准功能集成到应用中,Spring AI是你的不二之选。它的无缝集成和极低的上手门槛会让你事半功倍。
  • 如果你需要构建高度定制化的AI工作流,或者需要使用一些LangChain4j独有的高级功能,直接使用LangChain4j会给你更大的灵活性和控制力。

好消息是,你不必二选一。你完全可以在一个Spring AI项目中使用LangChain4j的组件,它们可以和谐共存。

总结

今天,我们探索了Spring官方的AI解决方案——Spring AI。我们了解了它以“Spring原生体验”为核心的设计思想,并通过ChatClient体验了其简洁流畅的API。

我们现在武器库中又增添了一件利器。我们既有功能全面、灵活强大的LangChain4j,又有与Spring生态无缝集成的Spring AI。作为开发者,我们可以根据项目的具体需求,选择最合适的工具。

在我们开发之旅接近尾声时,我们已经探索了多种工具和技术。但无论技术如何,将AI应用推向生产环境,都会面临一些共通的挑战。


源码获取

本文中所有实战代码均已同步更新至Gitee仓库。建议您git pull拉取最新代码,对照本文进行学习。

  • Gitee仓库地址: https://gitee.com/chaocloud/spring-ai-demo

下一篇预告:
Java大模型开发入门 (14/15):生产环境考量 - 成本、安全与性能优化》—— 我们将从编码转向工程,探讨在生产环境中部署和运维一个LLM应用时,必须考虑的成本控制、安全防护和性能优化等关键问题。

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

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

相关文章

Github搜索案例

今天的内容是这个案例的实现&#xff0c;以及其中涉及到的内容&#xff0c;需要全部掌握&#xff0c;比如ref&#xff0c;受控组件&#xff0c;props在组件之中的传递&#xff0c;以及Pubsub包的使用这些前端React框架有关的内容。现在进入正题 1.github搜索案例&#xff08;a…

Vue3学习(生命周期,hooks,axios的简单讲解)

一&#xff0c;前言 继续努力&#xff0c;南方见。 二&#xff0c;生命周期 1.对生命周期的理解 例如&#xff1a;人的生命周期&#xff0c;出生&#xff0c;经历&#xff0c;死亡 组件的话就是&#xff0c;创建&#xff0c;挂载&#xff0c;更新&#xff0c;销毁。***在特…

Pytorch实战四 基于 VGG net 搭建一个串联的神经网络结构

系列文章目录 文章目录 系列文章目录前言一、VGG类的搭建1.源码2.初始化类2.1 初始化函数2.2 前向传播函数 forward(self,x) 二、卷积补充卷积 前言 对于标准的 VGG net 输入图像的尺寸是 24 x 24,进行 32 维的下采样之后得到一个 7 x 7 的特征图&#xff0c;然后用 FC 层完成分…

大学专业解读——计算机

我们继续&#xff0c;讲讲排名第二流行的新工科专业——计算机。说到计算机&#xff0c;可能所有人都知道&#xff0c;但具体到细分的专业类别&#xff0c;除了计算机科学&#xff0c;其实大多数人都是不了解的。 序&#xff1a; 计算机主要有如下几个专业&#xff1a; 计算机…

Bootstrap 5学习教程,从入门到精通, Bootstrap 5 列表组(List Group)语法知识点及案例(14)

Bootstrap 5 列表组(List Group)语法知识点及案例 一、列表组基础语法 列表组是Bootstrap中用于显示一系列内容的灵活组件&#xff0c;常用于显示菜单、导航或任何项目列表。 基本列表组结构 <ul class"list-group"><li class"list-group-item&quo…

FPGA基础 -- Verilog 命名事件

Verilog 的“命名事件&#xff08;Named Events&#xff09;”机制 进行一次系统、专业的培训。该机制在 Verilog 中是比较冷门但重要的仿真控制特性&#xff0c;主要用于 模块间同步、行为仿真触发、事件通信&#xff0c;在复杂的 Testbench、行为模型中尤为重要。 一、命名事…

《Go语言圣经》结构体

《Go语言圣经》结构体 一、结构体指针的高效应用 在处理大型结构体时&#xff0c;为避免内存复制&#xff0c;通常使用指针传递和返回结构体&#xff1a; // 通过指针传入结构体&#xff0c;避免值拷贝 func Bonus(e *Employee, percent int) int {return e.Salary * percen…

Ascend上如何进行带宽测试

1 工具安装 1.1 下载链接 https://www.hiascend.com/developer/download/community/result?moduledl%2Bcann 1.2 安装指令&#xff1a; ./Ascend-mindx-toolbox_{version}_linux-{arch}.run --install设置环境变量&#xff1a; source /usr/local/Ascend/toolbox/set_env.…

生产BUG集

磁盘达到阈值导致ES无法删除数据 method [POST], host [http://xx.xxx.xxx.xxx:9200], URI [/security_event/_delete_by_query?slices1&requests_per_second-1&ignore_unavailablefalse&expand_wildcardsopen&allow_no_indicestrue&ignore_throttledtru…

基于FastAPI与Selenium的智能开关状态管理系统实践

引言 在工业物联网&#xff08;IIoT&#xff09;与自动化控制场景中&#xff0c;设备状态的实时监控与自然语言指令执行是提升效率的关键。本文将介绍一种基于 FastAPI 和 Selenium 的智能设备状态管理系统&#xff0c;通过大语言模型&#xff08;LLM&#xff09;解析用户指令…

主体和债项均为“AAA”等级 海尔消金发行10亿金融债

6月18日&#xff0c;继年内发行ABS、落地ESG挂钩银团贷后&#xff0c;海尔消费金融&#xff08;以下简称“海尔消金”&#xff09;在金融市场上又迈出重要一步&#xff0c;成功簿记发行2025年首期规模达10亿元金融债&#xff0c;且主体信用等级仍为“AAA”。这一举措为海尔消金…

n8n:轻松自动化您的工作流

借助开源自动化利器 n8n&#xff0c;释放重复劳动的生产力&#xff01; 引言 n8n 是一款免费、开源的工作流自动化工具&#xff0c;致力于帮助开发者和团队通过连接各种应用和服务&#xff0c;实现重复任务的自动化处理。 它由 Jan Oberhauser 于 2019 年在德国柏林创建&…

Angular--Hello(TODO)

最近有个小错误&#xff0c;因为最近还是在看thingsboard&#xff0c;最近终于看到前端的代码&#xff0c;突然发现怎么全是ts的文件&#xff0c;仔细一看原来并不是之前认为的AngularJS&#xff0c;而是Angular。。。我tm真的无语了&#xff0c;又要去重新学。。。 Angular的…

在 Linux 系统中通过 yum 安装 Sublime Text

在 Linux 系统中通过 yum 安装 Sublime Text 的步骤如下&#xff1a; ​步骤 1&#xff1a;导入 GPG 公钥​ sudo rpm -v --import https://download.sublimetext.com/sublimehq-rpm-pub.gpg 这一步用于验证软件包的合法性。 ​步骤 2&#xff1a;添加 Sublime Text 的软件仓…

面向自主多星对地观测的多智能体强化学习

大家读完觉的有帮助记得及时关注和点赞&#xff01;&#xff01;&#xff01; 抽象 近地轨道 &#xff08;LEO&#xff09; 卫星的指数级增长彻底改变了地球观测 &#xff08;EO&#xff09; 任务&#xff0c;解决了气候监测、灾害管理等方面的挑战。然而&#xff0c;多卫星系统…

flutter 短视频相关插件选型

​插件名称​​核心优势​​缺点​​短视频场景适用性​​推荐指数​​video_player​ (官方基础库)• 官方维护&#xff0c;跨平台兼容性最佳&#xff08;iOS/Android/macOS&#xff09; • 轻量级&#xff0c;无额外依赖&#xff0c;启动速度快 • 支持本地/网络视频、基础播…

QTableView为例:Qt模型视图委托(MVD)(Model-View-Delegate)

文章目录 1. QT中的MVD模式2. View3. Model4. Delegate5. 以TableView为例 1. QT中的MVD模式 模型视图委托&#xff08;MVD&#xff09;是Qt中特有的设计模式&#xff0c;类似MVC设计模式&#xff0c;将MVC设计模式中的Controller当做MVD中的Delegate&#xff0c;两者的概念基…

uni-app总结3-项目新建运行调试

一、新建项目 通过HbuilderX新建 在点击工具栏里的文件 -> 新建 -> 项目&#xff08;快捷键CtrlN&#xff0c;MacOS上是CMD N&#xff09;&#xff1a; 左测Tab选择uni-app类型&#xff0c;输入工程名&#xff0c;选择模板&#xff0c;Vue版本选择3&#xff0c;其他不…

LeetCode 每日一题打卡|若谷的刷题日记 4day--移动零

移动零 题目&#xff1a; 给定一个数组 nums&#xff0c;编写一个函数将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序。 请注意 &#xff0c;必须在不复制数组的情况下原地对数组进行操作。 示例 1&#xff1a; 输入: nums [0,1,0,3,12] 输出: [1,3,1…

简历模板3——数据挖掘工程师5年经验

姓名 / Your Name 数据挖掘工程师 | 5年经验 | 推荐/画像/反欺诈 &#x1f4de; 138-XXXX-XXXX | ✉️ your.emailexample.com | &#x1f310; github.com/yourname | &#x1f4cd; 北京 &#x1f3af; 个人简介 / Summary 5年大厂数据挖掘工程经验&#xff0c;硕士学历&am…