跳到主要内容

OpenAI

备注

这是 OpenAI 集成的文档,它使用自定义的 Java 实现来调用 OpenAI REST API,在 Quarkus(因为使用了 Quarkus REST 客户端)和 Spring(因为使用了 Spring 的 RestClient)中效果最佳。

如果使用 Quarkus,请参阅 Quarkus LangChain4j 文档

LangChain4j 提供了 3 种不同的 OpenAI 聊天模型集成,本文档对应第 1 种:

  • OpenAI 使用自定义的 Java 实现来调用 OpenAI REST API,在 Quarkus(Quarkus REST 客户端)和 Spring(Spring RestClient)中效果最佳。
  • OpenAI Official SDK 使用官方 OpenAI Java SDK。
  • Azure OpenAI 使用 Microsoft 的 Azure SDK,如果你使用 Microsoft Java 技术栈(包括高级 Azure 身份验证机制),则效果最佳。

OpenAI 文档

Maven 依赖

纯 Java

<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-open-ai</artifactId>
<version>1.18.1</version>
</dependency>

Spring Boot

<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-open-ai-spring-boot-starter</artifactId>
<version>1.18.1-beta28</version>
</dependency>

API Key

要使用 OpenAI 模型,你需要一个 API key。 可以在这里创建。

如果没有 API key 怎么办?

如果你没有自己的 OpenAI API key,也不用担心。 你可以临时使用我们免费提供的 demo key,仅用于演示目的。 请注意:使用 demo key 时,所有发往 OpenAI API 的请求都需要经过我们的代理, 代理会在转发请求到 OpenAI API 之前注入真正的 key。 我们不会以任何方式收集或使用你的数据。 demo key 有配额限制,且仅限 gpt-4o-mini 模型,只应用于演示目的。

OpenAiChatModel model = OpenAiChatModel.builder()
.baseUrl("http://langchain4j.dev/demo/openai/v1")
.apiKey("demo")
.modelName("gpt-4o-mini")
.build();

创建 OpenAiChatModel

纯 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 中添加:

# 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 Service 使用, 也可以在需要的地方自动注入,例如:

@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);
}
}

结构化输出(Structured Outputs)

Structured Outputs 功能同时支持 工具响应格式

关于 Structured Outputs 的更多信息见此处

工具的 Structured Outputs

要为工具启用 Structured Outputs,请在构建模型时设置 .strictTools(true)

OpenAiChatModel.builder()
...
.strictTools(true)
.build(),

请注意,这会自动使所有工具参数变为必填(JSON schema 中的 required), 并为 JSON schema 中的每个 object 设置 additionalProperties=false。这是由于当前 OpenAI 的限制。

响应格式的 Structured Outputs

在使用 AI Services 时,若要为响应格式启用 Structured Outputs, 请在构建模型时设置 .supportedCapabilities(RESPONSE_FORMAT_JSON_SCHEMA).strictJsonSchema(true)

OpenAiChatModel.builder()
...
.supportedCapabilities(RESPONSE_FORMAT_JSON_SCHEMA)
.strictJsonSchema(true)
.build();

在这种情况下,AI Service 会自动从给定的 POJO 生成 JSON schema 并传递给 LLM。

Thinking / Reasoning(思考 / 推理)

该设置面向 DeepSeek

在构建 OpenAiChatModelOpenAiStreamingChatModel 时启用 returnThinking 参数后, DeepSeek API 响应中的 reasoning_content 字段会被解析, 并在 AiMessage.thinking() 中返回。

OpenAiStreamingChatModel 启用 returnThinking 后, 当 DeepSeek API 流式返回 reasoning_content 时, 会调用 StreamingChatResponseHandler.onPartialThinking()TokenStream.onPartialThinking() 回调。

以下是配置 thinking 的示例:

ChatModel model = OpenAiChatModel.builder()
.baseUrl("https://api.deepseek.com/v1")
.apiKey(System.getenv("DEEPSEEK_API_KEY"))
.modelName("deepseek-reasoner")
.returnThinking(true)
.build();

在构建 OpenAiChatModelOpenAiStreamingChatModel 时启用 sendThinking 参数后, AiMessage.thinking() 会在请求中发送给 DeepSeek API。 字段名可通过 sendThinking(boolean, String) 构建器方法配置。 默认使用 reasoning_content 字段名。

创建 OpenAiStreamingChatModel

纯 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 中添加:

# 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

ModerationModel model = OpenAiModerationModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.modelName("text-moderation-stable")
.build();

Spring Boot

application.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-1tts-1-hdgpt-4o-mini-ttsgpt-4o-mini-tts-2025-12-15 (参见 OpenAiTextToSpeechModelName)。默认语音为 alloy

纯 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-1tts-1-hdgpt-4o-mini-ttsgpt-4o-mini-tts-2025-12-15 (参见 OpenAiTextToSpeechModelName)。默认语音为 alloy

纯 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

TokenCountEstimator tokenCountEstimator = new OpenAiTokenCountEstimator("gpt-4o-mini");

设置自定义聊天请求参数

在使用 OpenAiChatModelOpenAiStreamingChatModel 时, 你可以在 HTTP 请求的 JSON body 中配置自定义聊天请求参数。 以下是启用网页搜索的示例:

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 请求 body:

{
"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 结构:

Map<String, Object> customParameters = Map.of(
"web_search_options", Map.of(
"user_location", Map.of(
"type", "approximate",
"approximate", Map.of("city", "London")
)
)
);

访问原始 HTTP 响应和 Server-Sent Events(SSE)

使用 OpenAiChatModel 时,你可以访问原始 HTTP 响应:

SuccessfulHttpResponse rawHttpResponse = ((OpenAiChatResponseMetadata) chatResponse.metadata()).rawHttpResponse();
System.out.println(rawHttpResponse.body());
System.out.println(rawHttpResponse.headers());
System.out.println(rawHttpResponse.statusCode());

使用 OpenAiStreamingChatModel 时,你可以访问原始 HTTP 响应(见上文)以及原始 Server-Sent Events:

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 模块时, 默认 HTTP 客户端为 JDK 的 java.net.http.HttpClient

你可以自定义它,或使用任意其他 HTTP 客户端。 更多信息见此处

Spring Boot

使用 langchain4j-open-ai-spring-boot-starter Spring Boot starter 时, 默认 HTTP 客户端为 Spring 的 RestClient

你可以自定义它,或使用任意其他 HTTP 客户端。 更多信息见此处

OpenAI Responses API

备注

该功能为实验性功能,未来版本可能会发生变化。

OpenAI 的 Responses API/v1/responses)是 Chat Completions API 的替代方案。

创建 OpenAiResponsesChatModel

ChatModel model = OpenAiResponsesChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.modelName("gpt-5.4")
.build();

创建 OpenAiResponsesStreamingChatModel

StreamingChatModel model = OpenAiResponsesStreamingChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.modelName("gpt-4o-mini")
.build();

OpenAiResponsesChatRequestParameters

OpenAiResponsesChatRequestParametersDefaultChatRequestParameters 基础上扩展了 Responses API 特有字段: previousResponseIdmaxToolCallsparallelToolCallstopLogprobstruncationincludeserviceTiersafetyIdentifierpromptCacheKeypromptCacheRetentionreasoningEffortreasoningSummarytextVerbositystreamIncludeObfuscationstorestrictToolsstrictJsonSchema

这些参数可以在创建模型时配置为默认值(通过构建器上的 defaultRequestParameters), 也可以通过 ChatRequest 按请求传入(按请求参数会覆盖默认值):

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 形态发送内置工具

当你希望发送 web_searchfile_search 或其他 OpenAI Responses API 工具对象, 而又不想引入额外的类型化封装时,请使用 serverTools

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();

也可以按请求配置内置工具:

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 既可以在模型构建器上配置为默认值,也可以通过 OpenAiResponsesChatRequestParameters 按请求配置。当两者都提供时,按请求的值优先生效, 并替换该请求的模型级 serverTools

serverTools 是提供商特定的,并有意镜像 OpenAI 的线格式,因此嵌套工具字段 应以普通的 Map / List 值提供。

Thinking / Reasoning(思考 / 推理)

OpenAI 推理模型(例如 gpt-5.4gpt-5-mini)支持 推理摘要, 可暴露模型内部推理的摘要。

要启用推理摘要,请在构建器上(或通过 OpenAiResponsesChatRequestParameters)将 reasoningSummary 设为 "auto"。 也可以通过 reasoningEffort 控制模型投入推理的力度。

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 后, 会在推理摘要 token 流式输出时调用 StreamingChatResponseHandler.onPartialThinking() 回调:

StreamingChatModel model = OpenAiResponsesStreamingChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.modelName("gpt-5-mini")
.reasoningEffort("low")
.reasoningSummary("auto")
.build();

AiMessage.thinking() 中的推理摘要仅供参考,无需在后续请求中回传—— OpenAI 会在各轮之间丢弃它。若要真正跨轮次保留模型的推理状态 (例如在工具调用之间),请改用下文所述的加密推理。

加密推理(在上下文中保留推理)

storefalse(默认)或你的组织启用了零数据保留时, 模型的推理上下文会在各轮之间丢失。 要保留它,请通过 include 参数请求 加密推理内容

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" 时,响应中的推理项 会包含一个不透明的加密 blob。它会自动存储在 AiMessage.attributes() 中,键名为 "encrypted_reasoning"

当你在后续请求中传回该 AiMessage(例如工具调用之后)时, 加密推理会自动包含在请求中, 使模型能够恢复其推理上下文:

// 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 之外提供了额外字段:

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, 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();

示例