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