Anthropic Java SDK는 Java로 작성된 애플리케이션에서 Anthropic REST API에 편리하게 접근할 수 있도록 합니다. 요청 생성에 빌더 패턴을 사용하며 동기 및 비동기 작업을 모두 지원합니다.
코드 예제가 포함된 API 기능 문서는 API 레퍼런스를 참조하세요. 이 페이지는 Java 전용 SDK 기능 및 구성을 다룹니다.
이 라이브러리는 Java 8 이상이 필요합니다.
SDK는 Java 8 이상을 지원합니다. 이 문서의 코드 예제는 JDK 25 compact source files로 작성되었으며, 단순한 void main() 진입점과 출력을 위한 IO.println()을 사용합니다. API 호출 자체는 지원되는 모든 JDK에서 동일합니다. 이전 버전에서 예제를 컴파일하려면 IO.println(...)을 System.out.println(...)으로 바꾸고 본문을 클래스 내부의 public static void main(String[] args) 안에 배치하세요.
import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;
import com.anthropic.models.messages.Message;
import com.anthropic.models.messages.MessageCreateParams;
import com.anthropic.models.messages.Model;
// `anthropic.apiKey`, `anthropic.authToken`, `anthropic.baseUrl` 시스템 속성을 사용하여 구성합니다
// 또는 `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, `ANTHROPIC_BASE_URL` 환경 변수를 사용하여 구성합니다
AnthropicClient client = AnthropicOkHttpClient.fromEnv();
MessageCreateParams params = MessageCreateParams.builder()
.maxTokens(1024L)
.addUserMessage("Hello, Claude")
.model(Model.CLAUDE_OPUS_4_8)
.build();
Message message = client.messages().create(params);시스템 속성 또는 환경 변수를 사용하여 클라이언트를 구성하세요:
import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;
// `anthropic.apiKey`, `anthropic.authToken`, `anthropic.baseUrl` 시스템 속성을 사용하여 구성합니다
// 또는 `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, `ANTHROPIC_BASE_URL` 환경 변수를 사용하여 구성합니다
AnthropicClient client = AnthropicOkHttpClient.fromEnv();또는 수동으로 구성하세요:
import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;
AnthropicClient client = AnthropicOkHttpClient.builder()
.apiKey("my-anthropic-api-key")
.build();또는 두 가지 방식을 조합하여 사용하세요:
import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;
AnthropicClient client = AnthropicOkHttpClient.builder()
// 시스템 속성 또는 환경 변수를 사용하여 구성합니다
.fromEnv()
.apiKey("my-anthropic-api-key")
.build();Workload Identity Federation을 포함한 인증 옵션에 대해서는 인증을 참조하세요.
| Setter | 시스템 속성 | 환경 변수 | 필수 여부 | 기본값 |
|---|---|---|---|---|
apiKey | anthropic.apiKey | ANTHROPIC_API_KEY | false | - |
authToken | anthropic.authToken | ANTHROPIC_AUTH_TOKEN | false | - |
baseUrl | anthropic.baseUrl | ANTHROPIC_BASE_URL | true | "https://api.anthropic.com" |
시스템 속성은 환경 변수보다 우선합니다.
동일한 애플리케이션에서 둘 이상의 클라이언트를 생성하지 마세요. 각 클라이언트에는 연결 풀과 스레드 풀이 있으며, 이는 요청 간에 공유하는 것이 더 효율적입니다.
동일한 연결 및 스레드 풀을 재사용하면서 수정된 클라이언트 구성을 일시적으로 사용하려면 클라이언트 또는 서비스에서 withOptions()를 호출하세요:
import com.anthropic.client.AnthropicClient;
AnthropicClient clientWithOptions = client.withOptions(optionsBuilder -> {
optionsBuilder.baseUrl("https://example.com");
optionsBuilder.maxRetries(42);
});withOptions() 메서드는 원래 클라이언트나 서비스에 영향을 주지 않습니다.
기본 클라이언트는 동기식입니다. 비동기 실행으로 전환하려면 async() 메서드를 호출하세요:
import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;
import com.anthropic.models.messages.Message;
import com.anthropic.models.messages.MessageCreateParams;
import com.anthropic.models.messages.Model;
AnthropicClient client = AnthropicOkHttpClient.fromEnv();
MessageCreateParams params = MessageCreateParams.builder()
.maxTokens(1024L)
.addUserMessage("Hello, Claude")
.model(Model.CLAUDE_OPUS_4_8)
.build();
CompletableFuture<Message> message = client.async().messages().create(params);또는 처음부터 비동기 클라이언트를 생성하세요:
import com.anthropic.client.AnthropicClientAsync;
import com.anthropic.client.okhttp.AnthropicOkHttpClientAsync;
import com.anthropic.models.messages.Message;
import com.anthropic.models.messages.MessageCreateParams;
import com.anthropic.models.messages.Model;
AnthropicClientAsync client = AnthropicOkHttpClientAsync.fromEnv();
MessageCreateParams params = MessageCreateParams.builder()
.maxTokens(1024L)
.addUserMessage("Hello, Claude")
.model(Model.CLAUDE_OPUS_4_8)
.build();
CompletableFuture<Message> message = client.messages().create(params);비동기 클라이언트는 대부분의 메서드가 CompletableFuture를 반환한다는 점을 제외하면 동기 클라이언트와 동일한 옵션을 지원합니다.
SDK는 응답 "청크" 스트림을 반환하는 메서드를 정의하며, 각 청크는 전체 응답을 기다리지 않고 도착하는 즉시 개별적으로 처리할 수 있습니다.
이러한 스트리밍 메서드는 동기 클라이언트에 대해 StreamResponse를 반환합니다:
import com.anthropic.core.http.StreamResponse;
import com.anthropic.models.messages.RawMessageStreamEvent;
try (StreamResponse<RawMessageStreamEvent> streamResponse = client.messages().createStreaming(params)) {
streamResponse.stream().forEach(chunk -> {
IO.println(chunk);
});
IO.println("No more chunks!");
}비동기 클라이언트의 경우 메서드는 AsyncStreamResponse를 반환합니다:
import com.anthropic.core.http.AsyncStreamResponse;
import com.anthropic.models.messages.RawMessageStreamEvent;
client.async().messages().createStreaming(params).subscribe(chunk -> {
IO.println(chunk);
});
// 스트림의 오류나 완료를 처리해야 하는 경우
client.async().messages().createStreaming(params).subscribe(new AsyncStreamResponse.Handler<>() {
@Override
public void onNext(RawMessageStreamEvent chunk) {
IO.println(chunk);
}
@Override
public void onComplete(Optional<Throwable> error) {
if (error.isPresent()) {
IO.println("Something went wrong!");
throw new RuntimeException(error.get());
} else {
IO.println("No more chunks!");
}
}
});
// 또는 futures를 사용하세요
client.async().messages().createStreaming(params)
.subscribe(chunk -> {
IO.println(chunk);
})
.onCompleteFuture()
.whenComplete((unused, error) -> {
if (error != null) {
IO.println("Something went wrong!");
throw new RuntimeException(error);
} else {
IO.println("No more chunks!");
}
});비동기 스트리밍은 현재 스레드를 차단하지 않고 스트리밍하기 위해 클라이언트별 전용 캐시 스레드 풀 Executor를 사용합니다. 다른 Executor를 사용하려면:
Executor executor = Executors.newFixedThreadPool(4);
client.async().messages().createStreaming(params).subscribe(
chunk -> IO.println(chunk), executor
);또는 streamHandlerExecutor 메서드를 사용하여 클라이언트를 전역적으로 구성하세요:
import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;
AnthropicClient client = AnthropicOkHttpClient.builder()
.fromEnv()
.streamHandlerExecutor(Executors.newFixedThreadPool(4))
.build();MessageAccumulator는 응답의 이벤트 스트림이 처리될 때 이를 기록하고, 비스트리밍 API가 반환했을 것과 유사한 Message 객체를 누적할 수 있습니다.
동기 응답의 경우 스트림 파이프라인에 Stream.peek() 호출을 추가하여 각 이벤트를 누적하세요:
import com.anthropic.core.http.StreamResponse;
import com.anthropic.helpers.MessageAccumulator;
import com.anthropic.models.messages.Message;
import com.anthropic.models.messages.RawMessageStreamEvent;
MessageAccumulator messageAccumulator = MessageAccumulator.create();
try (StreamResponse<RawMessageStreamEvent> streamResponse =
client.messages().createStreaming(createParams)) {
streamResponse.stream()
.peek(messageAccumulator::accumulate)
.flatMap(event -> event.contentBlockDelta().stream())
.flatMap(deltaEvent -> deltaEvent.delta().text().stream())
.forEach(textDelta -> IO.print(textDelta.text()));
}
Message message = messageAccumulator.message();비동기 응답의 경우 subscribe() 호출에 MessageAccumulator를 추가하세요:
import com.anthropic.helpers.MessageAccumulator;
import com.anthropic.models.messages.Message;
MessageAccumulator messageAccumulator = MessageAccumulator.create();
client.async().messages()
.createStreaming(createParams)
.subscribe(event -> messageAccumulator.accumulate(event).contentBlockDelta().stream()
.flatMap(deltaEvent -> deltaEvent.delta().text().stream())
.forEach(textDelta -> IO.print(textDelta.text())))
.onCompleteFuture()
.join();
Message message = messageAccumulator.message();BetaMessage 객체의 누적을 위한 BetaMessageAccumulator도 제공됩니다. 이는 MessageAccumulator와 동일한 방식으로 사용됩니다.
Java 예제를 포함한 전체 구조화된 출력 문서는 구조화된 출력을 참조하세요.
Claude와 함께 도구 사용을 통해 외부 도구와 함수를 AI 모델의 응답에 직접 통합할 수 있습니다. 모델은 일반 텍스트를 생성하는 대신 적절한 경우 도구나 함수를 호출하기 위한 지침(매개변수 포함)을 출력할 수 있습니다. 도구에 대한 JSON 스키마를 정의하면 모델은 해당 스키마를 사용하여 이러한 도구를 언제 어떻게 사용할지 결정합니다.
도구 사용 기능은 AI 모델의 JSON 출력이 입력 매개변수에 제공한 JSON 스키마를 준수하도록 보장하는 "strict" 모드를 지원합니다.
SDK는 임의의 Java 클래스 구조에서 도구와 그 매개변수를 자동으로 도출할 수 있습니다. 클래스 이름(스네이크 케이스로 변환됨)이 도구 이름을 제공하고, 클래스의 필드가 도구의 매개변수를 정의합니다.
도구 클래스는 최상위 클래스 또는 static 중첩 클래스로 선언하세요. 이 요구 사항은 SDK가 도구 입력을 클래스 인스턴스로 역직렬화하는 데 사용하는 Jackson Databind 라이브러리(com.fasterxml.jackson.databind)에서 비롯되며, 이 라이브러리는 비정적 내부 클래스를 인스턴스화할 수 없습니다.
import com.fasterxml.jackson.annotation.JsonClassDescription;
import com.fasterxml.jackson.annotation.JsonPropertyDescription;
enum Unit {
CELSIUS,
FAHRENHEIT;
public String toString() {
switch (this) {
case CELSIUS:
return "C";
case FAHRENHEIT:
default:
return "F";
}
}
public double fromKelvin(double temperatureK) {
switch (this) {
case CELSIUS:
return temperatureK - 273.15;
case FAHRENHEIT:
default:
return (temperatureK - 273.15) * 1.8 + 32.0;
}
}
}
@JsonClassDescription("Get the weather in a given location")
static class GetWeather {
@JsonPropertyDescription("The city and state, e.g. San Francisco, CA")
public String location;
@JsonPropertyDescription("The unit of temperature")
public Unit unit;
public Weather execute() {
double temperatureK;
switch (location) {
case "San Francisco, CA":
temperatureK = 300.0;
break;
case "New York, NY":
temperatureK = 310.0;
break;
case "Dallas, TX":
temperatureK = 305.0;
break;
default:
temperatureK = 295;
break;
}
return new Weather(String.format("%.0f%s", unit.fromKelvin(temperatureK), unit));
}
}
static class Weather {
public String temperature;
public Weather(String temperature) {
this.temperature = temperature;
}
}도구 클래스가 정의되면 MessageCreateParams.Builder.addTool(Class<T>)를 사용하여 메시지 매개변수에 추가한 다음, AI 모델의 응답에서 요청된 경우 호출하세요. BetaToolUseBlock.input(Class<T>)를 사용하여 JSON 형식의 도구 매개변수를 도구 정의 클래스의 인스턴스로 파싱할 수 있습니다.
도구를 호출한 후 BetaToolResultBlockParam.Builder.contentAsJson(Object)를 사용하여 도구의 결과를 AI 모델에 다시 전달하세요:
import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;
import com.anthropic.models.beta.messages.*;
import com.anthropic.models.messages.Model;
AnthropicClient client = AnthropicOkHttpClient.fromEnv();
MessageCreateParams.Builder createParamsBuilder = MessageCreateParams.builder()
.model(Model.CLAUDE_OPUS_4_8)
.maxTokens(2048)
.addTool(GetWeather.class)
.addUserMessage("What's the temperature in New York?");
client.beta().messages().create(createParamsBuilder.build()).content().stream()
.flatMap(contentBlock -> contentBlock.toolUse().stream())
.forEach(toolUseBlock -> createParamsBuilder
// 도구 사용이 요청되었음을 나타내는 메시지를 추가합니다.
.addAssistantMessageOfBetaContentBlockParams(
List.of(BetaContentBlockParam.ofToolUse(BetaToolUseBlockParam.builder()
.name(toolUseBlock.name())
.id(toolUseBlock.id())
.input(toolUseBlock._input())
.build())))
// 요청된 도구 사용의 결과를 담은 메시지를 추가합니다.
.addUserMessageOfBetaContentBlockParams(
List.of(BetaContentBlockParam.ofToolResult(BetaToolResultBlockParam.builder()
.toolUseId(toolUseBlock.id())
.contentAsJson(callTool(toolUseBlock))
.build()))));
client.beta().messages().create(createParamsBuilder.build()).content().stream()
.flatMap(contentBlock -> contentBlock.text().stream())
.forEach(textBlock -> IO.println(textBlock.text()));
private static Object callTool(BetaToolUseBlock toolUseBlock) {
if (!"get_weather".equals(toolUseBlock.name())) {
throw new IllegalArgumentException("Unknown tool: " + toolUseBlock.name());
}
GetWeather tool = toolUseBlock.input(GetWeather.class);
return tool != null ? tool.execute() : new Weather("unknown");
}도구 이름은 카멜 케이스 도구 클래스 이름(예: GetWeather)에서 파생되어 스네이크 케이스(예: get_weather)로 변환됩니다. 단어 경계는 현재 문자가 첫 번째 문자가 아니고, 대문자이며, 앞 문자가 소문자이거나 뒤 문자가 소문자인 곳에서 시작됩니다. 예를 들어 MyJSONParser는 my_json_parser가 되고 ParseJSON은 parse_json이 됩니다. 이 변환은 @JsonTypeName 어노테이션을 사용하여 재정의할 수 있습니다.
도구 클래스에서 파생된 JSON 스키마가 Anthropic의 제한 사항을 준수하는지 확인하기 위해 로컬 검증을 수행할 수 있습니다. 로컬 검증은 기본적으로 활성화되어 있지만 비활성화할 수 있습니다:
MessageCreateParams.Builder createParamsBuilder = MessageCreateParams.builder()
.model(Model.CLAUDE_OPUS_4_8)
.maxTokens(2048)
.addTool(GetWeather.class, JsonSchemaLocalValidation.NO)
.addUserMessage("What's the temperature in New York?");어노테이션을 사용하여 JSON 스키마에 도구에 대한 추가 정보를 추가할 수 있습니다:
@JsonClassDescription - 해당 도구를 언제 어떻게 사용하는지 자세히 설명하는 설명을 도구 클래스에 추가합니다.@JsonTypeName - 도구 이름을 스네이크 케이스로 변환된 클래스의 단순 이름이 아닌 다른 이름으로 설정합니다.@JsonPropertyDescription - 도구 매개변수에 자세한 설명을 추가합니다.@JsonIgnore - 도구 매개변수에 대해 생성된 JSON 스키마에서 public 필드 또는 getter 메서드를 제외합니다.@JsonProperty - 도구 매개변수에 대해 생성된 JSON 스키마에 비 public 필드 또는 getter 메서드를 포함합니다.SDK는 client.messages().batches() 네임스페이스에서 배치 처리를 지원합니다. 배치를 나열하고 페이지를 매기는 방법은 페이지네이션을 참조하세요.
SDK는 MultipartField 클래스를 통해 파일을 받는 메서드를 정의합니다:
import com.anthropic.core.MultipartField;
import com.anthropic.models.beta.files.FileMetadata;
import com.anthropic.models.beta.files.FileUploadParams;
FileUploadParams params = FileUploadParams.builder()
.file(
MultipartField.<InputStream>builder()
.value(Files.newInputStream(Paths.get("/path/to/file.pdf")))
.contentType("application/pdf")
.build()
)
.build();
FileMetadata fileMetadata = client.beta().files().upload(params);또는 InputStream에서:
import com.anthropic.core.MultipartField;
import com.anthropic.models.beta.files.FileMetadata;
import com.anthropic.models.beta.files.FileUploadParams;
FileUploadParams params = FileUploadParams.builder()
.file(
MultipartField.<InputStream>builder()
.value(new URL("https://example.com/path/to/file").openStream())
.filename("document.pdf")
.contentType("application/pdf")
.build()
)
.build();
FileMetadata fileMetadata = client.beta().files().upload(params);또는 메모리 내 바이트에서:
import com.anthropic.core.MultipartField;
import com.anthropic.models.beta.files.FileMetadata;
import com.anthropic.models.beta.files.FileUploadParams;
FileUploadParams params = FileUploadParams.builder()
.file(
MultipartField.<InputStream>builder()
.value(new ByteArrayInputStream("content".getBytes()))
.filename("document.txt")
.contentType("text/plain")
.build()
)
.build();
FileMetadata fileMetadata = client.beta().files().upload(params);SDK는 반드시 JSON으로 파싱되지 않는 API 응답에 대해 바이너리 응답을 반환하는 메서드를 정의합니다:
import com.anthropic.core.http.HttpResponse;
HttpResponse response = client.beta().files().download("file_id");응답 콘텐츠를 파일에 저장하려면:
import com.anthropic.core.http.HttpResponse;
try (HttpResponse response = client.beta().files().download(params)) {
Files.copy(
response.body(),
Paths.get(path),
StandardCopyOption.REPLACE_EXISTING
);
} catch (Exception e) {
IO.println("Something went wrong!");
throw new RuntimeException(e);
}또는 응답 콘텐츠를 임의의 OutputStream으로 전송하려면:
import com.anthropic.core.http.HttpResponse;
try (HttpResponse response = client.beta().files().download(params)) {
response.body().transferTo(Files.newOutputStream(Paths.get(path)));
} catch (Exception e) {
IO.println("Something went wrong!");
throw new RuntimeException(e);
}SDK는 사용자 정의 unchecked 예외 타입을 발생시킵니다:
AnthropicServiceException - HTTP 오류의 기본 클래스입니다.AnthropicIoException - I/O 네트워킹 오류입니다.AnthropicRetryableException - 재시도할 수 있는 실패를 나타내는 일반 오류입니다.AnthropicInvalidDataException - 성공적으로 파싱된 데이터를 해석하지 못한 경우입니다(예: 필수여야 하는 속성에 접근했지만 API가 예기치 않게 이를 생략한 경우).AnthropicException - 모든 예외의 기본 클래스입니다.| 상태 | 예외 |
|---|---|
| 400 | BadRequestException |
| 401 | UnauthorizedException |
| 403 | PermissionDeniedException |
| 404 | NotFoundException |
| 422 | UnprocessableEntityException |
| 429 | RateLimitException |
| 5xx | InternalServerException |
| 기타 | UnexpectedStatusCodeException |
SseException은 성공적인 초기 HTTP 응답 이후 SSE 스트리밍 중에 발생한 오류에 대해 발생합니다.
import com.anthropic.errors.*;
try {
Message message = client.messages().create(params);
} catch (RateLimitException e) {
IO.println("Rate limited, retry after: " + e.headers());
} catch (UnauthorizedException e) {
IO.println("Invalid API key");
} catch (AnthropicServiceException e) {
IO.println("API error: " + e.statusCode());
} catch (AnthropicIoException e) {
IO.println("Network error: " + e.getMessage());
}원시 응답을 사용할 때 requestId() 메서드를 사용하여 request-id 응답 헤더에 접근할 수 있습니다:
import com.anthropic.core.http.HttpResponseFor;
import com.anthropic.models.messages.Message;
HttpResponseFor<Message> message = client.messages().withRawResponse().create(params);
Optional<String> requestId = message.requestId();이를 사용하여 실패한 요청을 빠르게 로깅하고 Anthropic에 보고할 수 있습니다. 요청 디버깅에 대한 자세한 내용은 요청 ID를 참조하세요.
SDK는 기본적으로 요청 간에 짧은 지수 백오프를 사용하여 자동으로 2회 재시도합니다.
다음 오류 유형만 재시도됩니다:
API는 또한 SDK에 요청을 재시도하거나 재시도하지 않도록 명시적으로 지시할 수 있습니다.
사용자 정의 재시도 횟수를 설정하려면 maxRetries 메서드를 사용하여 클라이언트를 구성하세요:
import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;
AnthropicClient client = AnthropicOkHttpClient.builder().fromEnv().maxRetries(4).build();요청은 기본적으로 10분 후에 타임아웃됩니다.
그러나 maxTokens를 받는 메서드의 경우, 큰 maxTokens 값을 지정하고 스트리밍 중이라면 기본 타임아웃은 다음 공식을 사용하여 동적으로 계산됩니다:
Duration.ofSeconds(
Math.min(
60 * 60, // 1 hour max
Math.max(
10 * 60, // 10 minute minimum
60 * 60 * maxTokens / 128_000
)
)
)이로 인해 재정의되지 않는 한 maxTokens 매개변수에 따라 최대 60분까지 타임아웃이 조정됩니다.
비스트리밍 요청의 경우 동적 타임아웃은 maxTokens를 기준으로 최소 30초에서 최대 10분까지 조정됩니다.
요청별로 사용자 정의 타임아웃을 설정하려면:
import com.anthropic.models.messages.Message;
Message message = client
.messages()
.create(params, RequestOptions.builder().timeout(Duration.ofSeconds(30)).build());또는 클라이언트 수준에서 모든 메서드 호출에 대한 기본값을 구성하세요:
import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;
AnthropicClient client = AnthropicOkHttpClient.builder()
.fromEnv()
.timeout(Duration.ofSeconds(30))
.build();더 오래 실행되는 요청에는 스트리밍 사용을 고려하세요.
스트리밍을 사용하지 않고 큰 maxTokens 값을 설정하는 것은 피하세요. 일부 네트워크는 일정 시간이 지나면 유휴 연결을 끊을 수 있으며, 이로 인해 Anthropic으로부터 응답을 받지 못한 채 요청이 실패하거나 타임아웃될 수 있습니다. SDK는 연결을 유지하고 이러한 네트워크의 영향을 줄이기 위해 주기적으로 API에 핑을 보냅니다.
SDK는 비스트리밍 요청이 10분 이상 걸릴 것으로 예상되는 경우 오류를 발생시킵니다. 스트리밍 메서드를 사용하거나 클라이언트 또는 요청 수준에서 타임아웃을 재정의하면 이 오류가 비활성화됩니다.
SDK는 한 번에 한 페이지씩 또는 모든 페이지에 걸쳐 항목별로 페이지네이션된 결과에 접근하는 편리한 방법을 제공합니다.
모든 페이지에 걸쳐 모든 결과를 반복하려면 필요에 따라 자동으로 더 많은 페이지를 가져오는 autoPager() 메서드를 사용하세요.
import com.anthropic.models.messages.batches.BatchListPage;
import com.anthropic.models.messages.batches.MessageBatch;
BatchListPage page = client.messages().batches().list();
// Iterable로 처리
for (MessageBatch batch : page.autoPager()) {
IO.println(batch);
}
// Stream으로 처리
page.autoPager()
.stream()
.limit(50)
.forEach(batch -> IO.println(batch));비동기 클라이언트를 사용할 때 이 메서드는 AsyncStreamResponse를 반환합니다:
import com.anthropic.core.http.AsyncStreamResponse;
import com.anthropic.models.messages.batches.BatchListPageAsync;
import com.anthropic.models.messages.batches.MessageBatch;
CompletableFuture<BatchListPageAsync> pageFuture = client.async().messages().batches().list();
pageFuture.thenAccept(page -> page.autoPager().subscribe(batch -> {
IO.println(batch);
}));
// 스트림의 오류나 완료를 처리해야 하는 경우
pageFuture.thenAccept(page -> page.autoPager().subscribe(new AsyncStreamResponse.Handler<>() {
@Override
public void onNext(MessageBatch batch) {
IO.println(batch);
}
@Override
public void onComplete(Optional<Throwable> error) {
if (error.isPresent()) {
IO.println("Something went wrong!");
throw new RuntimeException(error.get());
} else {
IO.println("No more!");
}
}
}));
// 또는 futures를 사용하세요
pageFuture.thenAccept(page -> page.autoPager()
.subscribe(batch -> {
IO.println(batch);
})
.onCompleteFuture()
.whenComplete((unused, error) -> {
if (error != null) {
IO.println("Something went wrong!");
throw new RuntimeException(error);
} else {
IO.println("No more!");
}
}));개별 페이지 항목에 접근하고 다음 페이지를 수동으로 요청하려면:
import com.anthropic.models.messages.batches.BatchListPage;
import com.anthropic.models.messages.batches.MessageBatch;
BatchListPage page = client.messages().batches().list();
while (true) {
for (MessageBatch batch : page.items()) {
IO.println(batch);
}
if (!page.hasNextPage()) {
break;
}
page = page.nextPage();
}SDK의 각 클래스에는 이를 구성하기 위한 관련 빌더가 있습니다. 각 클래스는 일단 구성되면 불변입니다. 클래스에 관련 빌더가 있는 경우 toBuilder() 메서드가 있으며, 이를 사용하여 수정된 복사본을 만들기 위해 다시 빌더로 변환할 수 있습니다.
MessageCreateParams params = MessageCreateParams.builder()
.maxTokens(1024L)
.addUserMessage("Hello, Claude")
.model(Model.CLAUDE_OPUS_4_8)
.build();
// toBuilder()를 사용하여 수정된 복사본 생성
MessageCreateParams modified = params.toBuilder().maxTokens(2048L).build();각 클래스가 불변이므로 빌더 수정은 이미 빌드된 클래스 인스턴스에 영향을 주지 않습니다.
Claude API에 요청을 보내려면 Params 클래스의 인스턴스를 빌드하고 해당 클라이언트 메서드에 전달하세요. 응답이 수신되면 Java 클래스의 인스턴스로 역직렬화됩니다.
예를 들어 client.messages().create(...)는 MessageCreateParams의 인스턴스로 호출되어야 하며, Message의 인스턴스를 반환합니다.
문서화되지 않은 매개변수를 설정하려면 Params 클래스에서 putAdditionalHeader, putAdditionalQueryParam 또는 putAdditionalBodyProperty 메서드를 호출하세요:
import com.anthropic.core.JsonValue;
import com.anthropic.models.messages.MessageCreateParams;
MessageCreateParams params = MessageCreateParams.builder()
.putAdditionalHeader("Secret-Header", "42")
.putAdditionalQueryParam("secret_query_param", "42")
.putAdditionalBodyProperty("secretProperty", JsonValue.from("42"))
.build();이러한 값은 나중에 빌드된 객체에서 _additionalHeaders(), _additionalQueryParams() 및 _additionalBodyProperties() 메서드를 사용하여 접근할 수 있습니다.
이러한 메서드에 전달된 값은 이전 메서드에 전달된 값을 덮어씁니다. 보안상의 이유로 이러한 메서드는 신뢰할 수 있는 입력 데이터에만 사용하세요.
중첩된 헤더, 쿼리 매개변수 또는 본문 클래스에 문서화되지 않은 매개변수를 설정하려면:
import com.anthropic.core.JsonValue;
import com.anthropic.models.messages.MessageCreateParams;
import com.anthropic.models.messages.Metadata;
MessageCreateParams params = MessageCreateParams.builder()
.metadata(
Metadata.builder().putAdditionalProperty("secretProperty", JsonValue.from("42")).build()
)
.build();이러한 속성은 나중에 중첩된 빌드 객체에서 _additionalProperties() 메서드를 사용하여 접근할 수 있습니다.
문서화된 매개변수 또는 속성을 문서화되지 않았거나 아직 지원되지 않는 값으로 설정하려면 해당 setter에 JsonValue 객체를 전달하세요:
import com.anthropic.core.JsonValue;
import com.anthropic.models.messages.MessageCreateParams;
import com.anthropic.models.messages.Model;
MessageCreateParams params = MessageCreateParams.builder()
.maxTokens(JsonValue.from(3.14))
.addUserMessage("Hello, Claude")
.model(Model.CLAUDE_OPUS_4_8)
.build();JsonValue를 생성하는 가장 간단한 방법은 from(...) 메서드를 사용하는 것입니다:
import com.anthropic.core.JsonValue;
// 기본 JSON 값 생성
JsonValue nullValue = JsonValue.from(null);
JsonValue booleanValue = JsonValue.from(true);
JsonValue numberValue = JsonValue.from(42);
JsonValue stringValue = JsonValue.from("Hello World!");
// `["Hello", "World"]`와 동등한 JSON 배열 값 생성
JsonValue arrayValue = JsonValue.from(List.of("Hello", "World"));
// `{ "a": 1, "b": 2 }`와 동등한 JSON 객체 값 생성
JsonValue objectValue = JsonValue.from(Map.of("a", 1, "b", 2));
// 다음과 동등한 임의로 중첩된 JSON 생성:
// { "a": [1, 2], "b": [3, 4] }
JsonValue complexValue = JsonValue.from(Map.of("a", List.of(1, 2), "b", List.of(3, 4)));일반적으로 Builder 클래스의 build 메서드는 필수 매개변수 또는 속성이 설정되지 않은 경우 IllegalStateException을 발생시킵니다. 필수 매개변수 또는 속성을 강제로 생략하려면 JsonMissing을 전달하세요:
import com.anthropic.core.JsonMissing;
import com.anthropic.models.messages.MessageCreateParams;
import com.anthropic.models.messages.Model;
MessageCreateParams params = MessageCreateParams.builder()
.addUserMessage("Hello, world")
.model(Model.CLAUDE_OPUS_4_8)
.maxTokens(JsonMissing.of())
.build();문서화되지 않은 응답 속성에 접근하려면 _additionalProperties() 메서드를 호출하세요:
import com.anthropic.core.JsonValue;
Map<String, JsonValue> additionalProperties = client
.messages()
.create(params)
._additionalProperties();
JsonValue secretPropertyValue = additionalProperties.get("secretProperty");
String result = secretPropertyValue.accept(new JsonValue.Visitor<>() {
@Override
public String visitNull() {
return "It's null!";
}
@Override
public String visitBoolean(boolean value) {
return "It's a boolean!";
}
@Override
public String visitNumber(Number value) {
return "It's a number!";
}
// 다른 메서드로는 `visitMissing`, `visitString`, `visitArray`, `visitObject`가 있습니다
// 구현되지 않은 각 메서드의 기본 구현은 `visitDefault`에 위임하며,
// 이는 기본적으로 예외를 던지지만 재정의할 수도 있습니다
});속성의 원시 JSON 값에 접근하려면 _ 접두사가 붙은 메서드를 호출하세요:
import com.anthropic.core.JsonField;
import com.anthropic.models.messages.StopReason;
JsonField<StopReason> stopReason = client.messages().create(params)._stopReason();
if (stopReason.isMissing()) {
// JSON 응답에 해당 속성이 없습니다
} else if (stopReason.isNull()) {
// 속성이 리터럴 null로 설정되었습니다
} else {
// 값이 문자열로 제공되었는지 확인합니다
// 다른 메서드로는 `asNumber()`, `asBoolean()` 등이 있습니다
Optional<String> jsonString = stopReason.asString();
// 사용자 정의 타입으로 역직렬화를 시도합니다
MyClass myObject = stopReason.asUnknown().orElseThrow().convert(MyClass.class);
}기본적으로 SDK는 API가 예상 타입과 일치하지 않는 응답을 반환할 때 예외를 발생시키지 않습니다. 속성에 직접 접근하는 경우에만 AnthropicInvalidDataException을 발생시킵니다.
응답이 완전히 올바른 타입인지 미리 확인하려면 validate()를 호출하세요:
import com.anthropic.models.messages.Message;
Message message = client.messages().create(params).validate();또는 요청별로 구성하세요:
import com.anthropic.models.messages.Message;
Message message = client
.messages()
.create(params, RequestOptions.builder().responseValidation(true).build());또는 클라이언트 수준에서 모든 메서드 호출에 대한 기본값을 구성하세요:
import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;
AnthropicClient client = AnthropicOkHttpClient.builder()
.fromEnv()
.responseValidation(true)
.build();import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;
import java.net.Proxy;
AnthropicClient client = AnthropicOkHttpClient.builder()
.fromEnv()
.proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("https://example.com", 8080)))
.build();대부분의 애플리케이션은 이러한 메서드를 호출하지 말고 시스템 기본값을 사용해야 합니다. 기본값에는 구현이 수정될 경우 손실될 수 있는 특별한 최적화가 포함되어 있습니다.
import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;
AnthropicClient client = AnthropicOkHttpClient.builder()
.fromEnv()
.sslSocketFactory(yourSSLSocketFactory)
.trustManager(yourTrustManager)
.hostnameVerifier(yourHostnameVerifier)
.build();SDK는 세 개의 아티팩트로 구성됩니다:
anthropic-java-core - 핵심 SDK 로직을 포함하며 OkHttp에 의존하지 않습니다. AnthropicClient, AnthropicClientAsync 및 해당 구현 클래스를 노출하며, 이들은 모두 어떤 HTTP 클라이언트와도 작동할 수 있습니다.anthropic-java-client-okhttp - OkHttp에 의존합니다. AnthropicOkHttpClient 및 AnthropicOkHttpClientAsync를 노출합니다.anthropic-java - anthropic-java-core와 anthropic-java-client-okhttp 모두에 의존하고 해당 API를 노출합니다. 자체 로직은 없습니다.이 구조를 통해 불필요한 종속성을 가져오지 않고 SDK의 기본 HTTP 클라이언트를 교체할 수 있습니다.
기본 클라이언트를 교체하기 전에 사용 가능한 네트워크 옵션을 먼저 시도해 보세요.
사용자 정의된 OkHttpClient를 사용하려면:
anthropic-java 종속성을 anthropic-java-core로 교체하세요.anthropic-java-client-okhttp의 OkHttpClient 클래스를 코드에 복사하고 사용자 정의하세요.AnthropicClientImpl 또는 AnthropicClientAsyncImpl을 구성하세요.완전히 사용자 정의된 HTTP 클라이언트를 사용하려면:
anthropic-java 종속성을 anthropic-java-core로 교체하세요.HttpClient 인터페이스를 구현하는 클래스를 작성하세요.AnthropicClientImpl 또는 AnthropicClientAsyncImpl을 구성하세요.코드 예제가 포함된 자세한 플랫폼 설정 가이드는 다음을 참조하세요:
Java SDK는 플랫폼별 Backend 구현을 제공하는 별도의 종속성을 통해 다음 플랫폼을 지원합니다:
com.anthropic:anthropic-java-bedrock: Messages-API Bedrock 엔드포인트에는 BedrockMantleBackend.fromEnv() 또는 BedrockMantleBackend.builder()를 사용하고, bedrock-runtime 경로에는 BedrockBackend.fromEnv() / BedrockBackend.builder()를 사용하세요.com.anthropic:anthropic-java-vertex: VertexBackend.fromEnv() 또는 VertexBackend.builder()를 사용하세요.com.anthropic:anthropic-java-foundry: FoundryBackend.fromEnv() 또는 FoundryBackend.builder()를 사용하세요.com.anthropic:anthropic-java-aws: AwsBackend.fromEnv()(ANTHROPIC_AWS_WORKSPACE_ID와 AWS 기본 리전/자격 증명 체인을 읽음) 또는 AwsBackend.builder()를 사용하세요. 베타로 제공됩니다.새 프로젝트에는 BedrockMantleBackend를 사용하세요. BedrockBackend는 Bedrock InvokeModel API를 사용하는 기존 애플리케이션을 위해 유지됩니다.
각 Backend 구현은 AnthropicOkHttpClient.builder()의 .backend()를 통해 클라이언트에 전달됩니다. 각 클라우드 백엔드는 해당 클라우드 플랫폼 SDK 클래스를 전이적 종속성으로 가져옵니다.
HTTP 헤더, 상태 코드 및 원시 응답 본문에 접근하려면 HTTP 메서드 호출 앞에 withRawResponse()를 붙이세요:
import com.anthropic.core.http.Headers;
import com.anthropic.core.http.HttpResponseFor;
import com.anthropic.models.messages.Message;
import com.anthropic.models.messages.MessageCreateParams;
import com.anthropic.models.messages.Model;
MessageCreateParams params = MessageCreateParams.builder()
.maxTokens(1024L)
.addUserMessage("Hello, Claude")
.model(Model.CLAUDE_OPUS_4_8)
.build();
HttpResponseFor<Message> message = client.messages().withRawResponse().create(params);
int statusCode = message.statusCode();
Headers headers = message.headers();필요한 경우 응답을 Java 클래스의 인스턴스로 역직렬화할 수도 있습니다:
import com.anthropic.models.messages.Message;
Message parsedMessage = message.parse();SDK는 표준 OkHttp 로깅 인터셉터를 사용합니다.
ANTHROPIC_LOG 환경 변수를 info로 설정하여 로깅을 활성화하세요:
export ANTHROPIC_LOG=info또는 더 자세한 로깅을 위해 debug로 설정하세요:
export ANTHROPIC_LOG=debugSDK는 문서화된 API를 편리하게 사용할 수 있도록 타입이 지정되어 있습니다. 그러나 문서화되지 않았거나 아직 지원되지 않는 API 부분과의 작업도 지원합니다.
문서화되지 않은 요청 매개변수를 설정하려면 문서화되지 않은 매개변수에 설명된 대로 putAdditionalHeader, putAdditionalQueryParam 또는 putAdditionalBodyProperty 메서드를 사용하세요.
문서화되지 않은 응답 속성에 접근하려면 응답 속성에 설명된 대로 _additionalProperties() 메서드를 사용하세요.
Model 및 AnthropicBeta와 같은 SDK의 enum 유사 클래스는 닫힌 Java enum 타입이 아닙니다. 각 클래스는 임의의 문자열을 받는 of(String) 팩토리 메서드를 제공하므로, 사용 중인 SDK 버전 이후에 출시된 모델이나 베타 헤더와 같이 아직 SDK에 추가되지 않은 값을 사용할 수 있습니다:
import com.anthropic.models.beta.AnthropicBeta;
import com.anthropic.models.messages.Model;
Model model = Model.of("some-new-model");
AnthropicBeta beta = AnthropicBeta.of("some-new-beta-2026-01-01");이러한 타입을 받는 빌더 메서드는 종종 of(...)를 대신 호출해 주는 String 오버로드도 제공합니다:
import com.anthropic.models.messages.MessageCreateParams;
MessageCreateParams params = MessageCreateParams.builder()
.model("some-new-model") // same as .model(Model.of("some-new-model"))
.maxTokens(1024L)
.addUserMessage("Hello, Claude")
.build();자동 완성과 사용 중단 경고를 받을 수 있도록 타입이 잘 지정된 상수(예: Model.CLAUDE_OPUS_4_7)를 사용하는 것이 좋습니다. String 오버로드와 of(...)는 주로 해당 값이 포함된 SDK 릴리스를 기다리는 동안 문서화되지 않았거나 아직 지원되지 않는 값으로 필드를 설정하기 위한 것입니다.
베타 기능은 조기 피드백을 받고 새로운 기능을 테스트하기 위해 정식 출시 전에 제공됩니다. Claude의 모든 기능과 도구의 가용성은 Claude로 빌드하기 개요에서 확인할 수 있습니다.
클라이언트의 beta() 메서드를 통해 대부분의 베타 API 기능에 접근할 수 있습니다. 특정 베타 기능을 활성화하려면 메시지 매개변수를 빌드할 때 .addBeta()로 적절한 베타 헤더를 추가하세요.
예를 들어 Files API를 사용하려면:
import com.anthropic.models.beta.AnthropicBeta;
import com.anthropic.models.beta.messages.BetaContentBlockParam;
import com.anthropic.models.beta.messages.BetaMessage;
import com.anthropic.models.beta.messages.BetaRequestDocumentBlock;
import com.anthropic.models.beta.messages.BetaTextBlockParam;
import com.anthropic.models.beta.messages.MessageCreateParams;
void main() {
AnthropicClient client = AnthropicOkHttpClient.fromEnv();
BetaMessage message = client.beta().messages().create(
MessageCreateParams.builder()
.model(Model.CLAUDE_OPUS_4_8)
.maxTokens(1024L)
.addBeta(AnthropicBeta.FILES_API_2025_04_14)
.addUserMessageOfBetaContentBlockParams(List.of(
BetaContentBlockParam.ofText(
BetaTextBlockParam.builder()
.text("Please summarize this document for me.")
.build()),
BetaContentBlockParam.ofDocument(
BetaRequestDocumentBlock.builder()
.fileSource("file_abc123")
.build())))
.build());
}이 패키지는 일반적으로 SemVer 규칙을 따르지만, 특정 하위 호환되지 않는 변경 사항이 마이너 버전으로 릴리스될 수 있습니다:
Was this page helpful?