Spring AI 通过 OpenAI Java SDK 支持 OpenAI 的语言模型,提供与 OpenAI 服务(包括微软 Foundry 和 GitHub Models)的可靠、官方维护集成。
本实现使用 OpenAI 官方提供的 Java SDK。如需替代的 Spring AI 实现,请参考 OpenAI Chat。
OpenAI SDK 模块会根据你提供的基础 URL 自动检测服务提供商(OpenAI、微软 Foundry 或 GitHub Models)。
身份验证
身份验证通过基础 URL 和 API 密钥完成。该实现通过 Spring Boot 配置属性或环境变量提供灵活的配置选项。
使用 OpenAI
若直接使用 OpenAI,请在 OpenAI 注册页面创建账户,并在 API 密钥页面生成 API 密钥。
无需设置基础 URL,其默认值为 api.openai.com/v1:
spring.ai.openai-sdk.api-key=<your-openai-api-key> # base-url 为可选配置,默认值为 https://api.openai.com/v1
或使用环境变量:
export OPENAI_API_KEY=<your-openai-api-key> # OPENAI_BASE_URL 为可选配置,默认值为 https://api.openai.com/v1
使用微软 Foundry
使用微软 Foundry URL 时会自动检测该服务。可通过配置属性进行设置:
spring.ai.openai-sdk.base-url=https://<your-deployment-url>.openai.azure.com spring.ai.openai-sdk.api-key=<your-api-key> spring.ai.openai-sdk.microsoft-deployment-name=<your-deployment-name>
或使用环境变量:
export OPENAI_BASE_URL=https://<your-deployment-url>.openai.azure.com export OPENAI_API_KEY=<your-api-key>
无密码身份验证(Azure 推荐使用):
微软 Foundry 支持无需提供 API 密钥的无密码身份验证,在 Azure 上运行时安全性更高。
启用无密码身份验证,请添加 com.azure:azure-identity 依赖:
<dependency> <groupId>com.azure</groupId> <artifactId>azure-identity</artifactId> </dependency>
随后无需配置 API 密钥即可完成设置:
spring.ai.openai-sdk.base-url=https://<your-deployment-url>.openai.azure.com spring.ai.openai-sdk.microsoft-deployment-name=<your-deployment-name> # 无需配置 api-key - 系统将使用环境中的 Azure 凭据
使用 GitHub Models
使用 GitHub Models 基础 URL 时会自动检测该服务。你需要创建具备 models:read 权限的 GitHub 个人访问令牌(PAT)。
spring.ai.openai-sdk.base-url=https://models.inference.ai.azure.com spring.ai.openai-sdk.api-key=github_pat_XXXXXXXXXXX
或使用环境变量:
export OPENAI_BASE_URL=https://models.inference.ai.azure.com export OPENAI_API_KEY=github_pat_XXXXXXXXXXX
处理 API 密钥等敏感信息时,为提升安全性,可在配置属性中使用 Spring 表达式语言(SpEL):
spring.ai.openai-sdk.api-key=${OPENAI_API_KEY}添加仓库和物料清单(BOM)
Spring AI 构件发布在 Maven 中央仓库和 Spring 快照仓库中。参考「构件仓库」章节将这些仓库添加到你的构建系统中。
为简化依赖管理,Spring AI 提供了物料清单(BOM),确保整个项目使用一致的 Spring AI 版本。参考「依赖管理」章节将 Spring AI BOM 添加到你的构建系统中。
自动配置
Spring AI 为 OpenAI SDK 聊天客户端提供 Spring Boot 自动配置。启用该功能需在项目的 Maven pom.xml 或 Gradle build.gradle 构建文件中添加以下依赖:
Maven
<dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-starter-model-openai-sdk</artifactId> </dependency>
参考「依赖管理」章节将 Spring AI BOM 添加到你的构建文件中。
配置属性
连接属性
使用前缀 spring.ai.openai-sdk 配置 OpenAI SDK 客户端。
| 属性 | 描述 | 默认值 |
|---|---|---|
| spring.ai.openai-sdk.base-url | 连接地址。未设置时自动从 OPENAI_BASE_URL 环境变量读取 | api.openai.com/v1 |
| spring.ai.openai-sdk.api-key | API 密钥。未设置时自动从 OPENAI_API_KEY 环境变量读取 | - |
| spring.ai.openai-sdk.organization-id | 可选配置,指定 API 请求使用的组织 | - |
| spring.ai.openai-sdk.timeout | 请求超时时间 | - |
| spring.ai.openai-sdk.max-retries | 请求失败的最大重试次数 | - |
| spring.ai.openai-sdk.proxy | OpenAI 客户端代理设置(Java Proxy 对象) | - |
| spring.ai.openai-sdk.custom-headers | 请求中包含的自定义 HTTP 头,为键值对映射 | - |
微软 Foundry(Azure OpenAI)属性
OpenAI SDK 实现原生支持微软 Foundry(Azure OpenAI)并支持自动配置:
| 属性 | 描述 | 默认值 |
|---|---|---|
| spring.ai.openai-sdk.microsoft-foundry | 启用微软 Foundry 模式。若基础 URL 包含 openai.azure.com、cognitiveservices.azure.com 或 .openai.microsoftFoundry.com,则自动启用 | false |
| spring.ai.openai-sdk.microsoft-deployment-name | 微软 Foundry 部署名称。未指定时使用模型名称,可通过别名 deployment-name 访问 | - |
| spring.ai.openai-sdk.microsoft-foundry-service-version | 微软 Foundry API 服务版本 | - |
| spring.ai.openai-sdk.credential | 无密码身份验证凭据对象(需要 com.azure:azure-identity 依赖) | - |
微软 Foundry 支持无密码身份验证。添加 com.azure:azure-identity 依赖后,未提供 API 密钥时,实现会自动尝试使用环境中的 Azure 凭据。
GitHub Models 属性
原生支持 GitHub Models:
| 属性 | 描述 | 默认值 |
|---|---|---|
| spring.ai.openai-sdk.github-models | 启用 GitHub Models 模式。若基础 URL 包含 models.github.ai 或 models.inference.ai.azure.com,则自动启用 | false |
GitHub Models 需要具备 models:read 权限的个人访问令牌。可通过 OPENAI_API_KEY 环境变量或 spring.ai.openai-sdk.api-key 属性设置。
聊天模型属性
使用前缀 spring.ai.openai-sdk.chat 配置聊天模型实现:
| 属性 | 描述 | 默认值 |
|---|---|---|
| spring.ai.openai-sdk.chat.options.model | 使用的 OpenAI 聊天模型名称,可选 gpt-5-mini、gpt-4o、gpt-4o-mini、gpt-4-turbo、o1、o3-mini 等,详情参考模型页面 | gpt-5-mini |
| spring.ai.openai-sdk.chat.options.temperature | 采样温度,控制生成内容的创造性。数值越高输出越随机,数值越低结果越聚焦、越确定。不建议在同一请求中同时修改 temperature 和 top_p | 1.0 |
| spring.ai.openai-sdk.chat.options.frequency-penalty | 取值范围 -2.0 至 2.0。正值会基于令牌已出现的频率降低重复生成概率 | 0.0 |
| spring.ai.openai-sdk.chat.options.logit-bias | 调整指定令牌在生成结果中出现的概率 | - |
| spring.ai.openai-sdk.chat.options.logprobs | 是否返回输出令牌的对数概率 | false |
| spring.ai.openai-sdk.chat.options.top-logprobs | 0 至 5 的整数,指定每个令牌位置返回的最可能令牌数量,需要 logprobs 设为 true | - |
| spring.ai.openai-sdk.chat.options.max-tokens | 生成的最大令牌数,适用于非推理模型(如 gpt-4o、gpt-3.5-turbo),不可用于推理模型,与 maxCompletionTokens 互斥 | - |
| spring.ai.openai-sdk.chat.options.max-completion-tokens | 生成结果的最大令牌数上限(包含输出令牌和推理令牌),推理模型必填,不可用于非推理模型,与 maxTokens 互斥 | - |
| spring.ai.openai-sdk.chat.options.n | 每个输入消息生成的聊天完成结果数量 | 1 |
| spring.ai.openai-sdk.chat.options.output-modalities | 输出模式列表,可包含 text 和 audio | - |
| spring.ai.openai-sdk.chat.options.output-audio | 音频输出参数,使用 AudioParameters 设置音色(ALLOY、ASH 等)和格式(MP3、FLAC 等) | - |
| spring.ai.openai-sdk.chat.options.presence-penalty | 取值范围 -2.0 至 2.0。正值会基于令牌是否出现过降低生成概率 | 0.0 |
| spring.ai.openai-sdk.chat.options.response-format.type | 响应格式类型:TEXT、JSON_OBJECT、JSON_SCHEMA | TEXT |
| spring.ai.openai-sdk.chat.options.response-format.json-schema | 类型为 JSON_SCHEMA 时的结构化输出 JSON 模式 | - |
| spring.ai.openai-sdk.chat.options.seed | 指定后系统会尽力实现确定性采样,保证结果可复现 | - |
| spring.ai.openai-sdk.chat.options.stop | 最多 4 个终止序列,API 遇到后停止生成令牌 | - |
| spring.ai.openai-sdk.chat.options.top-p | 核采样,作为 temperature 的替代方案 | - |
| spring.ai.openai-sdk.chat.options.user | 终端用户唯一标识,用于 OpenAI 监控和检测滥用行为 | - |
| spring.ai.openai-sdk.chat.options.parallel-tool-calls | 工具调用时是否启用并行函数调用 | true |
| spring.ai.openai-sdk.chat.options.reasoning-effort | 约束推理模型的推理力度:low、medium、high | - |
| spring.ai.openai-sdk.chat.options.verbosity | 控制模型响应的详细程度 | - |
| spring.ai.openai-sdk.chat.options.store | 是否存储本次生成结果用于 OpenAI 模型蒸馏或评估 | false |
| spring.ai.openai-sdk.chat.options.metadata | 开发者自定义标签,用于仪表盘筛选生成结果 | - |
| spring.ai.openai-sdk.chat.options.service-tier | 指定延迟等级:auto、default、flex、priority | - |
| spring.ai.openai-sdk.chat.options.stream-options.include-usage | 流式响应中是否包含使用统计 | false |
| spring.ai.openai-sdk.chat.options.stream-options.include-obfuscation | 流式响应中是否包含混淆处理 | false |
| spring.ai.openai-sdk.chat.options.tool-choice | 控制模型调用的函数(可选) | - |
| spring.ai.openai-sdk.chat.options.internal-tool-execution-enabled | false 时 Spring AI 将工具调用代理给客户端手动处理;true(默认)时 Spring AI 内部处理函数调用 | true |
使用 gpt-5、gpt-5-mini、gpt-5-nano 等 GPT-5 模型时,不支持 temperature 参数。这类模型针对推理优化,不使用温度设置,指定该参数会报错。而 gpt-5-chat 等对话模型支持 temperature 参数。
所有以 spring.ai.openai-sdk.chat.options 为前缀的属性,都可以在运行时通过为 Prompt 调用添加请求级别的运行时选项来覆盖。
令牌限制参数:模型专用用法
OpenAI 提供两个互斥参数控制令牌生成上限:
| 参数 | 使用场景 | 兼容模型 |
|---|---|---|
| maxTokens | 非推理模型 | gpt-4o、gpt-4o-mini、gpt-4-turbo、gpt-3.5-turbo |
| maxCompletionTokens | 推理模型 | o1、o1-mini、o1-preview、o3、o4-mini 系列 |
这两个参数互斥,同时设置会触发 OpenAI 的 API 错误。
使用示例
非推理模型(gpt-4o、gpt-3.5-turbo):
ChatResponse response = chatModel.call(
new Prompt(
"用简单的语言解释量子计算。",
OpenAiSdkChatOptions.builder()
.model("gpt-4o")
.maxTokens(150) // 非推理模型使用 maxTokens
.build()
));推理模型(o1、o3 系列):
ChatResponse response = chatModel.call(
new Prompt(
"分步解这道复杂的数学题:...",
OpenAiSdkChatOptions.builder()
.model("o1-preview")
.maxCompletionTokens(1000) // 推理模型使用 maxCompletionTokens
.build()
));运行时选项
OpenAiSdkChatOptions.java 类提供模型配置,如使用的模型、温度、频率惩罚等。
启动时,可通过 OpenAiSdkChatModel(options) 构造方法或 spring.ai.openai-sdk.chat.options.* 配置属性设置默认选项。
运行时,可通过为 Prompt 调用添加新的请求级别选项覆盖默认配置。例如,覆盖指定请求的默认模型和温度:
ChatResponse response = chatModel.call(
new Prompt(
"生成5位著名海盗的名字。",
OpenAiSdkChatOptions.builder()
.model("gpt-4o")
.temperature(0.4)
.build()
));除了模型专用的 OpenAiSdkChatOptions,你还可以使用 ChatOptions#builder() 创建通用的 ChatOptions 实例。
工具调用
你可以向 OpenAiSdkChatModel 注册自定义 Java 函数或方法,让 OpenAI 模型智能选择输出包含参数的 JSON 对象,调用一个或多个注册的函数/工具。这是连接大语言模型能力与外部工具和 API 的强大技术。更多工具调用内容请参考相关文档。
使用示例:
var chatOptions = OpenAiSdkChatOptions.builder()
.toolCallbacks(List.of(
FunctionToolCallback.builder("getCurrentWeather", new WeatherService())
.description("获取指定地点的天气")
.inputType(WeatherService.Request.class)
.build()))
.build();
ChatResponse response = chatModel.call(
new Prompt("旧金山的天气怎么样?", chatOptions));多模态
多模态指模型能够同时理解和处理文本、图片、音频等多种来源信息的能力。
视觉
支持视觉多模态的 OpenAI 模型包括 gpt-4、gpt-4o、gpt-4o-mini。更多信息参考视觉指南。
Spring AI 的 Message 接口通过引入 Media 类型支持多模态 AI 模型。
以下代码示例展示用户文本与图片结合的用法:
var imageResource = new ClassPathResource("/multimodal.test.png");
var userMessage = new UserMessage(
"解释你在这张图片中看到了什么?",
List.of(new Media(MimeTypeUtils.IMAGE_PNG, imageResource)));
ChatResponse response = chatModel.call(
new Prompt(userMessage,
OpenAiSdkChatOptions.builder()
.model("gpt-4o")
.build()));或使用图片 URL:
var userMessage = new UserMessage(
"解释你在这张图片中看到了什么?",
List.of(Media.builder()
.mimeType(MimeTypeUtils.IMAGE_PNG)
.data(URI.create("https://docs.spring.io/spring-ai/reference/_images/multimodal.test.png"))
.build()));
ChatResponse response = chatModel.call(new Prompt(userMessage));也可以传递多张图片。
音频
支持音频输入的 OpenAI 模型包括 gpt-4o-audio-preview。更多信息参考音频指南。
Spring AI 支持在消息中携带 Base64 编码的音频文件。目前 OpenAI 支持以下媒体类型:audio/mp3 和 audio/wav。
音频输入示例:
var audioResource = new ClassPathResource("speech1.mp3");
var userMessage = new UserMessage(
"这段录音讲的是什么?",
List.of(new Media(MimeTypeUtils.parseMimeType("audio/mp3"), audioResource)));
ChatResponse response = chatModel.call(
new Prompt(userMessage,
OpenAiSdkChatOptions.builder()
.model("gpt-4o-audio-preview")
.build()));音频输出
gpt-4o-audio-preview 模型可以生成音频响应。
生成音频输出示例:
var userMessage = new UserMessage("给我讲一个关于 Spring 框架的笑话");
ChatResponse response = chatModel.call(
new Prompt(userMessage,
OpenAiSdkChatOptions.builder()
.model("gpt-4o-audio-preview")
.outputModalities(List.of("text", "audio"))
.outputAudio(new AudioParameters(Voice.ALLOY, AudioResponseFormat.WAV))
.build()));
String text = response.getResult().getOutput().getText(); // 音频文本转录
byte[] waveAudio = response.getResult().getOutput().getMedia().get(0).getDataAsByteArray(); // 音频数据结构化输出
OpenAI 提供自定义结构化输出 API,确保模型生成的响应严格符合你提供的 JSON 模式。
配置
你可以通过 OpenAiSdkChatOptions 构造器以编程方式设置响应格式:
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(
"如何解 8x + 7 = -23",
OpenAiSdkChatOptions.builder()
.model("gpt-4o-mini")
.responseFormat(ResponseFormat.builder()
.type(ResponseFormat.Type.JSON_SCHEMA)
.jsonSchema(jsonSchema)
.build())
.build());
ChatResponse response = chatModel.call(prompt);与 BeanOutputConverter 集成
你可以使用现有的 BeanOutputConverter 工具:
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);
String jsonSchema = outputConverter.getJsonSchema();
Prompt prompt = new Prompt(
"如何解 8x + 7 = -23",
OpenAiSdkChatOptions.builder()
.model("gpt-4o-mini")
.responseFormat(ResponseFormat.builder()
.type(ResponseFormat.Type.JSON_SCHEMA)
.jsonSchema(jsonSchema)
.build())
.build());
ChatResponse response = chatModel.call(prompt);
MathReasoning mathReasoning = outputConverter.convert(
response.getResult().getOutput().getText());示例控制器
创建新的 Spring Boot 项目,并在 pom(或 gradle)依赖中添加 spring-ai-openai-sdk。
在 src/main/resources 目录下添加 application.properties 文件配置 OpenAI SDK 聊天模型:
spring.ai.openai-sdk.api-key=YOUR_API_KEY spring.ai.openai-sdk.chat.options.model=gpt-5-mini spring.ai.openai-sdk.chat.options.temperature=0.7
将 api-key 替换为你的 OpenAI 凭据。
这会创建 OpenAiSdkChatModel 实现,你可以将其注入到类中。以下是一个简单的 @RestController 示例,使用聊天模型生成文本:
@RestController
public class ChatController {
private final OpenAiSdkChatModel chatModel;
@Autowired
public ChatController(OpenAiSdkChatModel chatModel) {
this.chatModel = chatModel;
}
@GetMapping("/ai/generate")
public Map<String,String> generate(
@RequestParam(value = "message", defaultValue = "给我讲个笑话") String message) {
return Map.of("generation", chatModel.call(message));
}
@GetMapping("/ai/generateStream")
public Flux<ChatResponse> generateStream(
@RequestParam(value = "message", defaultValue = "给我讲个笑话") String message) {
Prompt prompt = new Prompt(new UserMessage(message));
return chatModel.stream(prompt);
}
}手动配置
OpenAiSdkChatModel 实现了 ChatModel 接口,并使用官方 OpenAI Java SDK 连接 OpenAI 服务。
在项目的 Maven pom.xml 文件中添加 spring-ai-openai-sdk 依赖:
<dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-openai-sdk</artifactId> </dependency>
或在 Gradle build.gradle 构建文件中添加:
dependencies {
implementation 'org.springframework.ai:spring-ai-openai-sdk'
}参考「依赖管理」章节将 Spring AI BOM 添加到你的构建文件中。
接下来,创建 OpenAiSdkChatModel 并用于文本生成:
var chatOptions = OpenAiSdkChatOptions.builder()
.model("gpt-4o")
.temperature(0.7)
.apiKey(System.getenv("OPENAI_API_KEY"))
.build();
var chatModel = OpenAiSdkChatModel.builder()
.options(chatOptions)
.build();
ChatResponse response = chatModel.call(
new Prompt("生成5位著名海盗的名字。"));
// 或使用流式响应
Flux<ChatResponse> response = chatModel.stream(
new Prompt("生成5位著名海盗的名字。"));微软 Foundry 配置
微软 Foundry 配置:
var chatOptions = OpenAiSdkChatOptions.builder()
.baseUrl("https://your-resource.openai.azure.com")
.apiKey(System.getenv("OPENAI_API_KEY"))
.deploymentName("gpt-4")
.azureOpenAIServiceVersion(AzureOpenAIServiceVersion.V2024_10_01_PREVIEW)
.azure(true) // 启用微软 Foundry 模式
.build();
var chatModel = OpenAiSdkChatModel.builder()
.options(chatOptions)
.build();微软 Foundry 支持无密码身份验证。在项目中添加 com.azure:azure-identity 依赖,若未提供 API 密钥,实现会自动尝试使用环境中的 Azure 凭据。
GitHub Models 配置
GitHub Models 配置:
var chatOptions = OpenAiSdkChatOptions.builder()
.baseUrl("https://models.inference.ai.azure.com")
.apiKey(System.getenv("GITHUB_TOKEN"))
.model("gpt-4o")
.githubModels(true)
.build();
var chatModel = OpenAiSdkChatModel.builder()
.options(chatOptions)
.build();与 Spring AI OpenAI 的核心区别
本实现与 Spring AI OpenAI 实现在多个方面存在差异:
| 维度 | 官方 OpenAI SDK | 现有 OpenAI 实现 |
|---|---|---|
| HTTP 客户端 | OkHttp(通过官方 SDK) | Spring RestClient/WebClient |
| API 更新 | 通过 SDK 更新自动同步 | 手动维护 |
| Azure 支持 | 原生支持,含无密码认证 | 手动构建 URL |
| GitHub Models | 原生支持 | 不支持 |
| 音频/内容审核 | 暂不支持 | 完全支持 |
| 重试逻辑 | SDK 管理(指数退避) | Spring Retry(可自定义) |
| 依赖 | 官方 OpenAI SDK | Spring WebFlux |
使用 OpenAI SDK 的场景:
启动新项目
主要使用微软 Foundry 或 GitHub Models
希望自动同步 OpenAI 的 API 更新
不需要音频转录或内容审核功能
偏好官方 SDK 支持
使用 Spring AI OpenAI 的场景:
现有项目已在使用
需要音频转录或内容审核功能
需要精细化的 HTTP 控制
需要原生 Spring 响应式支持
需要自定义重试策略
可观测性
OpenAI SDK 实现通过 Micrometer 支持 Spring AI 的可观测性特性。所有聊天模型操作都已埋点,可用于监控和链路追踪。
局限性
OpenAI SDK 实现暂不支持以下功能:
音频语音生成(TTS)
音频转录
内容审核 API
文件 API 操作
这些功能在 Spring AI OpenAI 实现中可用。