SDK-Leitfäden
Java
Nutzen Sie die offizielle openai-java-Bibliothek mit api14: Base URL setzen, Chat, Streaming, Tool Calling, strukturierte Ausgabe und Fehlerbehandlung in Java.
Nutzen Sie die offizielle Bibliothek openai-java mit api14. Setzen Sie baseUrl im Client-Builder und übergeben Sie Modell-IDs (zum Beispiel openai/gpt-5-mini) als einfache Strings.
Installation
Gradle:
implementation("com.openai:openai-java:4.+")
Maven:
<dependency>
<groupId>com.openai</groupId>
<artifactId>openai-java</artifactId>
<version>LATEST</version>
</dependency>
Setzen Sie dann API14_API_KEY=sk-api14-... in Ihrer Umgebung.
Konfiguration
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
OpenAIClient client = OpenAIOkHttpClient.builder()
.baseUrl("https://api14.com/api/v1")
.apiKey(System.getenv("API14_API_KEY"))
.build();
OpenAIOkHttpClient.fromEnv() liest stattdessen OPENAI_BASE_URL und OPENAI_API_KEY, sodass Sie Umgebungen ohne Codeänderung wechseln können:
export OPENAI_BASE_URL="https://api14.com/api/v1"
export OPENAI_API_KEY="sk-api14-..."
Chat
import com.openai.models.chat.completions.ChatCompletion;
import com.openai.models.chat.completions.ChatCompletionCreateParams;
ChatCompletionCreateParams params = ChatCompletionCreateParams.builder()
.model("openai/gpt-5-mini")
.addUserMessage("Explain vector databases in two sentences.")
.build();
ChatCompletion completion = client.chat().completions().create(params);
completion.choices().get(0).message().content().ifPresent(System.out::println);
Streaming
import com.openai.core.http.StreamResponse;
import com.openai.models.chat.completions.ChatCompletionChunk;
ChatCompletionCreateParams params = ChatCompletionCreateParams.builder()
.model("anthropic/claude-sonnet-4.5")
.addUserMessage("Write a haiku about APIs.")
.build();
try (StreamResponse<ChatCompletionChunk> stream = client.chat().completions().createStreaming(params)) {
stream.stream()
.flatMap(chunk -> chunk.choices().stream())
.flatMap(choice -> choice.delta().content().stream())
.forEach(System.out::print);
}
Siehe Streaming.
Tool Calling
Beschreiben Sie ein Tool als Klasse; das SDK leitet daraus sein JSON Schema ab und parst die Argumente zurück in diese Klasse:
import com.fasterxml.jackson.annotation.JsonClassDescription;
import com.openai.models.chat.completions.*;
import java.util.Collection;
@JsonClassDescription("Current weather for a city")
static class GetWeather {
public String city;
}
ChatCompletionCreateParams.Builder builder = ChatCompletionCreateParams.builder()
.model("openai/gpt-5-mini")
.addTool(GetWeather.class)
.addUserMessage("What's the weather in Istanbul?");
while (true) {
ChatCompletionMessage message = client.chat().completions().create(builder.build())
.choices().get(0).message();
builder.addMessage(message);
if (message.toolCalls().map(Collection::isEmpty).orElse(true)) {
message.content().ifPresent(System.out::println);
break;
}
for (ChatCompletionMessageToolCall call : message.toolCalls().get()) {
GetWeather args = call.asFunction().function().arguments(GetWeather.class);
builder.addMessage(ChatCompletionToolMessageParam.builder()
.toolCallId(call.asFunction().id())
.contentAsJson(getWeather(args.city)) // Ihre Funktion
.build());
}
}
Der Builder hält die gesamte Unterhaltung: Jede Schleife fügt die Assistant-Nachricht mit ihren Tool-Aufrufen hinzu, dann je Aufruf eine Tool-Nachricht, und sendet alles erneut. Die Felder der Tool-Klasse werden zu den Properties des Schemas; fügen Sie einem Feld @JsonPropertyDescription hinzu, um dem Modell zu sagen, was es bedeutet. Begrenzen Sie im Produktionscode die Anzahl der Iterationen, damit ein Modell, das ständig Tools aufruft, nicht endlos schleift. Siehe Tool Calling.
Strukturierte Ausgabe
Übergeben Sie eine Klasse an responseFormat; das SDK erzeugt daraus ein striktes JSON Schema und parst den Inhalt jedes Choice in eine Instanz. Verwenden Sie ein Modell, das structured_outputs oder response_format in seinen supported_parameters aufführt:
static class Person {
public String name;
public int born;
public String city;
}
StructuredChatCompletionCreateParams<Person> params = ChatCompletionCreateParams.builder()
.model("openai/gpt-5-mini")
.responseFormat(Person.class)
.addUserMessage("Extract: Ada Lovelace, born 1815 in London.")
.build();
client.chat().completions().create(params).choices().stream()
.flatMap(choice -> choice.message().content().stream())
.forEach(person -> System.out.println(person.name + " " + person.born));
Siehe Strukturierte Ausgaben.
Bildeingabe
import java.util.List;
ChatCompletionCreateParams params = ChatCompletionCreateParams.builder()
.model("google/gemini-2.5-flash")
.addUserMessageOfArrayOfContentParts(List.of(
ChatCompletionContentPart.ofText(ChatCompletionContentPartText.builder()
.text("What is in this picture?").build()),
ChatCompletionContentPart.ofImageUrl(ChatCompletionContentPartImage.builder()
.imageUrl(ChatCompletionContentPartImage.ImageUrl.builder()
.url("https://example.com/photo.jpg") // oder eine data:image/png;base64,...-URL
.build())
.build())))
.build();
Siehe Vision & Dateien.
Zusätzliche Parameter
Gateway-Felder ohne typisierten Setter (reasoning, provider, models) übergeben Sie über putAdditionalBodyProperty:
import com.openai.core.JsonValue;
import java.util.Map;
ChatCompletionCreateParams params = ChatCompletionCreateParams.builder()
.model("anthropic/claude-sonnet-4.5")
.addUserMessage("Prove there are infinitely many primes.")
.putAdditionalBodyProperty("reasoning", JsonValue.from(Map.of("effort", "high")))
.build();
Fehler
Antworten außerhalb von 2xx werfen Unterklassen von OpenAIServiceException, die Status und Header bereitstellen:
import com.openai.errors.OpenAIServiceException;
try {
client.chat().completions().create(params);
} catch (OpenAIServiceException e) {
if (e.statusCode() == 402) {
System.err.println("Balance too low, add funds (insufficient_balance)");
} else if (e.statusCode() == 429) {
System.err.println("Rate limited, retry after " + e.headers().values("Retry-After") + "s");
} else {
throw e;
}
}
Siehe Fehler.
Timeouts und Wiederholungen
Der Client wiederholt Verbindungsfehler, 408, 409, 429 und 5xx standardmäßig zweimal mit exponentiellem Backoff. Konfigurieren Sie Anzahl und Timeout im Builder oder pro Anfrage:
import com.openai.core.RequestOptions;
import java.time.Duration;
OpenAIClient client = OpenAIOkHttpClient.builder()
.baseUrl("https://api14.com/api/v1")
.apiKey(System.getenv("API14_API_KEY"))
.maxRetries(4)
.timeout(Duration.ofSeconds(60))
.build();
client.chat().completions().create(params,
RequestOptions.builder().timeout(Duration.ofMinutes(5)).build());
Das Timeout im Builder gilt für jeden Versuch. Lange Reasoning-Anfragen können Minuten dauern; geben Sie ihnen daher ein längeres Timeout pro Anfrage oder streamen Sie sie. Wiederholungen helfen nicht bei daily_limit_reached oder insufficient_balance; fangen Sie RateLimitException ab und prüfen Sie den Fehlercode, bevor Sie einen weiteren Versuch planen. Siehe Rate Limits.
Alle Fähigkeiten
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api14.com/api/v1",
apiKey: process.env.API14_API_KEY,
});
const result = await client.chat.completions.create({
"model": "openai/gpt-5-mini",
"messages": [
{
"role": "user",
"content": "Explain vector databases in two sentences."
}
]
});
console.log(result.choices[0].message.content);