主题
OpenAI
NOTE
这是 OpenAI 集成的文档,它使用对 OpenAI REST API 的自定义 Java 实现,最适合与 Quarkus(因其使用 Quarkus REST 客户端)和 Spring(因其使用 Spring 的 RestClient)搭配。
如果你使用 Quarkus,请参阅 Quarkus LangChain4j 文档。
LangChain4j 提供了 3 种不同的 OpenAI 集成来使用聊天模型,这里是第 1 种:
- OpenAI 使用对 OpenAI REST API 的自定义 Java 实现,最适合与 Quarkus(因其使用 Quarkus REST 客户端)以及 Spring(因其使用 Spring 的 RestClient)搭配。
- OpenAI 官方 SDK 使用官方的 OpenAI Java SDK。
- Azure OpenAI 使用微软的 Azure SDK,最适合在你使用微软 Java 技术栈(包括高级 Azure 认证机制)时。
OpenAI 文档
Maven 依赖
纯 Java
xml
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-open-ai</artifactId>
<version>1.22.0</version>
</dependency>Spring Boot
xml
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-open-ai-spring-boot4-starter</artifactId>
<version>1.22.0-beta32</version>
</dependency>NOTE
该 starter 需要 Spring Boot 4。在 Spring Boot 3 上,请改用 langchain4j-open-ai-spring-boot-starter。 详见 Spring Boot 集成。
API 密钥
要使用 OpenAI 模型,你需要一个 API 密钥。你可以在这里创建一个。
创建 OpenAiChatModel
纯 Java
java
ChatModel model = OpenAiChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.modelName("gpt-4o-mini")
.build();
// You can also specify default chat request parameters using ChatRequestParameters or OpenAiChatRequestParameters
ChatModel model = OpenAiChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.defaultRequestParameters(OpenAiChatRequestParameters.builder()
.modelName("gpt-4o-mini")
.build())
.build();这会以指定的默认参数创建一个 OpenAiChatModel 实例。
Spring Boot
添加到 application.properties:
properties
# Mandatory properties:
langchain4j.open-ai.chat-model.api-key=${OPENAI_API_KEY}
langchain4j.open-ai.chat-model.model-name=gpt-4o-mini
# Optional properties:
langchain4j.open-ai.chat-model.base-url=...
langchain4j.open-ai.chat-model.custom-headers=...
langchain4j.open-ai.chat-model.frequency-penalty=...
langchain4j.open-ai.chat-model.log-requests=...
langchain4j.open-ai.chat-model.log-responses=...
langchain4j.open-ai.chat-model.logit-bias=...
langchain4j.open-ai.chat-model.max-retries=...
langchain4j.open-ai.chat-model.max-completion-tokens=...
langchain4j.open-ai.chat-model.max-tokens=...
langchain4j.open-ai.chat-model.metadata=...
langchain4j.open-ai.chat-model.organization-id=...
langchain4j.open-ai.chat-model.parallel-tool-calls=...
langchain4j.open-ai.chat-model.presence-penalty=...
langchain4j.open-ai.chat-model.project-id=...
langchain4j.open-ai.chat-model.reasoning-effort=...
langchain4j.open-ai.chat-model.response-format=...
langchain4j.open-ai.chat-model.return-thinking=...
langchain4j.open-ai.chat-model.seed=...
langchain4j.open-ai.chat-model.service-tier=...
langchain4j.open-ai.chat-model.stop=...
langchain4j.open-ai.chat-model.store=...
langchain4j.open-ai.chat-model.strict-schema=...
langchain4j.open-ai.chat-model.strict-tools=...
langchain4j.open-ai.chat-model.supported-capabilities=...
langchain4j.open-ai.chat-model.temperature=...
langchain4j.open-ai.chat-model.timeout=...
langchain4j.open-ai.chat-model.top-p=
langchain4j.open-ai.chat-model.user=...
# Optional Property: Custom Parameters (user-defined key=value)
langchain4j.open-ai.chat-model.custom-parameters.<key>=<value>上文大多数参数的说明见这里。
该配置会创建一个 OpenAiChatModel bean,它可被某个 AI 服务使用,或在需要处自动注入,例如:
java
@RestController
class ChatModelController {
ChatModel chatModel;
ChatModelController(ChatModel chatModel) {
this.chatModel = chatModel;
}
@GetMapping("/model")
public String model(@RequestParam(value = "message", defaultValue = "Hello") String message) {
return chatModel.chat(message);
}
}结构化输出
关于结构化输出的更多信息,见这里。
面向工具的结构化输出
要为工具启用结构化输出特性,请在构建模型时设置 .strictTools(true):
java
OpenAiChatModel.builder()
...
.strictTools(true)
.build(),请注意,这会自动将所有工具参数变为必填(json schema 中的 required),并为 json schema 中的每个 object 设置 additionalProperties=false。这是由于当前 OpenAI 的限制所致。
面向响应格式的结构化输出
要在用 AI 服务时启用面向响应格式化的结构化输出特性,请在构建模型时设置 .supportedCapabilities(RESPONSE_FORMAT_JSON_SCHEMA) 与 .strictJsonSchema(true):
java
OpenAiChatModel.builder()
...
.supportedCapabilities(RESPONSE_FORMAT_JSON_SCHEMA)
.strictJsonSchema(true)
.build();这种情况下,AI 服务会自动从给定的 POJO 生成一个 JSON schema 并传给 LLM。
思考 / 推理
该设置面向 DeepSeek。
当在构建 OpenAiChatModel 或 OpenAiStreamingChatModel 时启用 returnThinking 参数,DeepSeek API 响应的 reasoning_content 字段会被解析,并返回在 AiMessage.thinking() 中。
当为 OpenAiStreamingChatModel 启用 returnThinking 参数时,随着 DeepSeek API 流式返回 reasoning_content,StreamingChatResponseHandler.onPartialThinking() 与 TokenStream.onPartialThinking() 回调会被调用。
下面是一个如何配置思考的示例:
java
ChatModel model = OpenAiChatModel.builder()
.baseUrl("https://api.deepseek.com/v1")
.apiKey(System.getenv("DEEPSEEK_API_KEY"))
.modelName("deepseek-reasoner")
.returnThinking(true)
.build();当在构建 OpenAiChatModel 或 OpenAiStreamingChatModel 时启用 sendThinking 参数,AiMessage.thinking() 会被包含在对 DeepSeek API 的请求中。该字段的名称可以用 sendThinking(boolean, String) builder 方法配置。默认使用 reasoning_content 字段名。
创建 OpenAiStreamingChatModel
纯 Java
java
StreamingChatModel model = OpenAiStreamingChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.modelName("gpt-4o-mini")
.build();
// You can also specify default chat request parameters using ChatRequestParameters or OpenAiChatRequestParameters
StreamingChatModel model = OpenAiStreamingChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.defaultRequestParameters(OpenAiChatRequestParameters.builder()
.modelName("gpt-4o-mini")
.build())
.build();Spring Boot
添加到 application.properties:
properties
# Mandatory properties:
langchain4j.open-ai.streaming-chat-model.api-key=${OPENAI_API_KEY}
langchain4j.open-ai.streaming-chat-model.model-name=gpt-4o-mini
# Optional properties:
langchain4j.open-ai.streaming-chat-model.base-url=...
langchain4j.open-ai.streaming-chat-model.custom-headers=...
langchain4j.open-ai.streaming-chat-model.frequency-penalty=...
langchain4j.open-ai.streaming-chat-model.log-requests=...
langchain4j.open-ai.streaming-chat-model.log-responses=...
langchain4j.open-ai.streaming-chat-model.logit-bias=...
langchain4j.open-ai.streaming-chat-model.max-retries=...
langchain4j.open-ai.streaming-chat-model.max-completion-tokens=...
langchain4j.open-ai.streaming-chat-model.max-tokens=...
langchain4j.open-ai.streaming-chat-model.metadata=...
langchain4j.open-ai.streaming-chat-model.organization-id=...
langchain4j.open-ai.streaming-chat-model.parallel-tool-calls=...
langchain4j.open-ai.streaming-chat-model.presence-penalty=...
langchain4j.open-ai.streaming-chat-model.project-id=...
langchain4j.open-ai.streaming-chat-model.reasoning-effort=...
langchain4j.open-ai.streaming-chat-model.response-format=...
langchain4j.open-ai.streaming-chat-model.return-thinking=...
langchain4j.open-ai.streaming-chat-model.seed=...
langchain4j.open-ai.streaming-chat-model.service-tier=...
langchain4j.open-ai.streaming-chat-model.stop=...
langchain4j.open-ai.streaming-chat-model.store=...
langchain4j.open-ai.streaming-chat-model.strict-schema=...
langchain4j.open-ai.streaming-chat-model.strict-tools=...
langchain4j.open-ai.streaming-chat-model.temperature=...
langchain4j.open-ai.streaming-chat-model.timeout=...
langchain4j.open-ai.streaming-chat-model.top-p=...
langchain4j.open-ai.streaming-chat-model.user=...
# Optional Property: Custom Parameters (user-defined key=value)
langchain4j.open-ai.streaming-chat-model.custom-parameters.<key>=<value>创建 OpenAiModerationModel
纯 Java
java
ModerationModel model = OpenAiModerationModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.modelName("text-moderation-stable")
.build();Spring Boot
添加到 application.properties:
properties
# Mandatory properties:
langchain4j.open-ai.moderation-model.api-key=${OPENAI_API_KEY}
langchain4j.open-ai.moderation-model.model-name=text-moderation-stable
# Optional properties:
langchain4j.open-ai.moderation-model.base-url=...
langchain4j.open-ai.moderation-model.custom-headers=...
langchain4j.open-ai.moderation-model.log-requests=...
langchain4j.open-ai.moderation-model.log-responses=...
langchain4j.open-ai.moderation-model.max-retries=...
langchain4j.open-ai.moderation-model.organization-id=...
langchain4j.open-ai.moderation-model.project-id=...
langchain4j.open-ai.moderation-model.timeout=...创建 OpenAiTextToSpeechModel
OpenAiTextToSpeechModel 通过 OpenAI Speech API 执行文本转语音(TTS)。它以包装在 Audio 对象中的原始字节返回所生成的音频。
受支持的模型有 tts-1、tts-1-hd、gpt-4o-mini-tts 与 gpt-4o-mini-tts-2025-12-15(见 OpenAiTextToSpeechModelName)。默认声音为 alloy。
纯 Java
java
import dev.langchain4j.model.audio.TextToSpeechModel;
import dev.langchain4j.model.audio.TextToSpeechRequest;
import dev.langchain4j.model.audio.TextToSpeechResponse;
import dev.langchain4j.model.openai.OpenAiTextToSpeechModel;
import dev.langchain4j.model.openai.OpenAiTextToSpeechModelName;
TextToSpeechModel model = OpenAiTextToSpeechModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.modelName(OpenAiTextToSpeechModelName.TTS_1)
.voice("alloy") // optional, defaults to "alloy"
.build();
// Convenience method (uses the model's default voice):
TextToSpeechResponse response = model.synthesize("Hello world!");
// Or with an explicit request (the voice here overrides the model default):
TextToSpeechRequest request = TextToSpeechRequest.builder()
.text("Hello world!")
.voice("nova")
.build();
TextToSpeechResponse response2 = model.synthesize(request);
byte[] audioBytes = response.audio().binaryData(); // e.g. write to an .mp3 file
String mimeType = response.audio().mimeType(); // e.g. "audio/mpeg"输入文本不得超过 4096 个字符(OpenAI Speech API 的上限);更长的输入会导致 IllegalArgumentException。
创建 OpenAiTextToSpeechModel
OpenAiTextToSpeechModel 通过 OpenAI Speech API 执行文本转语音(TTS)。它以包装在 Audio 对象中的原始字节返回所生成的音频。
受支持的模型有 tts-1、tts-1-hd、gpt-4o-mini-tts 与 gpt-4o-mini-tts-2025-12-15(见 OpenAiTextToSpeechModelName)。默认声音为 alloy。
纯 Java
java
import dev.langchain4j.model.audio.TextToSpeechModel;
import dev.langchain4j.model.audio.TextToSpeechRequest;
import dev.langchain4j.model.audio.TextToSpeechResponse;
import dev.langchain4j.model.openai.OpenAiTextToSpeechModel;
import dev.langchain4j.model.openai.OpenAiTextToSpeechModelName;
TextToSpeechModel model = OpenAiTextToSpeechModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.modelName(OpenAiTextToSpeechModelName.TTS_1)
.voice("alloy") // optional, defaults to "alloy"
.build();
// Convenience method (uses the model's default voice):
TextToSpeechResponse response = model.synthesize("Hello world!");
// Or with an explicit request (the voice here overrides the model default):
TextToSpeechRequest request = TextToSpeechRequest.builder()
.text("Hello world!")
.voice("nova")
.build();
TextToSpeechResponse response2 = model.synthesize(request);
byte[] audioBytes = response.audio().binaryData(); // e.g. write to an .mp3 file
String mimeType = response.audio().mimeType(); // e.g. "audio/mpeg"输入文本不得超过 4096 个字符(OpenAI Speech API 的上限);更长的输入会导致 IllegalArgumentException。
创建 OpenAiTokenCountEstimator
java
TokenCountEstimator tokenCountEstimator = new OpenAiTokenCountEstimator("gpt-4o-mini");设置自定义聊天请求参数
使用 OpenAiChatModel 与 OpenAiStreamingChatModel 时,你可以在 HTTP 请求的 JSON 体内为聊天请求配置自定义参数。这里是启用网页搜索的一个示例:
java
record ApproximateLocation(String city) {}
record UserLocation(String type, ApproximateLocation approximate) {}
record WebSearchOptions(UserLocation user_location) {}
WebSearchOptions webSearchOptions = new WebSearchOptions(new UserLocation("approximate", new ApproximateLocation("London")));
Map<String, Object> customParameters = Map.of("web_search_options", webSearchOptions);
ChatRequest chatRequest = ChatRequest.builder()
.messages(UserMessage.from("Where can I buy good coffee?"))
.parameters(OpenAiChatRequestParameters.builder()
.modelName("gpt-4o-mini-search-preview")
.customParameters(customParameters)
.build())
.build();
ChatModel model = OpenAiChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.logRequests(true)
.build();
ChatResponse chatResponse = model.chat(chatRequest);这会产出一个带如下请求体的 HTTP 请求:
json
{
"model" : "gpt-4o-mini-search-preview",
"messages" : [ {
"role" : "user",
"content" : "Where can I buy good coffee?"
} ],
"web_search_options" : {
"user_location" : {
"type" : "approximate",
"approximate" : {
"city" : "London"
}
}
}
}或者,自定义参数也可以指定为嵌套 map 的结构:
java
Map<String, Object> customParameters = Map.of(
"web_search_options", Map.of(
"user_location", Map.of(
"type", "approximate",
"approximate", Map.of("city", "London")
)
)
);提示词缓存
OpenAI 会缓存较长的、重复的提示词前缀,并按输入价的一小部分对缓存读取计费。下述控制项对 OpenAiChatModel/OpenAiStreamingChatModel(Chat Completions API)与 OpenAiResponsesChatModel/OpenAiResponsesStreamingChatModel(Responses API)都有效。
关于提示词缓存的更多信息可在这里找到。
promptCacheKey
promptCacheKey 是一个可选字符串,用于引导路由,使相关的请求更可能到达一台持有该缓存条目的机器。它不会把请求钉在某台机器上,也不保证缓存命中。
java
OpenAiChatModel model = OpenAiChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.modelName("gpt-5.6")
.promptCacheKey("satisfaction_judge_v1")
.build();promptCacheOptions
gpt-5.6 及更新版本会在一个*断点(breakpoint)*处精确匹配缓存前缀,而不会回退到一个更短的未标记前缀。promptCacheOptions 控制断点来自何处:
implicit—— OpenAI 在最新一条符合条件消息的末尾放置一个断点。explicit—— 只使用你设置的断点。若没有任何断点,则什么都不缓存。
java
OpenAiChatModel model = OpenAiChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.modelName("gpt-5.6")
.promptCacheOptions(OpenAiPromptCacheOptions.builder()
.mode(OpenAiPromptCacheOptions.MODE_EXPLICIT)
.ttl(OpenAiPromptCacheOptions.TTL_30M)
.build())
.build();OpenAiPromptCacheOptions.implicit() 与 OpenAiPromptCacheOptions.explicit() 是只设置模式的选项简写。
promptCacheOptions.ttl 会取代 promptCacheRetention(后者适用于比 gpt-5.6 更旧的模型)。OpenAI 会拒绝同时携带二者的请求。
promptCacheBreakpoint
SystemMessage、UserMessage 与 ToolExecutionResultMessage 各自都可被标记为一个提示词缓存断点。由于提示词缓存是基于前缀的,断点会应用在被标记消息的最后一个内容块上,从而使到该消息为止(含该消息)的一切都构成被缓存的前缀。
OpenAiPromptCacheBreakpoint.mark() 返回该消息的一个被标记副本,保持原消息不变:
java
SystemMessage systemMessage = OpenAiPromptCacheBreakpoint.mark(SystemMessage.from(SHARED_INSTRUCTIONS));
UserMessage userMessage = OpenAiPromptCacheBreakpoint.mark(UserMessage.from(LONG_DOCUMENT));
ToolExecutionResultMessage toolResult = OpenAiPromptCacheBreakpoint.mark(someToolExecutionResultMessage);标记本质上只是消息上的一个属性,因此也可手动完成——例如当你本来就在构建该消息时:
java
SystemMessage systemMessage = SystemMessage.builder()
.text(SHARED_INSTRUCTIONS)
.attributes(Map.of(OpenAiPromptCacheBreakpoint.ATTRIBUTE_KEY,
OpenAiPromptCacheBreakpoint.MODE_EXPLICIT))
.build();标记一条消息会让 LangChain4j 以内容块列表的形式发送该消息的内容,因为纯字符串形式无法携带断点。
AiMessage 无法携带断点:助手输出的块不在 OpenAI 允许在其上放置断点的块类型之中。标记一个 AiMessage,或使用除 explicit 以外的任何模式,都会快速失败,而不是产生一个 HTTP 400。
每个请求最多支持四次缓存写入,其中一次会被 implicit 模式占用。
读取缓存词元数
OpenAiTokenUsage.InputTokensDetails 会上报有多少输入词元是从提示词缓存读取、以及写入其中的:
java
OpenAiTokenUsage tokenUsage = (OpenAiTokenUsage) chatResponse.tokenUsage();
tokenUsage.inputTokensDetails().cachedTokens(); // tokens read from the cache
tokenUsage.inputTokensDetails().cacheWriteTokens(); // tokens written to the cache当模型提供者未上报 cacheWriteTokens() 时,它返回 null,这与上报为零是不同的。
访问原始 HTTP 响应与服务端事件流(SSE)
使用 OpenAiChatModel 时,你可以访问原始 HTTP 响应:
java
SuccessfulHttpResponse rawHttpResponse = ((OpenAiChatResponseMetadata) chatResponse.metadata()).rawHttpResponse();
System.out.println(rawHttpResponse.body());
System.out.println(rawHttpResponse.headers());
System.out.println(rawHttpResponse.statusCode());使用 OpenAiStreamingChatModel 时,你可以访问原始 HTTP 响应(见上)以及原始服务端事件流:
java
List<ServerSentEvent> rawServerSentEvents = ((OpenAiChatResponseMetadata) chatResponse.metadata()).rawServerSentEvents();
System.out.println(rawServerSentEvents.get(0).data());
System.out.println(rawServerSentEvents.get(0).event());HTTP 客户端
纯 Java
使用 langchain4j-open-ai 模块时,JDK 的 java.net.http.HttpClient 被用作默认 HTTP 客户端。
你可以定制它,或使用你选择的任何其他 HTTP 客户端。更多信息见这里。
Spring Boot
使用 langchain4j-open-ai-spring-boot4-starter/langchain4j-open-ai-spring-boot-starter Spring Boot starter 时,Spring 的 RestClient 被用作默认 HTTP 客户端。
你可以定制它,或使用你选择的任何其他 HTTP 客户端。更多信息见这里。
OpenAI Responses API
NOTE
该特性尚属实验性,未来版本可能变化。
OpenAI 的 Responses API(/v1/responses)是 Chat Completions API 的一种替代方案。
创建 OpenAiResponsesChatModel
java
ChatModel model = OpenAiResponsesChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.modelName("gpt-5.4")
.build();创建 OpenAiResponsesStreamingChatModel
java
StreamingChatModel model = OpenAiResponsesStreamingChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.modelName("gpt-4o-mini")
.build();自定义 HTTP 头
如果 OpenAI API 是经一个需要认证的代理、或一个期望额外 HTTP 头的网关访问的,这些头可以在 builder 上设置。它们会随每个请求发送:
java
ChatModel model = OpenAiResponsesChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.modelName("gpt-4o-mini")
.customHeaders(Map.of("Proxy-Authorization", "Basic dXNlcjpwYXNz"))
.build();若某个头的取值不是恒定的(例如一个会过期、需要刷新的 OAuth2 令牌),可以改提供一个 Supplier。它会在每个请求之前被调用:
java
ChatModel model = OpenAiResponsesChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.modelName("gpt-4o-mini")
.customHeaders(() -> Map.of("Authorization", "Bearer " + tokenProvider.currentToken()))
.build();自定义头最后应用,因此它们也可用来覆盖 LangChain4j 默认设置的那些头(例如 Authorization)。
同样的道理适用于 OpenAiResponsesStreamingChatModel。
OpenAiResponsesChatRequestParameters
OpenAiResponsesChatRequestParameters 在 DefaultChatRequestParameters 基础上扩展出 Responses API 专有字段:previousResponseId、maxToolCalls、parallelToolCalls、topLogprobs、truncation、include、serviceTier、safetyIdentifier、promptCacheKey、promptCacheRetention、promptCacheOptions、reasoningEffort、reasoningSummary、textVerbosity、streamIncludeObfuscation、store、strictTools、strictJsonSchema。
这些参数可在创建模型时配置为默认值(通过 builder 上的 defaultRequestParameters),或经 ChatRequest 逐次请求传入(逐次请求参数会覆盖默认值):
java
ChatRequest chatRequest = ChatRequest.builder()
.messages(UserMessage.from("Hello"))
.parameters(OpenAiResponsesChatRequestParameters.builder()
.modelName("gpt-4o-mini")
.previousResponseId("resp_abc123")
.store(true)
.build())
.build();配置内置 / 服务端工具
OpenAI Responses API 集成通过 serverTools 支持 OpenAI 内置工具。
serverTools以原始的 OpenAI 形状用于 OpenAI 内置工具
当你想发送像 web_search、file_search 或其他 OpenAI Responses API 工具对象这样的内置工具、而又不引入额外的带类型包装时,使用 serverTools:
java
ChatModel model = OpenAiResponsesChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.modelName("gpt-5.4")
.serverTools(List.of(
Map.of(
"type", "web_search",
"filters", Map.of("allowed_domains", List.of("openai.com", "developers.openai.com")),
"user_location", Map.of(
"type", "approximate",
"country", "US")),
Map.of(
"type", "file_search",
"vector_store_ids", List.of("vs_abc123"),
"max_num_results", 3,
"filters", Map.of(
"type", "eq",
"key", "category",
"value", "blog"))))
.build();你也可以逐次请求配置内置工具:
java
ChatRequest chatRequest = ChatRequest.builder()
.messages(UserMessage.from("What's the weather in Berlin?"))
.parameters(OpenAiResponsesChatRequestParameters.builder()
.serverTools(List.of(Map.of("type", "web_search")))
.build())
.build();
ChatResponse response = model.chat(chatRequest);serverTools 既可以作为默认值在模型 builder 上配置,也可以经 OpenAiResponsesChatRequestParameters 逐次请求配置。当二者都提供时,逐次请求的值优先,会在该请求上替换模型级的 serverTools。
serverTools 是提供者专有的,且有意识地镜像 OpenAI 的线路格式,因此嵌套的工具字段应作为常规的 Map / List 值提供。
思考 / 推理
OpenAI 推理模型(例如 gpt-5.4、gpt-5-mini)支持推理摘要,它会把模型内部推理的摘要暴露出来。
要启用推理摘要,请在 builder 上(或通过 OpenAiResponsesChatRequestParameters)将 reasoningSummary 设为 "auto"。你也可以用 reasoningEffort 控制模型在推理上投入多少精力。
java
ChatModel model = OpenAiResponsesChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.modelName("gpt-5-mini")
.reasoningEffort("low")
.reasoningSummary("auto")
.build();
ChatResponse response = model.chat("What is the capital of Germany?");
response.aiMessage().text(); // "The capital of Germany is Berlin."
response.aiMessage().thinking(); // reasoning summary text当为 OpenAiResponsesStreamingChatModel 设置了 reasoningSummary 时,随着推理摘要词元的流式返回,StreamingChatResponseHandler.onPartialThinking() 回调会被调用:
java
StreamingChatModel model = OpenAiResponsesStreamingChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.modelName("gpt-5-mini")
.reasoningEffort("low")
.reasoningSummary("auto")
.build();AiMessage.thinking() 中的推理摘要仅供参考,无需在后续请求中回传——OpenAI 会在轮次之间丢弃它。要真正在多轮之间(例如工具调用之间)保留模型的推理状态,请使用下文的加密推理。
加密推理(将推理保留在上下文中)
当 store 为 false(默认)或你的组织采用零数据保留时,模型的推理上下文会在轮次之间丢失。要保留它,请通过 include 参数请求加密推理内容:
java
ChatModel model = OpenAiResponsesChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.modelName("gpt-5-mini")
.reasoningEffort("medium")
.include(List.of("reasoning.encrypted_content"))
.build();当 include 包含 "reasoning.encrypted_content" 时,响应的推理项会包含一个不透明的加密块。它会被自动存储在 AiMessage.attributes() 下的 "encrypted_reasoning" 键中。
当你在后续请求(例如工具调用之后)把那个 AiMessage 传回时,加密推理会被自动包含进请求,从而让模型得以恢复其推理上下文:
java
// Turn 1: model calls a tool
ChatResponse response1 = model.chat(ChatRequest.builder()
.messages(userMessage)
.parameters(ChatRequestParameters.builder()
.toolSpecifications(weatherTool)
.build())
.build());
AiMessage aiMessage1 = response1.aiMessage();
// aiMessage1.attribute("encrypted_reasoning", String.class) is not null
// Turn 2: send tool result back — encrypted reasoning is sent automatically
ChatResponse response2 = model.chat(ChatRequest.builder()
.messages(
userMessage,
aiMessage1, // contains encrypted reasoning in attributes
ToolExecutionResultMessage.from(aiMessage1.toolExecutionRequests().get(0), "sunny"))
.parameters(ChatRequestParameters.builder()
.toolSpecifications(weatherTool)
.build())
.build());这对 OpenAiResponsesStreamingChatModel 同样适用。
OpenAiResponsesChatResponseMetadata
Responses API 的响应元数据在标准 ChatResponseMetadata 之外提供了额外字段:
java
OpenAiResponsesChatResponseMetadata metadata =
(OpenAiResponsesChatResponseMetadata) chatResponse.metadata();
metadata.id(); // Response ID (can be used as previousResponseId)
metadata.modelName(); // Model name used for the request
metadata.finishReason(); // Finish reason (STOP, LENGTH, TOOL_EXECUTION, CONTENT_FILTER, OTHER)
metadata.tokenUsage(); // Returns OpenAiTokenUsage with detailed token counts
metadata.createdAt(); // Timestamp when the response was created
metadata.completedAt(); // Timestamp when the response was completed
metadata.serviceTier(); // Service tier used for the request
// Raw HTTP access (same as Chat Completions API)
metadata.rawHttpResponse();
metadata.rawServerSentEvents();