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

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 的实现。

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

ChatCompletion

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

usage

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

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

总结

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


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

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

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

深入解析 Spring AI 系列:解析OpenAI接口对接的更多相关文章

  1. Spring Boot系列(三):Spring Boot整合Mybatis源码解析

    一.Mybatis回顾 1.MyBatis介绍 Mybatis是一个半ORM框架,它使用简单的 XML 或注解用于配置和原始映射,将接口和Java的POJOs(普通的Java 对象)映射成数据库中的记 ...

  2. Spring Cloud系列(三):Eureka源码解析之服务端

    一.自动装配 1.根据自动装配原理(详见:Spring Boot系列(二):Spring Boot自动装配原理解析),找到spring-cloud-starter-netflix-eureka-ser ...

  3. Spring Cloud系列(四):Eureka源码解析之客户端

    一.自动装配 1.根据自动装配原理(详见:Spring Boot系列(二):Spring Boot自动装配原理解析),找到spring-cloud-netflix-eureka-client.jar的 ...

  4. Spring Boot 系列教程11-html页面解析-jsoup

    需求 需要对一个页面进行数据抓取,并导出doc文档 html解析器 jsoup 可直接解析某个URL地址.HTML文本内容.它提供了一套非常省力的API,可通过DOM,CSS以及类似于JQuery的操 ...

  5. Spring源码解析 - AbstractBeanFactory 实现接口与父类分析

    我们先来看类图吧: 除了BeanFactory这一支的接口,AbstractBeanFactory主要实现了AliasRegistry和SingletonBeanRegistry接口. 这边主要提供了 ...

  6. Spring源码解析 - BeanFactory接口体系解读

    不知道为什么看着Spring的源码,感触最深的是Spring对概念的抽象,所以我就先学接口了. BeanFactory是Spring IOC实现的基础,这边定义了一系列的接口,我们通过这些接口的学习, ...

  7. Spring源码解析系列汇总

    相信我,你会收藏这篇文章的 本篇文章是这段时间撸出来的Spring源码解析系列文章的汇总,总共包含以下专题.喜欢的同学可以收藏起来以备不时之需 SpringIOC源码解析(上) 本篇文章搭建了IOC源 ...

  8. Spring Boot系列(四):Spring Boot源码解析

    一.自动装配原理 之前博文已经讲过,@SpringBootApplication继承了@EnableAutoConfiguration,该注解导入了AutoConfigurationImport Se ...

  9. Spring源码解析-ioc容器的设计

    Spring源码解析-ioc容器的设计 1 IoC容器系列的设计:BeanFactory和ApplicatioContext 在Spring容器中,主要分为两个主要的容器系列,一个是实现BeanFac ...

  10. Spring 是如何解析泛型 - ResolvalbeType

    Spring 是如何解析泛型 - ResolvalbeType Spring 系列目录(https://www.cnblogs.com/binarylei/p/10198698.html) Java ...

随机推荐

  1. 研发LLM模型,如何用数值表示人类自然语言?

    上一篇:<人工智能--自然语言处理简介> 序言:人工智能大语言模型(LLM)如何理解人类的自然语言?这个过程的核心在于将文本转化为计算机能处理的数值形式,经过计算,最终达到对语言的理解.起 ...

  2. Sublime装sftp远程编辑插件

    我平时很喜欢用Sublime来编辑一些脚本软件,本次需要远程编辑Linux上的脚本,需要安装一些插件来完成. Ctrl+Shift+P呼叫出命令行面板后输入 install选择 Install Pac ...

  3. PHP数据库连接教程 - QSZ

    1准备工作 首先,确保你的环境中已安装: PHP 7.0+ MySQL/MariaDB Web服务器(Apache/Nginx) 2数据库连接代码 // config.php setAttribute ...

  4. apisix启动报错undefined symbol: EVP_KDF_ctrl, version OPENSSL_1_1_1b

    报错内容 2024/08/06 16:56:13 [error] 154236#154236: *7039 [lua] plugin.lua:110: load_plugin(): failed to ...

  5. LNMP一键安装

    PHP环境快捷搭建工具: https://lnmp.org/ [安装] wget https://soft.lnmp.com/lnmp/lnmp2.1.tar.gz -O lnmp2.1.tar.gz ...

  6. Linux命令之ncdu

    简介 Ncdu - NCurses Disk Usage Ncdu 是一个带有 ncurses 接口的磁盘使用分析器. 它旨在在您没有完整图形设置可用的远程服务器上查找空间占用,但即使在常规桌面系统上 ...

  7. 移动端PDF阅读器重排版效果对比-小白PDF阅读器与KOReader重排效果对比

    PDF是一种跨操作系统平台的电子文件格式,它能在各种不同的平台上以相同的版式显示.很多扫描书籍或者电子书籍都会采用PDF格式存储.但是移动端由于屏幕的限制,以原版展示PDF会导致画面缩放严重,影响阅读 ...

  8. 01编程语言简介与C++

    编程语言是编程的工具 计算机系统是分层的 图1: 图2: 编程语言是软件,也是分层的 图3: 图4: 图5: 图6: visual studio.vscode .dev-c++是三种用于C++编程的集 ...

  9. 小程序 构建npm

    1. 在项目文件夹下 打开cmd 窗口,输入: npm init 一直回车即可 2. 安装模板 npm i @vant/weapp -S --production 3. 在微信开发者工具,左上角工具中 ...

  10. 【MyBatis】学习笔记06:各种查询所返回数据的数据类型

    [Mybatis]学习笔记01:连接数据库,实现增删改 [Mybatis]学习笔记02:实现简单的查 [MyBatis]学习笔记03:配置文件进一步解读(非常重要) [MyBatis]学习笔记04:配 ...