Spring AI 第二讲 之 Chat Model API 第一节OpenAI Chat

Spring AI 支持 OpenAI 的人工智能语言模型 ChatGPT。由于 ChatGPT 创建了业界领先的文本生成模型和嵌入,它在激发人们对人工智能驱动的文本生成的兴趣方面发挥了重要作用。

先决条件

要访问 ChatGPT 模型,您需要与 OpenAI 创建一个 API。在 OpenAI 注册页面创建账户,并在 API Keys 页面生成令牌。Spring AI 项目定义了一个名为 spring.ai.openai.api-key 的配置属性,你应该将其设置为从 openai.com 获取的 API 密钥的值。导出环境变量是设置该配置属性的一种方法:

java 复制代码
export SPRING_AI_OPENAI_API_KEY=<INSERT KEY HERE>

添加资源库和 BOM

Spring AI 工件发布在 Spring Milestone 和 Snapshot 资源库中。请参阅 "资源库 "部分,将这些资源库添加到您的构建系统中。

为了帮助进行依赖性管理,Spring AI 提供了一个 BOM(物料清单),以确保在整个项目中使用一致的 Spring AI 版本。请参阅 "依赖关系管理 "部分,将 Spring AI BOM 添加到构建系统中。

自动配置

Spring AI 为 OpenAI 聊天客户端提供 Spring Boot 自动配置功能。要启用它,请在项目的 Maven pom.xml 文件中添加以下依赖项:

XML 复制代码
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-openai-spring-boot-starter</artifactId>
</dependency>

或 Gradle build.gradle 构建文件。

XML 复制代码
dependencies {
    implementation 'org.springframework.ai:spring-ai-openai-spring-boot-starter'
}

请参阅 "依赖关系管理 "部分,将 Spring AI BOM 添加到构建文件中。

聊天属性

重试属性

spring.ai.retry 作为属性前缀,可用于配置 OpenAI 聊天模型的重试机制。

Property Description Default
spring.ai.retry.max-attempts Maximum number of retry attempts. 10
spring.ai.retry.backoff.initial-interval Initial sleep duration for the exponential backoff policy. 2 sec.
spring.ai.retry.backoff.multiplier Backoff interval multiplier. 5
spring.ai.retry.backoff.max-interval Maximum backoff duration. 3 min.
spring.ai.retry.on-client-errors If false, throw a NonTransientAiException, and do not attempt retry for 4xx client error codes false
spring.ai.retry.exclude-on-http-codes List of HTTP status codes that should not trigger a retry (e.g. to throw NonTransientAiException). empty
spring.ai.retry.on-http-codes List of HTTP status codes that should trigger a retry (e.g. to throw TransientAiException). empty

连接属性

spring.ai.openai 作为属性前缀,可用于连接 OpenAI。

Property Description Default
spring.ai.openai.base-url The URL to connect to api.openai.com
spring.ai.openai.api-key The API Key -

配置属性

spring.ai.openai.chat 前缀是属性前缀,用于配置 OpenAI 的聊天模型实现。

Property Description Default
spring.ai.openai.chat.enabled 启用 OpenAI 聊天模式。 true
spring.ai.openai.chat.base-url 可选择覆盖 spring.ai.openai.base-url 以提供特定的聊天 URL -
spring.ai.openai.chat.api-key 可选重载 spring.ai.openai.api-key,以提供特定于聊天的 api-key -
spring.ai.openai.chat.options.model GPT-4O、GPT-4-TURBO、GPT-4-TURBO-2024-04-09、GPT-4-0125-PREVIEW、GPT-4-TURBO-PREVIEW、GPT-4-VISION-PREVIEW、GPT-4-32K、GPT-3.5-TURBO、GPT-3.5-TURBO-0125、GPT-3.5-TURBO-1106。更多信息,请参 models 页面。 gpt-3.5-turbo
spring.ai.openai.chat.options.temperature 采样温度,用于控制生成的补间明显的创造性。取值越高,输出结果越随机,取值越低,结果越集中和确定。不建议针对同一个补全请求修改温度和 top_p,因为这两个设置之间的相互作用很难预测。 0.8
spring.ai.openai.chat.options.frequencyPenalty 介于 -2.0 和 2.0 之间的数值。正值会根据新标记在文本中的现有频率对其进行惩罚,从而降低模型逐字重复同一行的可能性。 0.0f
spring.ai.openai.chat.options.logitBias 修改指定标记在完成时出现的可能性。 -
spring.ai.openai.chat.options.maxTokens 聊天完成时要生成的最大标记数。输入词组和生成词组的总长度受模型上下文长度的限制。 -
spring.ai.openai.chat.options.n 为每条输入信息生成多少个聊天完成选项。请注意,您将根据所有选择生成的代币数量收费。请保持 n 为 1,以尽量减少费用。 1
spring.ai.openai.chat.options.presencePenalty 介于 -2.0 和 2.0 之间的数值。正值会根据新标记是否出现在文本中对其进行惩罚,从而增加模型谈论新话题的可能性。 -
spring.ai.openai.chat.options.responseFormat 指定模型必须输出的格式的对象。设置为 { "type": "json_object" } 可启用 JSON 模式,该模式可确保模型生成的信息是有效的 JSON 格式。 -
spring.ai.openai.chat.options.seed 该功能处于测试阶段。如果指定了该功能,我们的系统将尽最大努力进行确定性采样,这样,使用相同种子和参数的重复请求将返回相同的结果。 -
spring.ai.openai.chat.options.stop 最多 4 个序列,在这些序列中,API 将停止生成更多令牌。 -
spring.ai.openai.chat.options.topP 温度采样的另一种方法是核采样,即模型考虑概率质量为 top_p 的标记的结果。因此,0.1 意味着只考虑概率质量最高的 10%的标记。一般情况下,我们建议改变这一点或温度,但不能同时改变。 -
spring.ai.openai.chat.options.tools 模型可调用的工具列表。目前只支持函数作为工具。用它来提供模型可生成 JSON 输入的函数列表。 -
spring.ai.openai.chat.options.toolChoice 控制模型调用哪个函数(如果有的话)。"无 "表示模型不会调用函数,而是生成一条消息。"自动 "表示模型可以选择生成消息或调用函数。通过 {"type: "function", "function": {"name": "my_function"}}强制模型调用该函数。none 是默认值,表示没有函数。 -
spring.ai.openai.chat.options.user 代表最终用户的唯一标识符,可帮助 OpenAI 监控和检测滥用行为。 -
spring.ai.openai.chat.options.functions 由函数名称标识的函数列表,用于在单个提示请求中启用函数调用。具有这些名称的函数必须存在于 functionCallbacks 注册表中。

您可以为 ChatModel 和 EmbeddingModel 实现覆盖常用的 spring.ai.openai.base-url 和 spring.ai.openai.api-key 属性。如果设置了 spring.ai.openai.chat.base-url 和 spring.ai.openai.chat.api-key 属性,它们将优先于通用属性。如果您想为不同的模型和不同的模型端点使用不同的 OpenAI 账户,这将非常有用。

所有以 spring.ai.openai.chat.options 为前缀的属性都可以通过在提示调用中添加特定于请求的运行时选项在运行时重写。

运行时选项

OpenAiChatOptions.java 提供了模型配置,如要使用的模型、温度、频率惩罚等。

启动时,可使用 OpenAiChatModel(api, options) 构造函数或 spring.ai.openai.chat.options.* 属性配置默认选项。

在运行时,您可以通过在提示调用中添加新的、针对特定请求的选项来覆盖默认选项。例如,覆盖特定请求的默认模型和温度:

java 复制代码
ChatResponse response = chatModel.call(
    new Prompt(
        "Generate the names of 5 famous pirates.",
        OpenAiChatOptions.builder()
            .withModel("gpt-4-32k")
            .withTemperature(0.4)
        .build()
    ));

除了模型专用的 OpenAiChatOptions 之外,您还可以使用通过 ChatOptionsBuilder#builder() 创建的便携式 ChatOptions 实例。

功能调用

您可以向 OpenAiChatModel 注册自定义 Java 函数,并让 OpenAI 模型智能地选择输出包含参数的 JSON 对象,以调用一个或多个已注册函数。这是一种将 LLM 功能与外部工具和 API 相连接的强大技术。了解有关 OpenAI 函数调用的更多信息。

多模态

多模态是指模型能够同时理解和处理来自不同来源的信息,包括文本、图像、音频和其他数据格式。目前,OpenAI gpt-4-visual-preview 和 gpt-4o 模型提供多模态支持。更多信息,请参阅视觉指南。

OpenAI 用户消息 API 可将 base64 编码的图片或图片 url 列表与消息结合在一起。Spring AI 的消息接口通过引入 "媒体"(Media)类型,为多模态 AI 模型提供了便利。该类型包含有关消息中媒体附件的数据和详细信息,利用 Spring 的 org.springframework.util.MimeType 和 java.lang.Object 来处理原始媒体数据。

下面是从 OpenAiChatModelIT.java 中摘录的代码示例,说明如何使用GPT_4_VISION_PREVIEW 模型将用户文本与图像融合。

java 复制代码
byte[] imageData = new ClassPathResource("/multimodal.test.png").getContentAsByteArray();

var userMessage = new UserMessage("Explain what do you see on this picture?",
        List.of(new Media(MimeTypeUtils.IMAGE_PNG, imageData)));

ChatResponse response = chatModel.call(new Prompt(List.of(userMessage),
        OpenAiChatOptions.builder().withModel(OpenAiApi.ChatModel.GPT_4_VISION_PREVIEW.getValue()).build()));

或使用 GPT_4_O 模型的等效图像 URL :

java 复制代码
var userMessage = new UserMessage("Explain what do you see on this picture?",
        List.of(new Media(MimeTypeUtils.IMAGE_PNG,
                "https://docs.spring.io/spring-ai/reference/1.0-SNAPSHOT/_images/multimodal.test.png")));

ChatResponse response = chatModel.call(new Prompt(List.of(userMessage),
        OpenAiChatOptions.builder().withModel(OpenAiApi.ChatModel.GPT_4_O.getValue()).build()));

也可以传递多个图像。

它的输入是 multimodal.test.png 图像:

以及文本信息 "解释一下您在这张图片上看到了什么?

这是一个设计简单的水果碗。该水果碗由金属制成,金属丝边缘呈弧形,形成一个开放式结构。

形成一个开放式结构,让水果从各个角度都能一览无余。碗内有两根

黄色的香蕉,上面放着一个红色的苹果。从香蕉皮上的棕色斑点可以看出,香蕉稍微有点过熟。

从香蕉皮上的棕色斑点可以看出。碗的顶部有一个金属环,可能是用来作为提手的。

便于携带。碗放在一个平面上,背景为中性色,可以清楚地看到里面的水果。

可以清楚地看到里面的水果。

示例Controller

创建一个新的 Spring Boot 项目,并将 spring-ai-openai-spring-boot-starter 添加到你的 pom(或 gradle)依赖项中。

在 src/main/resources 目录下添加 application.properties 文件,以启用和配置 OpenAi 聊天模型:

XML 复制代码
spring.ai.openai.api-key=YOUR_API_KEY
spring.ai.openai.chat.options.model=gpt-3.5-turbo
spring.ai.openai.chat.options.temperature=0.7

将 api-key 替换为您的 OpenAI 凭据。

这将创建一个 OpenAiChatModel 实现,您可以将其注入到您的类中。下面是一个使用聊天模型生成文本的简单 @Controller 类的示例。

java 复制代码
@RestController
public class ChatController {

    private final OpenAiChatModel chatModel;

    @Autowired
    public ChatController(OpenAiChatModel chatModel) {
        this.chatModel = chatModel;
    }

    @GetMapping("/ai/generate")
    public Map generate(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
        return Map.of("generation", chatModel.call(message));
    }

    @GetMapping("/ai/generateStream")
	public Flux<ChatResponse> generateStream(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
        Prompt prompt = new Prompt(new UserMessage(message));
        return chatModel.stream(prompt);
    }
}

手动配置

OpenAiChatModel 实现了 ChatModel 和 StreamingChatModel,并使用底层 OpenAiApi Client 连接到 OpenAI 服务。

在项目的 Maven pom.xml 文件中添加 Spring-ai-openai 依赖关系:

XML 复制代码
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-openai</artifactId>
</dependency>

或 Gradle build.gradle 构建文件。

XML 复制代码
dependencies {
    implementation 'org.springframework.ai:spring-ai-openai'
}

请参阅 "依赖关系管理 "部分,将 Spring AI BOM 添加到构建文件中。

接下来,创建 OpenAiChatModel 并将其用于文本生成:

java 复制代码
var openAiApi = new OpenAiApi(System.getenv("OPENAI_API_KEY"));
var openAiChatOptions = OpenAiChatOptions.builder()
            .withModel("gpt-3.5-turbo")
            .withTemperature(0.4)
            .withMaxTokens(200)
        .build();
var chatModel = new OpenAiChatModel(openAiApi, openAiChatOptions)


ChatResponse response = chatModel.call(
    new Prompt("Generate the names of 5 famous pirates."));

// Or with streaming responses
Flux<ChatResponse> response = chatModel.stream(
    new Prompt("Generate the names of 5 famous pirates."));

OpenAiChatOptions 为聊天请求提供配置信息。OpenAiChatOptions.Builder 是一个流畅的选项生成器。

Low-level OpenAiApi 客户端

OpenAiApi 是 OpenAI Chat API 的轻量级 Java 客户端。

下面的类图说明了 OpenAiApi 聊天接口和构建模块:

下面是一个如何以编程方式使用 api 的简单片段:

java 复制代码
OpenAiApi openAiApi =
    new OpenAiApi(System.getenv("OPENAI_API_KEY"));

ChatCompletionMessage chatCompletionMessage =
    new ChatCompletionMessage("Hello world", Role.USER);

// Sync request
ResponseEntity<ChatCompletion> response = openAiApi.chatCompletionEntity(
    new ChatCompletionRequest(List.of(chatCompletionMessage), "gpt-3.5-turbo", 0.8f, false));

// Streaming request
Flux<ChatCompletionChunk> streamResponse = openAiApi.chatCompletionStream(
        new ChatCompletionRequest(List.of(chatCompletionMessage), "gpt-3.5-turbo", 0.8f, true));

更多信息请参阅 OpenAiApi.java 的 JavaDoc。

Low-level接口示例

  • OpenAiApiIT.java 测试提供了一些如何使用轻量级库的一般示例。
  • OpenAiApiToolFunctionCallIT.java 测试展示了如何使用底层 API 调用工具函数。基于 OpenAI 函数调用教程。

下一章节:Spring AI 第二讲 之 Chat Model API 第一节Ollama Chat

代码演练后期补充

相关推荐
小鑫记得努力5 分钟前
Java类和对象(下篇)
java
撞南墙者6 分钟前
OpenCV自学系列(1)——简介和GUI特征操作
人工智能·opencv·计算机视觉
OCR_wintone4217 分钟前
易泊车牌识别相机,助力智慧工地建设
人工智能·数码相机·ocr
binishuaio9 分钟前
Java 第11天 (git版本控制器基础用法)
java·开发语言·git
zz.YE11 分钟前
【Java SE】StringBuffer
java·开发语言
老友@11 分钟前
aspose如何获取PPT放映页“切换”的“持续时间”值
java·powerpoint·aspose
颜淡慕潇20 分钟前
【K8S问题系列 |1 】Kubernetes 中 NodePort 类型的 Service 无法访问【已解决】
后端·云原生·容器·kubernetes·问题解决
wrx繁星点点26 分钟前
状态模式(State Pattern)详解
java·开发语言·ui·设计模式·状态模式
王哈哈^_^29 分钟前
【数据集】【YOLO】【VOC】目标检测数据集,查找数据集,yolo目标检测算法详细实战训练步骤!
人工智能·深度学习·算法·yolo·目标检测·计算机视觉·pyqt
Upaaui29 分钟前
Aop+自定义注解实现数据字典映射
java