Używamy plików cookie. Pliki cookie i pamięć przeglądarki pozwalają utrzymać logowanie i zapamiętać Twoje preferencje. Za Twoją zgodą mierzymy też, jak korzystasz ze strony. W każdej chwili możesz . Zobacz naszą politykę cookie.

Java

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