写点什么

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

  • 2025-01-16
    福建
  • 本文字数:2223 字

    阅读完需:约 7 分钟

今天我们将主要探讨 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 的接口进行高效对接与交互。


文章转载自:努力的小雨

原文链接:https://www.cnblogs.com/guoxiaoyu/p/18665146

体验地址:http://www.jnpfsoft.com/?from=001YH

用户头像

还未添加个人签名 2023-06-19 加入

还未添加个人简介

评论

发布
暂无评论
深入解析 Spring AI 系列:解析OpenAI接口对接_人工智能_快乐非自愿限量之名_InfoQ写作社区