深入解析 Spring AI 系列:剖析OpenAI接口接入组件
今天我们将继续探讨如何在Spring AI中接入大语言模型,以OpenAI为例,详细分析其接入过程。我们将逐步探讨OpenAI是如何与Spring AI系统对接的,具体包括如何配置接口、如何封装接口参数以及如何定义相关的接口。在讲解过程中,我们仍然会以整体架构为主线,逐步深入,详细了解类内部的实现细节和定义。这种渐进式的分析方式有助于更清晰地理解每个模块的功能和它们是如何协同工作的。
整体结构
在这里,我简单地绘制了一张示意图,旨在帮助你更直观、快速地理解整个系统是如何运作的。通过这张图,你可以清晰地看到各个组件之间的关系,以及数据如何在各个模块中流动和交互。如图所示:

接下来,我们将查看它的整体目录文件内容,具体内容如图所示:

刚才提到的所有目录结构实际上并没有包含具体的业务实现,所有的实现都集中在外层的定义部分。举个例子,我们要了解的核心业务是聊天功能,而这一功能的具体实现则是在 OpenAIChatModel 类中。因此,关于聊天实现的细节我们会稍后深入探讨。
至于其他的细节问题,我们稍后也会一一解析。如果对前面提到的 AOT 协议不太熟悉,可以参考我之前的文章,我已专门对该协议做了详细的讲解。这里不做主要说明了。
聊天对接
我们目前主要关注的是聊天接口是如何接入的,至于其他功能,如音频或图像处理,我们可以在后续的讨论中再进行详细探讨。不过,为了更好地理解整个系统,我们需要找到一个合适的切入点,从而逐步通过查看各个类的引用关系,深入了解整个架构的运作方式。
在我们以往构建 Agent 的过程中,第一步通常是注入一个 chatClient 类,这个类实际上就是我们最初使用的核心起点。因此,接下来我们就从 chatClient 这个类开始,深入分析其实现细节和作用。
ChatClient
这个部分是由 Spring AI 封装好的,目的是为了能够在进行底层大模型切换时,确保代码能够做到无感知地平滑过渡,依然能够正常调用。为了快速了解 Spring AI 如何实现这个链路的传递,我们可以简要地浏览一下非常简单的用法:
@GetMapping("/ai-Entity")
ActorFilms generationByEntity() {
ActorFilms actorFilms = chatClient.prompt()
.user("Generate the filmography for a random actor.")
.call()
.entity(ActorFilms.class);//只接收string的话,正常写成content()即可
return actorFilms;
}
这里的写法实际上说明,无论底层所采用的具体大模型是什么类型,若希望能够顺利将其集成到系统中,必须首先进行与ChatClient的适配。如果没有经过这一层适配,系统将无法正确地处理和调用底层模型。因此,接下来我们将直接分析其如何将请求切换至OpenAiChatModel,并实现通过API进行通信的过程。具体实现方式可以参考下方示意图:

关于AdvisedResponse,我们之前已经详细讲解过其定义和作用,因此在此不再赘述。需要强调的是,所有集成到系统中的ChatModel都必须实现一个名为call的方法,stream一样。如图所示:

OpenAiChatModel
虽然这个类包含了众多方法,但从实际应用的角度来看,我们主要关注的实际上只有两个核心方法。第一个是用于生成文本回复的方法,第二个则是支持流式回复的处理方法。其他方法大多数都是私有的辅助性方法,主要作用是为了将主方法的实现进行拆分和优化,从而避免将主方法代码写得过于复杂和臃肿。如图所示:

这几个方法内的代码也基本是固定的写法,具体业务逻辑,我们下一章节再讲。
OpenAiChatOptions
这个类的设计十分直观,理解起来并没有太多复杂的内容。其核心功能主要集中在一些常见的大模型参数配置上,比如选择具体的模型类型、调整生成结果的temperature等。这些配置项是大多数大模型在实际应用中都需要进行设置的参数,对于那些有过大模型使用经验的人来说,应该会非常熟悉这些概念。如图所示:

由于OpenAI提供的功能极为丰富,其系统中涉及到的参数种类也相应很多。
总结
通过今天的分析,我们对如何在Spring AI框架中接入OpenAI的大语言模型有了更清晰的了解。从配置接口到封装参数,再到定义相关接口,我们逐步剖析了整个接入过程。通过对ChatClient、OpenAiChatModel和OpenAiChatOptions等核心类的简单解析,我们不仅看到了大语言模型如何与Spring AI系统高效协同工作,也对其背后的设计理念有了更深刻的认识。值得一提的是,我们采取的渐进式分析方法,让每个模块的功能和其相互关系更加明了,帮助我们更好地把握整体架构。
我是努力的小雨,一个正经的 Java 东北服务端开发,整天琢磨着 AI 技术这块儿的奥秘。特爱跟人交流技术,喜欢把自己的心得和大家分享。还当上了腾讯云创作之星,阿里云专家博主,华为云云享专家,掘金优秀作者。各种征文、开源比赛的牌子也拿了。
想把我在技术路上走过的弯路和经验全都分享出来,给你们的学习和成长带来点启发,帮一把。
欢迎关注努力的小雨,咱一块儿进步!
深入解析 Spring AI 系列:剖析OpenAI接口接入组件的更多相关文章
- Spring Boot系列(三):Spring Boot整合Mybatis源码解析
一.Mybatis回顾 1.MyBatis介绍 Mybatis是一个半ORM框架,它使用简单的 XML 或注解用于配置和原始映射,将接口和Java的POJOs(普通的Java 对象)映射成数据库中的记 ...
- Spring Cloud系列(三):Eureka源码解析之服务端
一.自动装配 1.根据自动装配原理(详见:Spring Boot系列(二):Spring Boot自动装配原理解析),找到spring-cloud-starter-netflix-eureka-ser ...
- Spring Cloud系列(四):Eureka源码解析之客户端
一.自动装配 1.根据自动装配原理(详见:Spring Boot系列(二):Spring Boot自动装配原理解析),找到spring-cloud-netflix-eureka-client.jar的 ...
- Spring Boot 系列教程11-html页面解析-jsoup
需求 需要对一个页面进行数据抓取,并导出doc文档 html解析器 jsoup 可直接解析某个URL地址.HTML文本内容.它提供了一套非常省力的API,可通过DOM,CSS以及类似于JQuery的操 ...
- spring源码系列(二):IOC接口设计分析
这里主要对springIOC接口体系进行简单的概述和分析,具体每个接口详细分析在下面目录: 参考内容: <Spring技术内幕:深入解析 Spring架构与设计原理> 和 <Spri ...
- Spring Boot系列(四):Spring Boot源码解析
一.自动装配原理 之前博文已经讲过,@SpringBootApplication继承了@EnableAutoConfiguration,该注解导入了AutoConfigurationImport Se ...
- Spring入门系列:浅析知识点
前言 讲解Spring之前,我们首先梳理下Spring有哪些知识点可以进行入手源码分析,比如: Spring IOC依赖注入 Spring AOP切面编程 Spring Bean的声明周期底层原理 S ...
- Spring mvc系列一之 Spring mvc简单配置
Spring mvc系列一之 Spring mvc简单配置-引用 Spring MVC做为SpringFrameWork的后续产品,Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块 ...
- Spring 源码剖析IOC容器(一)概览
目录 一.容器概述 二.核心类源码解读 三.模拟容器获取Bean ======================= 一.容器概述 spring IOC控制反转,又称为DI依赖注入:大体是先初始化bean ...
- Spring基础系列-AOP源码分析
原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/9560803.html 一.概述 Spring的两大特性:IOC和AOP. AOP是面向切 ...
随机推荐
- 工作中的技术总结_ thymeleaf的应用 _select&input的数据回显 _20210910
工作中的技术总结_ thymeleaf的应用 _select&input的数据回显 _20210910 在需要用户输入的场合,常常会有对用户填入数据的验证,对数据的验证不通过则需要返回到表单页 ...
- awk优化钉钉通知测试报告
一.背景 在之前的博客 Go服务自动触发单元测试覆盖率 中钉钉通知的效果实现如下图: 最近RD提出对本次和上次覆盖率的比对需求,并把比对结果也显示在钉钉通知上. 二.实现思路 要实现数据比对,就需要对 ...
- 5.4 Linux Vim基本操作
<Vim三种工作模式>一节给大家详细介绍了 Vim 的 3 种工作模式,本节来学习如何使用 Vim 编辑文件. 首先学习如何使用 Vim 打开文件. Vim 打开文件 使用 Vim 打开文 ...
- 小米R3G刷了padavan后时间不同步和定时关闭外网(wan)端口
怎么刷openwrt或者padavan请见我2022年3月份的帖子 https://www.cnblogs.com/jar/p/15954037.html 最近遇到个新环境,遂拿出来用用 有1个问题和 ...
- 我是如何从0开始,在23天里完成一款Android游戏开发的 – Part 1 – 开篇与前2天
本文由 ImportNew - ImportNew读者 翻译自 bigosaur.如需转载本文,请先参见文章末尾处的转载要求. 本文是这个系列的第一篇文章,记录作者的开篇和前2天的情况.文章由 朱新亮 ...
- 解决window.close()在谷歌浏览器不起作用
简单明了直接上解决方法: let url = ' '; // 空字符串中间要加空格 window.open(url, '_self').close();
- Tornado框架之应用安全(四)
知识点 Cookie操作 安全Cookie 跨站请求伪造原理 XSRF保护 模板 请求体 HTTP报文头 用户验证 authenticated装饰器 get_current_user()方法 logi ...
- Postman 汉化教程
Postman 汉化教程(Postman中文版) 迷恋自留地 postman官网下载地址 https://www.postman.com/downloads/ postman汉化包 https://g ...
- 《JavaScript 模式》读书笔记(7)— 设计模式2
这一篇我们主要来学习装饰者模式.策略模式以及外观模式.其中装饰者模式稍微复杂一点,大家认真阅读,要自己动手去实现一下哦. 四.装饰者模式 在装饰者模式中,可以在运行时动态添加附加功能到对象中.当处理静 ...
- openEuler欧拉配置Nacos集群
一.安装Nacos systemctl stop firewalld systemctl disable firewalld mkdir -p /home/nacos tar xvf nacos- ...