Nous utilisons des cookies. Les cookies et le stockage du navigateur vous gardent connecté et mémorisent vos préférences. Avec votre accord, nous mesurons aussi l’utilisation du site. Vous pouvez à tout moment. Consultez notre politique relative aux cookies.

Java

Guides SDK

Java

Utilisez openai-java avec api14 : client, chat, streaming, appel d'outils, sorties structurées, vision, gestion des erreurs, délais et nouvelles tentatives.

Utilisez la bibliothèque officielle openai-java avec api14. Définissez baseUrl sur le builder du client et passez les identifiants de modèle (par exemple openai/gpt-5-mini) comme simples chaînes.

Installation

Gradle :

implementation("com.openai:openai-java:4.+")

Maven :

<dependency>
  <groupId>com.openai</groupId>
  <artifactId>openai-java</artifactId>
  <version>LATEST</version>
</dependency>

Définissez ensuite API14_API_KEY=sk-api14-... dans votre environnement.

Configuration

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() lit à la place OPENAI_BASE_URL et OPENAI_API_KEY, ce qui permet de changer d'environnement sans modifier le code :

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

Voir Streaming.

Appel d'outils

Décrivez un outil sous forme de classe ; le SDK en déduit le JSON Schema et réanalyse les arguments dans cette classe :

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)) // votre fonction
            .build());
    }
}

Le builder conserve toute la conversation : chaque tour de boucle ajoute le message de l'assistant avec ses appels d'outils, puis un message d'outil par appel, et renvoie le tout. Les champs de la classe d'outil deviennent les propriétés du schéma ; ajoutez @JsonPropertyDescription à un champ pour indiquer au modèle ce qu'il signifie. Plafonnez le nombre d'itérations dans le code de production afin qu'un modèle qui n'arrête pas d'appeler des outils ne boucle pas indéfiniment. Voir Appel d'outils.

Sortie structurée

Passez une classe à responseFormat ; le SDK génère un JSON Schema strict à partir de celle-ci et analyse le contenu de chaque choix en une instance. Utilisez un modèle qui liste structured_outputs ou response_format dans ses 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));

Voir Sorties structurées.

Image en entrée

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") // ou une URL data:image/png;base64,...
                .build())
            .build())))
    .build();

Voir Vision et fichiers.

Paramètres supplémentaires

Les champs de la passerelle sans setter typé (reasoning, provider, models) passent par 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();

Erreurs

Les réponses non 2xx lèvent des sous-classes de OpenAIServiceException, qui exposent le statut et les en-têtes :

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

Voir Erreurs.

Délais d'attente et nouvelles tentatives

Par défaut, le client réessaie deux fois les erreurs de connexion, 408, 409, 429 et 5xx avec un backoff exponentiel. Configurez le nombre de tentatives et le délai sur le builder, ou par requête :

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

Le délai défini sur le builder s'applique à chaque tentative. Les longues requêtes de raisonnement peuvent durer plusieurs minutes : donnez-leur un délai par requête plus long ou diffusez-les en streaming. Réessayer n'aide pas face à daily_limit_reached ou insufficient_balance ; interceptez RateLimitException et vérifiez le code d'erreur avant de planifier une nouvelle tentative. Voir Limites de débit.

Toutes les capacités

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