OpenAI
本站(springdoc.cn)中的内容来源于 spring.io ,原始版权归属于 spring.io。由 springdoc.cn 进行翻译,整理。可供个人学习、研究,未经许可,不得进行任何转载、商用或与之相关的行为。 商标声明:Spring 是 Pivotal Software, Inc. 在美国以及其他国家的商标。 |
Spring AI 支持来自 ChatGPT 母公司 OpenAI 的多种 AI 语言模型。OpenAI 通过创建行业领先的文本生成模型和嵌入技术,在推动 AI 驱动文本生成领域的发展中发挥了关键作用。
先决条件
你需要创建 OpenAI API Key 以访问 ChatGPT 模型。
在 OpenAI 注册页面 创建账户,并于 API Key 页面 生成访问令牌。
Spring AI 项目定义了名为 spring.ai.openai.api-key
的配置属性,你应将其设置为从 openai.com
获取的 API Key。
你可以在 application.properties
文件中设置此配置属性:
spring.ai.openai.api-key=<your-openai-api-key>
为提升处理 API Key 等敏感信息的安全性,可使用 Spring 表达式语言(SpEL)引用自定义环境变量:
# In application.yml
spring:
ai:
openai:
api-key: ${OPENAI_API_KEY}
# In your environment or .env file
export OPENAI_API_KEY=<your-openai-api-key>
你还可以在应用程序代码中以编程方式设置此配置:
// Retrieve API key from a secure source or environment variable
String apiKey = System.getenv("OPENAI_API_KEY");
自动配置
Spring AI 自动配置及 Starter 模块的 artifact 命名已发生重大变更。具体升级说明请参阅 更新文档。 |
Spring AI 为 OpenAI 聊天客户端提供 Spring Boot 自动配置。要启用该功能,请将以下依赖项添加到项目的 Maven pom.xml
或 Gradle build.gradle
构建文件中:
-
Maven
-
Gradle
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-openai</artifactId>
</dependency>
dependencies {
implementation 'org.springframework.ai:spring-ai-starter-model-openai'
}
请参考 依赖管理 章节,将 Spring AI BOM 添加到构建文件中。 |
聊天配置
重试配置
前缀 spring.ai.retry
用作配置属性前缀,用于配置 OpenAI 聊天模型的重试机制。
属性 | 说明 | 默认值 |
---|---|---|
spring.ai.retry.max-attempts |
最大重试次数。 |
10 |
spring.ai.retry.backoff.initial-interval |
指数退避策略的初始休眠时长。 |
2 sec. |
spring.ai.retry.backoff.multiplier |
退避间隔乘数。 |
5 |
spring.ai.retry.backoff.max-interval |
最大退避时长。 |
3 min. |
spring.ai.retry.on-client-errors |
若为 |
false |
spring.ai.retry.exclude-on-http-codes |
不应触发重试的 HTTP 状态码列表(例如用于抛出 |
empty |
spring.ai.retry.on-http-codes |
应触发重试的 HTTP 状态码列表(例如用于抛出 |
empty |
连接配置
前缀 spring.ai.openai
用作属性前缀,用于配置 OpenAI 连接参数。
属性 | 说明 | 默认值 |
---|---|---|
spring.ai.openai.base-url |
要连接到的 URL |
|
spring.ai.openai.api-key |
API Key |
- |
spring.ai.openai.organization-id |
可选参数,用于指定 API 请求使用的组织。 |
- |
spring.ai.openai.project-id |
可选参数,用于指定 API 请求使用的项目。 |
- |
对于属于多个组织的用户(或通过旧版用户 API Key访问项目),可选择性指定 API 请求使用的组织及项目。此类 API 请求的使用量将计入指定组织和项目。 |
配置属性
聊天自动配置的启用/禁用现在通过顶级属性配置,前缀为
此项变更是为了支持多模型配置。 |
前缀 spring.ai.openai.chat
用于配置 OpenAI 聊天模型实现的属性前缀。
属性 | 说明 | 默认值 |
---|---|---|
spring.ai.openai.chat.enabled (已移除且不再生效) |
启用 OpenAI 聊天模型 |
true |
spring.ai.model.chat |
启用 OpenAI 聊天模型 |
openai |
spring.ai.openai.chat.base-url |
可选参数,用于覆盖 |
- |
spring.ai.openai.chat.completions-path |
附加到 Base URL 的路径。 |
|
spring.ai.openai.chat.api-key |
可选参数,用于覆盖 |
- |
spring.ai.openai.chat.organization-id |
可选参数,用于指定 API 请求使用的组织。 |
- |
spring.ai.openai.chat.project-id |
可选参数,用于指定 API 请求使用的项目。 |
- |
spring.ai.openai.chat.options.model |
使用的 OpenAI 聊天模型名称。可选模型包括: |
|
spring.ai.openai.chat.options.temperature |
采样温度值参数,用于控制生成内容的表观创造性。较高值会使输出更随机,较低值则使结果更集中和确定。不建议在同一补全请求中同时修改 |
0.8 |
spring.ai.openai.chat.options.frequencyPenalty |
介于 -2.0 至 2.0 之间的数值。正值会根据新 Token 在当前文本中的现有频率进行惩罚,从而降低模型逐字重复相同内容的可能性。 |
0.0f |
spring.ai.openai.chat.options.logitBias |
调整指定 Token 在补全结果中出现的概率。 |
- |
spring.ai.openai.chat.options.maxTokens |
(已弃用,建议改用 |
- |
spring.ai.openai.chat.options.maxCompletionTokens |
生成补全结果时可产生的 Token 数量上限(包括可见输出 Token 和推理 Token)。 |
- |
spring.ai.openai.chat.options.n |
为每条输入消息生成的聊天补全选项数量。请注意,系统将根据所有选项生成的 Token 总数计费。保持 |
1 |
spring.ai.openai.chat.options.store |
是否存储此聊天补全请求的输出以用于模型改进。 |
false |
spring.ai.openai.chat.options.metadata |
开发者定义的标签和值,用于在聊天补全仪表板中筛选补全结果。 |
empty map |
spring.ai.openai.chat.options.output-modalities |
模型为此请求生成的输出类型。大多数模型默认生成文本。
|
- |
spring.ai.openai.chat.options.output-audio |
音频生成的参数配置。当通过 |
- |
spring.ai.openai.chat.options.presencePenalty |
介于 -2.0 和 2.0 之间的数值。正值会根据新 Token 是否已出现在当前文本中进行惩罚,从而增加模型讨论新话题的可能性。 |
- |
spring.ai.openai.chat.options.responseFormat.type |
兼容 |
- |
spring.ai.openai.chat.options.responseFormat.name |
响应格式模式名称。仅当 |
custom_schema |
spring.ai.openai.chat.options.responseFormat.schema |
响应格式 JSON模 式。仅适用于 |
- |
spring.ai.openai.chat.options.responseFormat.strict |
响应格式 JSON Schema 严格遵循级别。仅适用于 |
- |
spring.ai.openai.chat.options.seed |
该功能处于测试阶段。若指定此参数,系统将尽力进行确定性采样,使得使用相同种子和参数的重复请求应返回相同结果。 |
- |
spring.ai.openai.chat.options.stop |
最多可设置 4 个终止序列,当 API 生成到这些序列时将停止产生后续 Token。 |
- |
spring.ai.openai.chat.options.topP |
温度采样的替代方案——核采样(nucleus sampling),模型仅考虑概率质量累加达 |
- |
spring.ai.openai.chat.options.tools |
模型可调用的工具列表。当前仅支持将函数作为工具使用。通过此参数提供函数列表,模型可能为其生成 JSON 格式的输入。 |
- |
spring.ai.openai.chat.options.toolChoice |
控制模型是否调用函数及调用方式:
|
- |
spring.ai.openai.chat.options.user |
表示终端用户的唯一标识符,可帮助 OpenAI 监控和检测滥用行为。 |
- |
spring.ai.openai.chat.options.functions |
函数名称列表,用于在单次提示请求中启用函数调用功能。这些名称对应的函数必须存在于 |
- |
spring.ai.openai.chat.options.stream-usage |
(仅限流式传输)设置后将为整个请求添加包含 Token 使用统计信息的附加数据块。该数据块的 |
false |
spring.ai.openai.chat.options.parallel-tool-calls |
是否在工具使用时启用 并行函数调用。 |
true |
spring.ai.openai.chat.options.http-headers |
可选参数,为聊天补全请求添加 HTTP Header。要覆盖 |
- |
spring.ai.openai.chat.options.proxy-tool-calls |
若为 true,Spring AI 将不会内部处理函数调用,而是将其代理给客户端。此时客户端需负责处理函数调用、调度至对应函数并返回结果。若为 false(默认值), Spring AI 将在内部处理函数调用。仅适用于支持函数调用的聊天模型。 |
false |
你可覆盖 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 为前缀的属性,均可通过在 Prompt 调用中添加请求特定的 运行时属性 进行运行时覆盖。
|
运行时属性
OpenAiChatOptions.java 类提供模型配置参数,包括使用的模型、温度值、频率惩罚系数等。
启动时,默认选项可通过 OpenAiChatModel(api, options)
构造函数或 spring.ai.openai.chat.options.*
属性进行配置。
运行时,你可通过向 Prompt
调用添加新的请求特定选项来覆盖默认配置。例如,针对特定请求覆盖默认模型和温度值:
ChatResponse response = chatModel.call(
new Prompt(
"Generate the names of 5 famous pirates.",
OpenAiChatOptions.builder()
.model("gpt-4o")
.temperature(0.4)
.build()
));
除模型特定的 OpenAiChatOptions 外,你还可使用通过 ChatOptionsBuilder#builder() 创建的可移植 ChatOptions 实例。 |
函数调用
你可为 OpenAiChatModel
注册自定义 Java 函数,使 OpenAI 模型能智能输出包含参数的 JSON 对象来调用一个或多个注册函数。这是将 LLM 能力与外部工具及 API 连接的强大技术。了解更多关于 工具调用 的信息。
多模态
多模态指模型同时理解和处理多种来源信息的能力,包括文本、图像、音频及其他数据格式。OpenAI 支持文本、视觉和音频输入模态。
视觉
支持视觉多模态的 OpenAI 模型包括 gpt-4
、gpt-4o
和 gpt-4o-mini
。详情请参阅 视觉指南。
OpenAI 用户消息 API 支持将 base64 编码图像或图像 URL 列表与消息结合。Spring AI 的 Message 接口通过引入 Media 类型支持多模态 AI 模型,该类型利用 Spring 的 org.springframework.util.MimeType
和 org.springframework.core.io.Resource
处理消息中的媒体附件数据及元信息。
以下代码示例节选自 OpenAiChatModelIT.java,展示如何通过 gpt-4o
模型将用户文本与图像结合处理:
var imageResource = new ClassPathResource("/multimodal.test.png");
var userMessage = new UserMessage("Explain what do you see on this picture?",
new Media(MimeTypeUtils.IMAGE_PNG, this.imageResource));
ChatResponse response = chatModel.call(new Prompt(this.userMessage,
OpenAiChatOptions.builder().model(OpenAiApi.ChatModel.GPT_4_O.getValue()).build()));
自 2024 年 6 月 17 日起,GPT_4_VISION_PREVIEW 模型将仅对现有用户继续可用。若非现有用户,请使用 GPT_4_O 或 GPT_4_TURBO 模型。详情参见 此处。
|
或使用 gpt-4o
模型的等效图像 URL:
var userMessage = new UserMessage("Explain what do you see on this picture?",
new Media(MimeTypeUtils.IMAGE_PNG,
URI.create("https://docs.spring.io/spring-ai/reference/_images/multimodal.test.png")));
ChatResponse response = chatModel.call(new Prompt(this.userMessage,
OpenAiChatOptions.builder().model(OpenAiApi.ChatModel.GPT_4_O.getValue()).build()));
你还可以传递多张图像进行处理。 |
该示例展示模型接收 multimodal.test.png
图像作为输入:

并结合文本消息 “Explain what do you see on this picture?”,生成的响应示例如下:
This is an image of a fruit bowl with a simple design. The bowl is made of metal with curved wire edges that create an open structure, allowing the fruit to be visible from all angles. Inside the bowl, there are two yellow bananas resting on top of what appears to be a red apple. The bananas are slightly overripe, as indicated by the brown spots on their peels. The bowl has a metal ring at the top, likely to serve as a handle for carrying. The bowl is placed on a flat surface with a neutral-colored background that provides a clear view of the fruit inside.
音频
支持音频输入多模态的 OpenAI 模型包括 gpt-4o-audio-preview
。详情请参阅 音频 指南。
OpenAI 用户消息 API 支持将 base64 编码音频文件与消息结合。Spring AI 的 Message 接口通过引入 Media 类型支持多模态 AI 模型,该类型利用 Spring 的 org.springframework.util.MimeType
和 org.springframework.core.io.Resource
处理消息中的音频附件数据及元信息。当前 OpenAI 仅支持以下媒体类型:audio/mp3
和 audio/wav
。
以下代码示例节选自 OpenAiChatModelIT.java,展示如何通过 gpt-4o-audio-preview
模型将用户文本与音频文件结合处理:
var audioResource = new ClassPathResource("speech1.mp3");
var userMessage = new UserMessage("What is this recording about?",
List.of(new Media(MimeTypeUtils.parseMimeType("audio/mp3"), audioResource)));
ChatResponse response = chatModel.call(new Prompt(List.of(userMessage),
OpenAiChatOptions.builder().model(OpenAiApi.ChatModel.GPT_4_O_AUDIO_PREVIEW).build()));
你还可以传递多个音频文件进行处理。 |
输出音频
支持音频输入多模态的 OpenAI 模型包括 gpt-4o-audio-preview
。详情请参阅 音频 指南。
OpenAI Assystant Message API 可以在消息中包含一组 Base64 编码的音频文件。Spring AI 的 Message 接口通过引入 Media 类型来支持多模态 AI 模型。该类型包含有关消息中媒体附件的数据和详细信息,使用了 Spring 的 org.springframework.util.MimeType
和 org.springframework.core.io.Resource
来表示原始媒体数据。目前,OpenAI 仅支持以下音频类型:audio/mp3
和 audio/wav
。
以下是一个代码示例,演示了使用 gpt-4o-audio-preview
模型响应用户文本和音频字节数组的情况:
var userMessage = new UserMessage("Tell me joke about Spring Framework");
ChatResponse response = chatModel.call(new Prompt(List.of(userMessage),
OpenAiChatOptions.builder()
.model(OpenAiApi.ChatModel.GPT_4_O_AUDIO_PREVIEW)
.outputModalities(List.of("text", "audio"))
.outputAudio(new AudioParameters(Voice.ALLOY, AudioResponseFormat.WAV))
.build()));
String text = response.getResult().getOutput().getContent(); // audio transcript
byte[] waveAudio = response.getResult().getOutput().getMedia().get(0).getDataAsByteArray(); // audio data
你必须在 OpenAiChatOptions
中指定 audio
模态以生成音频输出。AudioParameters
类为音频输出提供语音和音频格式。
结构化输出
OpenAI 提供定制化 结构化输出 API,确保模型生成严格符合你提供的 JSON Schema
的响应。除现有的 Spring AI 模型无关 结构化输出转换器 外,这些 API 提供更精细的控制与精确度。
当前,OpenAI 支持 JSON Schema 语言格式的子集。 |
配置
Spring AI 支持通过 OpenAiChatOptions
Builder 以编程方式配置响应格式,或通过 application properties 进行配置。
使用聊天选项构建器
你可以通过 OpenAiChatOptions
Builder 以编程方式设置响应格式,如下所示:
String jsonSchema = """
{
"type": "object",
"properties": {
"steps": {
"type": "array",
"items": {
"type": "object",
"properties": {
"explanation": { "type": "string" },
"output": { "type": "string" }
},
"required": ["explanation", "output"],
"additionalProperties": false
}
},
"final_answer": { "type": "string" }
},
"required": ["steps", "final_answer"],
"additionalProperties": false
}
""";
Prompt prompt = new Prompt("how can I solve 8x + 7 = -23",
OpenAiChatOptions.builder()
.model(ChatModel.GPT_4_O_MINI)
.responseFormat(new ResponseFormat(ResponseFormat.Type.JSON_SCHEMA, this.jsonSchema))
.build());
ChatResponse response = this.openAiChatModel.call(this.prompt);
遵循 OpenAI 的 JSON Schema 语言格式子集规范。 |
集成 BeanOutputConverter 工具类
你可利用现有 BeanOutputConverter 工具类自动从 Domain 对象生成 JSON Schema,并将结构化响应转换为 Domain 实例:
-
Java
-
Kotlin
record MathReasoning(
@JsonProperty(required = true, value = "steps") Steps steps,
@JsonProperty(required = true, value = "final_answer") String finalAnswer) {
record Steps(
@JsonProperty(required = true, value = "items") Items[] items) {
record Items(
@JsonProperty(required = true, value = "explanation") String explanation,
@JsonProperty(required = true, value = "output") String output) {
}
}
}
var outputConverter = new BeanOutputConverter<>(MathReasoning.class);
var jsonSchema = this.outputConverter.getJsonSchema();
Prompt prompt = new Prompt("how can I solve 8x + 7 = -23",
OpenAiChatOptions.builder()
.model(ChatModel.GPT_4_O_MINI)
.responseFormat(new ResponseFormat(ResponseFormat.Type.JSON_SCHEMA, this.jsonSchema))
.build());
ChatResponse response = this.openAiChatModel.call(this.prompt);
String content = this.response.getResult().getOutput().getContent();
MathReasoning mathReasoning = this.outputConverter.convert(this.content);
data class MathReasoning(
val steps: Steps,
@get:JsonProperty(value = "final_answer") val finalAnswer: String) {
data class Steps(val items: Array<Items>) {
data class Items(
val explanation: String,
val output: String)
}
}
val outputConverter = BeanOutputConverter(MathReasoning::class.java)
val jsonSchema = outputConverter.jsonSchema;
val prompt = Prompt("how can I solve 8x + 7 = -23",
OpenAiChatOptions.builder()
.model(ChatModel.GPT_4_O_MINI)
.responseFormat(ResponseFormat(ResponseFormat.Type.JSON_SCHEMA, jsonSchema))
.build())
val response = openAiChatModel.call(prompt)
val content = response.getResult().getOutput().getContent()
val mathReasoning = outputConverter.convert(content)
通过 Application Properties 进行配置
或者,使用 OpenAI 自动配置时,可通过以下应用属性配置响应格式:
spring.ai.openai.api-key=YOUR_API_KEY
spring.ai.openai.chat.options.model=gpt-4o-mini
spring.ai.openai.chat.options.response-format.type=JSON_SCHEMA
spring.ai.openai.chat.options.response-format.name=MySchemaName
spring.ai.openai.chat.options.response-format.schema={"type":"object","properties":{"steps":{"type":"array","items":{"type":"object","properties":{"explanation":{"type":"string"},"output":{"type":"string"}},"required":["explanation","output"],"additionalProperties":false}},"final_answer":{"type":"string"}},"required":["steps","final_answer"],"additionalProperties":false}
spring.ai.openai.chat.options.response-format.strict=true
Sample Controller
Create a new Spring Boot project and add the spring-ai-starter-model-openai
to your pom (or gradle) dependencies.
Add an application.properties
file under the src/main/resources
directory to enable and configure the OpenAi chat model:
spring.ai.openai.api-key=YOUR_API_KEY
spring.ai.openai.chat.options.model=gpt-4o
spring.ai.openai.chat.options.temperature=0.7
将 api-key 替换为你的 OpenAI 凭证。
|
这将创建一个可注入到类中的 OpenAiChatModel
实现。以下是一个使用该聊天模型进行文本生成的简单 @RestController
类示例:
@RestController
public class ChatController {
private final OpenAiChatModel chatModel;
@Autowired
public ChatController(OpenAiChatModel chatModel) {
this.chatModel = chatModel;
}
@GetMapping("/ai/generate")
public Map<String,String> generate(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
return Map.of("generation", this.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 this.chatModel.stream(prompt);
}
}
手动配置
OpenAiChatModel 实现了 ChatModel
和 StreamingChatModel
接口,并通过 底层 OpenAiApi 客户端 连接 OpenAI 服务。
将 spring-ai-openai
依赖添加到项目的 Maven pom.xml
文件中:
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-openai</artifactId>
</dependency>
或添加到 Gradle build.gradle
构建文件中。
dependencies {
implementation 'org.springframework.ai:spring-ai-openai'
}
请参考 依赖管理 章节,将 Spring AI BOM 添加到构建文件中。 |
接下来,创建 OpenAiChatModel
实例并用于文本生成:
var openAiApi = OpenAiApi.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.build();
var openAiChatOptions = OpenAiChatOptions.builder()
.model("gpt-3.5-turbo")
.temperature(0.4)
.maxTokens(200)
.build();
var chatModel = new OpenAiChatModel(this.openAiApi, this.openAiChatOptions);
ChatResponse response = this.chatModel.call(
new Prompt("Generate the names of 5 famous pirates."));
// Or with streaming responses
Flux<ChatResponse> response = this.chatModel.stream(
new Prompt("Generate the names of 5 famous pirates."));
OpenAiChatOptions
为聊天请求提供配置信息。OpenAiApi.Builder
和 OpenAiChatOptions.Builder
分别是 API 客户端和聊天配置的 Fluent 式选项构建器。
底层 OpenAiApi 客户端
OpenAiApi 是 OpenAI Chat API 的轻量级 Java 客户端。
以下类图展示 OpenAiApi
聊天接口及核心组件:

以下是编程方式使用该 API 的简单代码片段:
OpenAiApi openAiApi = OpenAiApi.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.build();
ChatCompletionMessage chatCompletionMessage =
new ChatCompletionMessage("Hello world", Role.USER);
// Sync request
ResponseEntity<ChatCompletion> response = this.openAiApi.chatCompletionEntity(
new ChatCompletionRequest(List.of(this.chatCompletionMessage), "gpt-3.5-turbo", 0.8, false));
// Streaming request
Flux<ChatCompletionChunk> streamResponse = this.openAiApi.chatCompletionStream(
new ChatCompletionRequest(List.of(this.chatCompletionMessage), "gpt-3.5-turbo", 0.8, true));
更多信息请参考 OpenAiApi.java 的 JavaDoc 文档。
底层 API 示例
-
OpenAiApiIT.java 测试提供了使用该轻量级库的通用示例。
-
OpenAiApiToolFunctionCallIT.java 测试展示了如何使用底层 API 调用工具函数。基于 OpenAI 函数调用 教程实现。
API 密钥管理
Spring AI 通过 ApiKey
接口及其实现提供灵活的 API 密钥管理。默认实现 SimpleApiKey
适用于大多数场景,你也可创建自定义实现以满足复杂需求。
默认配置
默认情况下,Spring Boot 自动配置会使用 spring.ai.openai.api-key
属性创建 API Key Bean:
spring.ai.openai.api-key=your-api-key-here
自定义 API Key 配置
你可通过 Builder 模式使用自定义 ApiKey
实现创建 OpenAiApi
实例:
ApiKey customApiKey = new ApiKey() {
@Override
public String getValue() {
// Custom logic to retrieve API key
return "your-api-key-here";
}
};
OpenAiApi openAiApi = OpenAiApi.builder()
.apiKey(customApiKey)
.build();
// Create a chat client with the custom OpenAiApi instance
OpenAiChatClient chatClient = new OpenAiChatClient(openAiApi);
此方式适用于以下场景:
-
从安全密钥库获取 API Key
-
动态轮换 API Key
-
实现自定义 API Key 选择逻辑