Przewodniki SDK
Java
Użyj biblioteki openai-java z api14 w Javie: konfiguracja klienta, streaming, narzędzia, ustrukturyzowane wyjście, błędy oraz limity czasu.
Użyj oficjalnej biblioteki openai-java z api14. Ustaw baseUrl w builderze klienta i przekazuj identyfikatory modeli (na przykład openai/gpt-5-mini) jako zwykłe ciągi znaków.
Instalacja
Gradle:
implementation("com.openai:openai-java:4.+")
Maven:
<dependency>
<groupId>com.openai</groupId>
<artifactId>openai-java</artifactId>
<version>LATEST</version>
</dependency>
Następnie ustaw w środowisku API14_API_KEY=sk-api14-....
Konfiguracja
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() odczytuje zamiast tego OPENAI_BASE_URL i OPENAI_API_KEY, więc możesz przełączać środowiska bez zmian w kodzie:
export OPENAI_BASE_URL="https://api14.com/api/v1"
export OPENAI_API_KEY="sk-api14-..."
Czat
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);
}
Zobacz Streaming.
Wywoływanie narzędzi
Opisz narzędzie jako klasę; SDK wyprowadza z niej JSON Schema i parsuje argumenty z powrotem do tej klasy:
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)) // your function
.build());
}
}
Builder przechowuje całą rozmowę: każda iteracja pętli dodaje wiadomość asystenta z wywołaniami narzędzi, potem po jednej wiadomości narzędzia na każde wywołanie i wysyła wszystko ponownie. Pola klasy narzędzia stają się właściwościami schematu; dodaj @JsonPropertyDescription do pola, aby powiedzieć modelowi, co ono oznacza. W kodzie produkcyjnym ogranicz liczbę iteracji, aby model, który stale wywołuje narzędzia, nie zapętlił się w nieskończoność. Zobacz Wywoływanie narzędzi.
Ustrukturyzowane wyjście
Przekaż klasę do responseFormat; SDK generuje z niej ścisły JSON Schema i parsuje treść każdego wyboru do instancji. Użyj modelu, który ma structured_outputs lub response_format w supported_parameters:
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));
Zobacz Ustrukturyzowane wyjście.
Obraz na wejściu
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") // or a data:image/png;base64,... URL
.build())
.build())))
.build();
Zobacz Obrazy i pliki w wejściu.
Dodatkowe parametry
Pola bramki bez typowanego settera (reasoning, provider, models) przekazuj przez 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();
Błędy
Odpowiedzi inne niż 2xx rzucają podklasy OpenAIServiceException, które udostępniają status i nagłówki:
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;
}
}
Zobacz Błędy.
Limity czasu i ponowienia
Klient domyślnie ponawia błędy połączenia, 408, 409, 429 i 5xx dwukrotnie, z wykładniczym opóźnieniem. Skonfiguruj liczbę ponowień i limit czasu w builderze lub dla pojedynczego żądania:
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());
Limit czasu z buildera dotyczy każdej próby. Długie żądania z rozumowaniem mogą trwać minuty, więc daj im dłuższy limit na żądanie lub używaj streamingu. Ponawianie nie pomaga przy daily_limit_reached ani insufficient_balance; przechwyć RateLimitException i sprawdź kod błędu, zanim zaplanujesz kolejną próbę. Zobacz Limity zapytań.
Wszystkie możliwości
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);