深入解析 Spring AI 系列:解析OpenAI接口对接

news/2025/1/14 10:32:02/文章来源:https://www.cnblogs.com/guoxiaoyu/p/18665146

今天我们将主要探讨OpenAI是如何进行接口对接的,虽然我们不打算深入细节,但会对整体流程进行一个大概的了解。后续会逐步分析其中的具体细节,大家可以耐心等待,逐步展开。好的,现在让我们开始,下面是我简单绘制的一张图示,旨在帮助大家更好地理解接下来的分析流程。

image

OpenAiApi

我们第一步将直接查看 OpenAIApi 类,这是与接口最为密切相关的核心类。首先,我们会关注它的构造器部分,因为在构造器中,基本包含了与接口交互所需的最主要依赖和配置信息。通过这段代码,我们可以了解该类如何初始化并准备好与 OpenAI 接口进行通信。接下来,大家可以看到下面这段代码:

public OpenAiApi(String baseUrl, String apiKey, MultiValueMap<String, String> headers, String completionsPath,String embeddingsPath, RestClient.Builder restClientBuilder, WebClient.Builder webClientBuilder,ResponseErrorHandler responseErrorHandler) {this.completionsPath = completionsPath;
this.embeddingsPath = embeddingsPath; 
Consumer<HttpHeaders> finalHeaders = h -> {h.setBearerAuth(apiKey);h.setContentType(MediaType.APPLICATION_JSON);h.addAll(headers);
};
this.restClient = restClientBuilder.baseUrl(baseUrl).defaultHeaders(finalHeaders).defaultStatusHandler(responseErrorHandler).build();this.webClient = webClientBuilder.baseUrl(baseUrl).defaultHeaders(finalHeaders)
.build(); 
}

这段构造函数代码相对简单,主要负责创建一个包含认证信息和内容类型的HTTP头配置,并通过这些配置初始化RestClient和WebClient,从而为后续的网络请求提供基础支持。

RestClient

RestClient主要用于处理非流式的请求和响应,代码如下:

public ResponseEntity<ChatCompletion> chatCompletionEntity(ChatCompletionRequest chatRequest,MultiValueMap<String, String> additionalHttpHeader) {return this.restClient.post().uri(this.completionsPath).headers(headers -> headers.addAll(additionalHttpHeader)).body(chatRequest).retrieve().toEntity(ChatCompletion.class);
}

WebClient

WebClient主要就是处理流式的请求和响应,代码看下:

    public Flux<ChatCompletionChunk> chatCompletionStream(ChatCompletionRequest chatRequest,MultiValueMap<String, String> additionalHttpHeader) {AtomicBoolean isInsideTool = new AtomicBoolean(false);return this.webClient.post().uri(this.completionsPath)//此处省略部分代码

这部分代码参数很多,我们就看下核心逻辑即可。

类属性

这样,在理解了主要流程之后,你就能更清晰地理解每个参数在具体实现中的角色,以及它们如何影响整体功能的执行。接下来,我们来一起看一下这段关键代码:

public static final OpenAiApi.ChatModel DEFAULT_CHAT_MODEL = ChatModel.GPT_4_O;
public static final String DEFAULT_EMBEDDING_MODEL = EmbeddingModel.TEXT_EMBEDDING_ADA_002.getValue();
private static final Predicate<String> SSE_DONE_PREDICATE = "[DONE]"::equals;
private final String completionsPath;
private final String embeddingsPath;
private final RestClient restClient;
private final WebClient webClient;
private OpenAiStreamFunctionCallingHelper chunkMerger = new OpenAiStreamFunctionCallingHelper();

在去掉了向量的相关属性之后,剩下的部分就是chunkMerger,不过这个部分涉及的是处理流式响应的逻辑,暂时我们可以先不关注它。为了简化分析,当前我们主要关注的是最基本的、正常的阻塞式请求处理流程,因为这种模式更加直观易懂,便于我们理解和调试。

ChatCompletionRequest

接下来,我们将继续深入分析之前提到的阻塞请求 chatCompletionEntity。该请求的参数包括一个 ChatCompletionRequest 对象和一个包含额外头信息的 Map 结构。由于我们关注的重点是请求的核心内容,因此我们将主要分析 ChatCompletionRequest 的实现。

image

这部分内容相信大家一定很熟悉,它实际上就是接口请求的参数部分。具体来说,它是一个记录类,用于封装接口请求所需的各项信息。通过查看原有接口平台上展示的参数列表,我们可以很清楚地看到这个记录类是如何映射到实际接口请求中的各个字段的。如图所示:

image

ChatCompletion

他的返回参数是ResponseEntity,他会将返回信息包装成一个ChatCompletion实体,猜一下也是接口返回相关的参数封装。如图所示:

image

image

usage

在之前我们说过usage这个类,他其实就是计算token用的。如果不看统计类的信息,也没啥大用。

image

这里就不拿官方接口做对比了,结果是一样的。

总结

通过今天的分析,我们初步了解了OpenAI接口对接的整体流程。虽然我们没有深入细节,但通过对OpenAiApi类、RestClient、WebClient及相关请求参数的分析,大家应该对接口的工作原理有了一个大致的认识。后续,我们将继续细化具体实现,逐步揭示每个部分的功能与逻辑。希望大家耐心等待,跟随我们一起深入探索更多的技术细节。这一过程将帮助我们更好地理解如何与OpenAI的接口进行高效对接与交互。


我是努力的小雨,一个正经的 Java 东北服务端开发,整天琢磨着 AI 技术这块儿的奥秘。特爱跟人交流技术,喜欢把自己的心得和大家分享。还当上了腾讯云创作之星,阿里云专家博主,华为云云享专家,掘金优秀作者。各种征文、开源比赛的牌子也拿了。

💡 想把我在技术路上走过的弯路和经验全都分享出来,给你们的学习和成长带来点启发,帮一把。

🌟 欢迎关注努力的小雨,咱一块儿进步!🌟

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

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

相关文章

赛果公布!有灵AOP平台首届编程挑战赛圆满落幕

近日,网易伏羲有灵AOP平台首届编程挑战赛顺利落下帷幕。自赛事启动以来,在短短几周的时间里,来自各地的优秀开发者们汇集于此,通过人机协作的形式,完成了多项充满创意和技术深度的任务。此次挑战赛不仅展现了参赛者的卓越编程技能,也体现了AOP(Agent Oriented Programmi…

华大HC32F4A0串口使用及printf重定向

说明: 轮询 polling方法 更改自小华HC32官方库DDL_2.2.0版本相关宏定义 /* 串口 */ #define USART_RX_PORT (GPIO_PORT_B) /* PH13: USART1_RX */ #define USART_RX_PIN (GPIO_PIN_15) #define USART_RX_GPIO_FUNC (GPIO…

HC32F4A0串口使用

说明: 轮询 polling方法 更改自HC32官方库2.2.0版本相关宏定义 /* 串口 */ #define USART_RX_PORT (GPIO_PORT_B) /* PH13: USART1_RX */ #define USART_RX_PIN (GPIO_PIN_15) #define USART_RX_GPIO_FUNC (GPIO_FUNC_33…

读量子霸权03量子的崛起

瑞利-金斯灾变揭示牛顿力学漏洞,普朗克提出量子理论颠覆传统。爱因斯坦解释光电效应,薛定谔方程成量子基石。量子纠缠等理论展现量子世界奇妙,量子计算机应运而生。1. 瑞利-金斯灾变 1.1. 也被称为紫外灾变1.1.1. 在高频条件下发射的能量应该是无限大的,而这在现实中是根本…

宠物经济与即时零售:如何把握双赢机遇?

借助板栗看板,宠物食品和用品的即时零售模式可以实现从营销目标设定、库存管理、营销活动规划、顾客互动到数据分析与反馈的全链条优化。这不仅能够提升运营效率,还能增强品牌影响力,提升顾客满意度和忠诚度。宠物即时零售是近年来随着宠物经济的蓬勃发展和即时零售模式的兴…

manim边做边学--动画联动

今天介绍Manim中的动画联动的技巧,在数学动画中,动画联动是常用的功能, 比如讲解平面几何中三角形与圆的位置关系变化,通过动画联动可以让圆沿着三角形的边滚动,或者让三角形的顶点在圆上移动,从而直观地展示内切、外接等几何关系。 总之,通过动画联动,可以将复杂的概念…

刷力扣的技巧:4 个步骤 7 个关键点,事半功倍,冲进大厂!

最近好多人问我咋刷力扣呀,今天我就来给大家好好唠唠。我总结了7个要点和4个步骤,尤其是最后那提效4步骤,可太有用啦。 大家一定要看到最后哦,记得点赞、收藏呀。要点一:别光追求刷题量,题解也得看 咱好多同学呀,解开一道题就着急忙慌地去刷下一道,还把刷题数量当成衡量…

Linux 常用脚本命令-lsof、find、rpm、SS、top、vim

1,关机命令1 shutdown -h now/0 2 halt 3 init 0 4 poweroff 5 举例: 6 shutdown -h 3 ------3分钟后关机(可用shutdown -c来取消3分钟关机的操作)2,重启命令1 shutdown -r now/0 2 init 6 3 reboot 4 举例: 5 shutdown -r 3 ------3分钟后重启(可用shutdown -c来…

英伟达即将压缩AI模型的成本

在CES上,英伟达展示了一些有趣的新产品,其中最亮眼的是黄仁勋的新皮夹克。我的意思是,看看那件夹克:这是技术发布会还是时尚秀? 你不觉得惊艳吗? 说实话,我有点惊讶为什么更多人没有提到这个。这是黄仁勋迄今为止最棒的皮夹克。 当然,还有其他东西,比如全新的RTX 50系…

傅里叶级数

傅里叶级数 转自 https://zhuanlan.zhihu.com/p/609597010傅里叶级数的公式: 其中: 为了积分方便,积分区间一般设为[-π, π],也相当一个周期T的宽度。 1、把一个周期函数表示成三角级数:首先,周期函数是客观世界中周期运动的数学表述,如物体挂在弹簧上作简谐振动、单…

旅游巴士

旅游巴士一看题啥也不会 注意到数据点范围,发现有特殊性质 ai=0 ,也就是说,每个景点没有时间限制,所以在分层图上跑BFS最短路就行了。设 dis[i][j] 为到第 i 个点时,在时刻 t 时刻到达,记录为 t mod k=j,分为 j 层。 考虑正解,假设现在到达了 u 号点,在 t 时刻,要去往…

VS2022 安装 .NET Framework 4.0 和 .NET Framework 4.5 的方法

前言2022年5月27日,刚刚把VS2019升级到了VS2022,安装时已经不提供.NET Framework 4.0和.NET Framework 4.5的目标框架了,打开VS也提示不支持目标框架。 解决方法1、下载.NET Framework框架.NET Framework 4.5.2.NET Framework 4.5.1.NET Framework 4.5.NET Framework 4.0备…