今天我们将主要探讨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. python翻译词典实例

    #!/usr/bin/python # -*- coding:utf-8 -*- #通过有道翻译来进行内容翻译 import urllib2 import urllib import json #-- ...

  2. 如何在cnblogs的发文中使用自定义地址作为发文链接

    要知道在cnblogs中发表内容后其默认的链接地址都是一串数字的形式,比如本篇的默认地址:https://www.cnblogs.com/xyz/p/18461898 但是为了让发表的内容更有个性化, ...

  3. 新手入门Java自动化测试的利器:Selenium WebDriver

    今天我们将深入探讨一款强大的Java自动化测试工具--Selenium WebDriver.在正式介绍Selenium WebDriver之前,让我们首先对Selenium本身进行简要概述,以便更好地 ...

  4. 题解:CF687C The Values You Can Make

    CF687C The Values You Can Make 题解 题目翻译感觉不明不白的(至少我看了几遍没看懂),这里给个较为清晰的题面. 题目描述 给你 \(n\) 个硬币,第 \(i\) 个硬币 ...

  5. 《JVM第9课》垃圾回收器

    先来看一张图,串行代表两个垃圾回收器按顺序执行,并行代表同时执行.STW代表工作线程暂停,Stop The World的意思. 垃圾回收器 执行顺序 执行方式 作用区域 使用算法 说明 Serial ...

  6. MindSpore-2.4版本中的一些新特性

    技术背景 在前面的一篇博客中我们介绍了MindSpore-2.4-gpu的安装和其中可能出现的一些问题.这里我们在安装完成之后,可以尝试使用一些MindSpore新版本的特性.那么在安装之后,如果是使 ...

  7. Golang框架之gin

    gin是目前golang的主要web框架之一,之所以选择这个框架是因为其拥有高效的路由性能,并且有人长期维护,目前github上的star数已经破3W. [安装] go get -u github.c ...

  8. cmu15545笔记-WAL和数据库恢复

    目录 总览 缓存策略(Buffer Pool Policies) Shadow Paging(No-Steal + Force) SQLite Rollback Mode(Steal + Force) ...

  9. nvm切换版本报exec: “cmd”: executable file not found in %PATH% 问题

    由于也是第一次用,出了个这报错懵了 搜了下也没个准确的解决办法(也可能是问题太简单),有的说可能是cmd变量没配好,检查了一遍没问题 后来想到报的是cmd,而cmd存储位置在 C:\Windows\S ...

  10. DOM元素高度获取踩坑

    前情 最近在开发一个需求,需要做一个滚动列表展示当前中奖用户,但是列表每一项高度又不是固定的,每次滚动前需要先获取当前要滚动的块是多高才知道要滚动多少. 坑位 在开发这个滚动列表的时候发现滚着滚着就会 ...