쿠키를 사용합니다. 쿠키와 브라우저 저장소는 로그인 상태를 유지하고 환경설정을 기억합니다. 동의하시면 사이트 이용 방식도 측정합니다. 언제든지 할 수 있습니다. 자세한 내용은 쿠키 정책을 참고하세요.

Java

SDK 가이드

Java

Java의 공식 openai-java 라이브러리 클라이언트 빌더에 baseUrl을 지정해 api14에 연결하는 방법입니다. 채팅, 스트리밍, 도구 호출, 구조화된 출력, 이미지 입력, 재시도를 다룹니다. 추가 파라미터 전달법도 있습니다.

api14에서 공식 openai-java 라이브러리를 사용하세요. 클라이언트 빌더에 baseUrl을 설정하고 모델 ID(예: openai/gpt-5-mini)를 일반 문자열로 전달합니다.

설치

Gradle:

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

Maven:

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

그런 다음 환경에 API14_API_KEY=sk-api14-...를 설정하세요.

설정

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()는 대신 OPENAI_BASE_URL과 OPENAI_API_KEY를 읽으므로, 코드 변경 없이 환경을 전환할 수 있습니다.

export OPENAI_BASE_URL="https://api14.com/api/v1"
export OPENAI_API_KEY="sk-api14-..."

채팅

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

스트리밍

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

스트리밍을 참고하세요.

도구 호출

도구를 클래스로 설명하면 SDK가 JSON Schema를 만들고 인수를 다시 그 클래스로 파싱합니다.

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)) // 직접 작성한 함수
            .build());
    }
}

빌더는 전체 대화를 유지합니다. 루프마다 도구 호출이 담긴 어시스턴트 메시지를 추가하고, 호출마다 도구 메시지를 하나씩 추가한 뒤 전체를 다시 보냅니다. 도구 클래스의 필드가 스키마의 속성이 되며, 필드에 @JsonPropertyDescription을 추가하면 모델에게 그 의미를 알려 줄 수 있습니다. 도구를 계속 호출하는 모델이 무한 루프에 빠지지 않도록 프로덕션 코드에서는 반복 횟수에 상한을 두세요. 도구 호출을 참고하세요.

구조화된 출력

클래스를 responseFormat에 전달하면 SDK가 그 클래스로 엄격한 JSON Schema를 만들고 각 choice의 내용을 인스턴스로 파싱합니다. supported_parameters에 structured_outputs 또는 response_format이 있는 모델을 사용하세요.

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

구조화된 출력을 참고하세요.

이미지 입력

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

비전 및 파일을 참고하세요.

추가 파라미터

타입이 지정된 setter가 없는 게이트웨이 필드(reasoning, provider, models)는 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();

오류

2xx가 아닌 응답은 OpenAIServiceException의 하위 클래스를 던지며, 상태와 헤더를 확인할 수 있습니다.

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

오류를 참고하세요.

타임아웃과 재시도

클라이언트는 기본적으로 연결 오류, 408, 409, 429, 5xx를 지수 백오프로 두 번 재시도합니다. 재시도 횟수와 타임아웃은 빌더에서, 또는 요청마다 설정할 수 있습니다.

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

빌더의 타임아웃은 각 시도에 적용됩니다. 긴 추론 요청은 몇 분이 걸릴 수 있으므로 요청별 타임아웃을 더 길게 주거나 스트리밍하세요. daily_limit_reached나 insufficient_balance는 재시도해도 소용없습니다. RateLimitException을 잡아 다시 시도하기 전에 오류 코드를 확인하세요. 속도 제한을 참고하세요.

모든 기능

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