Java SDK
Установка и настройка Anthropic Java SDK с шаблонами builder и поддержкой асинхронных операций
Anthropic Java SDK предоставляет удобный доступ к Claude API из приложений, написанных на Java. Он использует шаблон builder для создания запросов и поддерживает как синхронные, так и асинхронные операции.
Установка
implementation("com.anthropic:anthropic-java:3.3.0")<dependency>
<groupId>com.anthropic</groupId>
<artifactId>anthropic-java</artifactId>
<version>3.3.0</version>
</dependency>Требования
Для этой библиотеки требуется Java 8 или более поздняя версия.
Быстрый старт
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_5_5)
.build();
Message message = client.messages().create(params);Настройка клиента
Настройка ключа API
Настройте клиент с помощью системных свойств или переменных окружения:
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, см. в разделе Аутентификация. Если ваш ключ API является ключом персональной или сервисной учётной записи, который не привязан к рабочему пространству, укажите идентификатор рабочего пространства в заголовке запроса anthropic-workspace-id; в разделе Выбор рабочего пространства показан вариант указания для каждого запроса в этом SDK.
Параметры конфигурации
| Сеттер | Системное свойство | Переменная окружения | Обязательный | Значение по умолчанию |
|---|---|---|---|---|
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_5_5)
.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_5_5)
.build();
CompletableFuture<Message> message = client.messages().create(params);Асинхронный клиент поддерживает те же параметры, что и синхронный, за исключением того, что большинство методов возвращают CompletableFuture.
Потоковая передача
«Streaming» (потоковая передача): 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 может записывать поток событий в ответе по мере их обработки и накапливать объект Message, аналогичный тому, который был бы возвращён API без потоковой передачи.
Для синхронного ответа добавьте вызов 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();Для асинхронного ответа добавьте MessageAccumulator в вызов subscribe():
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();Также доступен BetaMessageAccumulator для накопления объекта BetaMessage. Он используется так же, как MessageAccumulator.
Структурированные выходные данные
Полную документацию по структурированным выходным данным, включая примеры на Java, см. в разделе Структурированные выходные данные.
Использование инструментов
Использование инструментов с Claude («tool use», использование инструментов) позволяет интегрировать внешние инструменты и функции непосредственно в ответы модели ИИ. Вместо создания простого текста модель может при необходимости выводить инструкции (с параметрами) для вызова инструмента или функции. Вы определяете JSON-схемы для инструментов, а модель использует эти схемы, чтобы определить, когда и как использовать эти инструменты.
Функция использования инструментов поддерживает «строгий» режим, который гарантирует, что JSON-вывод модели ИИ будет соответствовать JSON-схеме, которую вы предоставляете во входных параметрах.
SDK может автоматически выводить инструмент и его параметры из структуры произвольного класса Java: имя класса (преобразованное в snake case) задаёт имя инструмента, а поля класса определяют параметры инструмента.
Определение инструментов с помощью аннотаций
import com.fasterxml.jackson.annotation.JsonClassDescription;
import com.fasterxml.jackson.annotation.JsonPropertyDescription;
enum Unit {
CELSIUS,
FAHRENHEIT;
public String toString() {
return switch (this) {
case CELSIUS -> "C";
case FAHRENHEIT -> "F";
};
}
public double fromKelvin(double temperatureK) {
return switch (this) {
case CELSIUS -> temperatureK - 273.15;
case FAHRENHEIT -> (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" -> 300.0;
case "New York, NY" -> 310.0;
case "Dallas, TX" -> 305.0;
default -> 295;
};
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>), а затем вызывайте их, если это запрошено в ответе модели ИИ. BetaToolUseBlock.input(Class<T>) можно использовать для разбора параметров инструмента в формате JSON в экземпляр вашего класса, определяющего инструмент.
После вызова инструмента используйте BetaToolResultBlockParam.Builder.contentAsJson(Object), чтобы передать результат инструмента обратно модели ИИ:
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_5_5)
.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
// Добавляем сообщение о том, что было запрошено использование инструментов.
.addAssistantMessageOfContentBlockParams(
List.of(BetaContentBlockParam.ofToolUse(BetaToolUseBlockParam.builder()
.name(toolUseBlock.name())
.id(toolUseBlock.id())
.input(toolUseBlock._input())
.build())))
// Добавляем сообщение с результатом запрошенного использования инструментов.
.addUserMessageOfContentBlockParams(
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");
}Преобразование имён инструментов
Имена инструментов выводятся из имён классов инструментов в camel case (например, GetWeather) и преобразуются в snake case (например, get_weather). Границы слов начинаются там, где текущий символ не является первым, находится в верхнем регистре и либо предыдущий символ находится в нижнем регистре, либо следующий символ находится в нижнем регистре. Например, MyJSONParser становится my_json_parser, а ParseJSON становится parse_json. Это преобразование можно переопределить с помощью аннотации @JsonTypeName.
Локальная проверка JSON-схемы инструмента
Вы можете выполнить локальную проверку, чтобы убедиться, что JSON-схема, выведенная из вашего класса инструмента, соответствует ограничениям Anthropic. Локальная проверка включена по умолчанию, но её можно отключить:
MessageCreateParams.Builder createParamsBuilder = MessageCreateParams.builder()
.model(Model.CLAUDE_OPUS_5_5)
.maxTokens(2048)
.addTool(GetWeather.class, JsonSchemaLocalValidation.NO)
.addUserMessage("What's the temperature in New York?");Аннотирование классов инструментов
Вы можете использовать аннотации, чтобы добавить в JSON-схемы дополнительную информацию об инструментах:
@JsonClassDescription— добавляет к классу инструмента описание, поясняющее, когда и как использовать этот инструмент.@JsonTypeName— задаёт имя инструмента, отличное от простого имени класса, преобразованного в snake case.@JsonPropertyDescription— добавляет подробное описание к параметру инструмента.@JsonIgnore— исключаетpublicполе или метод-геттер из сгенерированной JSON-схемы параметров инструмента.@JsonProperty— включает не-publicполе или метод-геттер в сгенерированную JSON-схему параметров инструмента.
Пакеты сообщений
SDK поддерживает пакетную обработку в пространстве имён client.messages().batches(). О том, как получать список пакетов и выполнять по ним пагинацию, см. в разделе Пагинация.
Загрузка файлов
SDK определяет методы, которые принимают файлы через класс MultipartField:
import com.anthropic.core.MultipartField;
import com.anthropic.models.files.FileMetadata;
import com.anthropic.models.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.files().upload(params);Или из InputStream:
import com.anthropic.core.MultipartField;
import com.anthropic.models.files.FileMetadata;
import com.anthropic.models.files.FileUploadParams;
FileUploadParams params = FileUploadParams.builder()
.file(
MultipartField.<InputStream>builder()
.value(URI.create("https://example.com/path/to/file").toURL().openStream())
.filename("document.pdf")
.contentType("application/pdf")
.build()
)
.build();
FileMetadata fileMetadata = client.files().upload(params);Или из байтов в памяти:
import com.anthropic.core.MultipartField;
import com.anthropic.models.files.FileMetadata;
import com.anthropic.models.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.files().upload(params);Двоичные ответы
SDK определяет методы, которые возвращают двоичные ответы для ответов API, которые не обязательно разбираются как JSON:
import com.anthropic.core.http.HttpResponse;
HttpResponse response = client.files().download("file_abc123");Чтобы сохранить содержимое ответа в файл:
import com.anthropic.core.http.HttpResponse;
try (HttpResponse response = client.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.files().download(params)) {
response.body().transferTo(Files.newOutputStream(Paths.get(path)));
} catch (Exception e) {
IO.println("Something went wrong!");
throw new RuntimeException(e);
}Обработка ошибок
SDK выбрасывает пользовательские непроверяемые типы исключений:
AnthropicServiceException— базовый класс для ошибок HTTP.AnthropicIoException— сетевые ошибки ввода-вывода.AnthropicRetryableException— общая ошибка, указывающая на сбой, который можно повторить.AnthropicInvalidDataException— невозможность интерпретировать успешно разобранные данные (например, при обращении к свойству, которое должно быть обязательным, но API неожиданно его опустил).AnthropicException— базовый класс для всех исключений.
Соответствие кодов состояния
| Статус | Исключение |
|---|---|
| 400 | BadRequestException |
| 401 | UnauthorizedException |
| 403 | PermissionDeniedException |
| 404 | NotFoundException |
| 422 | UnprocessableEntityException |
| 429 | RateLimitException |
| 5xx | InternalServerException |
| другие | UnexpectedStatusCodeException |
SseException выбрасывается при ошибках, возникших во время потоковой передачи SSE после успешного начального HTTP-ответа.
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());
}Идентификаторы запросов
При использовании необработанных ответов вы можете получить доступ к заголовку ответа request-id с помощью метода requestId():
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. Дополнительную информацию об отладке запросов см. в разделе Request ID.
Повторные попытки
По умолчанию SDK автоматически выполняет 2 повторные попытки с коротким экспоненциальным откатом между запросами.
Повторяются только следующие типы ошибок:
- Ошибки соединения (например, из-за проблемы с сетевым подключением)
- 408 Request Timeout
- 409 Conflict
- 429 Rate Limit
- 5xx Internal
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
)
)
)Это даёт тайм-аут до 60 минут, масштабируемый параметром maxTokens, если он не переопределён.
Для запросов без потоковой передачи динамический тайм-аут масштабируется от минимума в 30 секунд до максимума в 10 минут в зависимости от maxTokens.
Чтобы задать собственный тайм-аут для отдельного запроса:
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 периодически отправляет ping-запросы к 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();
}Система типов
Неизменяемость и builder-классы
Каждый класс в SDK имеет связанный builder для его создания. Каждый класс неизменяем после создания. Если у класса есть связанный builder, то у него есть метод toBuilder(), который можно использовать для преобразования обратно в builder, чтобы создать изменённую копию.
MessageCreateParams params = MessageCreateParams.builder()
.maxTokens(1024L)
.addUserMessage("Hello, Claude")
.model(Model.CLAUDE_OPUS_5_5)
.build();
// Создаём изменённую копию с помощью toBuilder()
MessageCreateParams modified = params.toBuilder().maxTokens(2048L).build();Поскольку каждый класс неизменяем, изменение builder никогда не влияет на уже созданные экземпляры класса.
Запросы и ответы
Чтобы отправить запрос к Claude API, создайте экземпляр некоторого класса Params и передайте его соответствующему методу клиента. Когда ответ получен, он десериализуется в экземпляр класса Java.
Например, client.messages().create(...) следует вызывать с экземпляром MessageCreateParams, и он возвращает экземпляр Message.
Недокументированные параметры
Чтобы задать недокументированные параметры, вызовите методы putAdditionalHeader, putAdditionalQueryParam или putAdditionalBodyProperty для любого класса Params:
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().
Чтобы задать документированному параметру или свойству недокументированное или ещё не поддерживаемое значение, передайте объект 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_5_5)
.build();Создание JsonValue
Самый простой способ создать 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!");
// Создание значения-массива JSON, эквивалентного `["Hello", "World"]`
JsonValue arrayValue = JsonValue.from(List.of("Hello", "World"));
// Создание значения-объекта JSON, эквивалентного `{ "a": 1, "b": 2 }`
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)));Принудительное опускание обязательных параметров
Обычно метод build класса Builder выбрасывает 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_5_5)
.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();Настройка HTTP-клиента
Настройка прокси
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();Настройка HTTPS / SSL
import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;
AnthropicClient client = AnthropicOkHttpClient.builder()
.fromEnv()
.sslSocketFactory(yourSSLSocketFactory)
.trustManager(yourTrustManager)
.hostnameVerifier(yourHostnameVerifier)
.build();Пользовательский HTTP-клиент
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 обоих. Не имеет собственной логики.
Такая структура позволяет заменить HTTP-клиент SDK по умолчанию, не подключая ненужные зависимости.
Настроенный OkHttpClient
Чтобы использовать настроенный OkHttpClient:
- Замените зависимость
anthropic-javaнаanthropic-java-core. - Скопируйте класс
OkHttpClientизanthropic-java-client-okhttpв свой код и настройте его. - Создайте
AnthropicClientImplилиAnthropicClientAsyncImpl, используя ваш настроенный клиент.
Полностью пользовательский HTTP-клиент
Чтобы использовать полностью пользовательский HTTP-клиент:
- Замените зависимость
anthropic-javaнаanthropic-java-core. - Напишите класс, реализующий интерфейс
HttpClient. - Создайте
AnthropicClientImplилиAnthropicClientAsyncImpl, используя ваш новый класс клиента.
Интеграции с платформами
Java SDK поддерживает следующие платформы через отдельные зависимости, предоставляющие специфичные для платформ реализации Backend:
- Agent Platform:
com.anthropic:anthropic-java-vertex: используйтеVertexBackend.builder()илиVertexBackend.fromEnv().fromEnv()считываетCLOUD_ML_REGIONиANTHROPIC_VERTEX_PROJECT_IDи использует Application Default Credentials. - Bedrock:
com.anthropic:anthropic-java-bedrock: используйтеBedrockMantleBackend.fromEnv()илиBedrockMantleBackend.builder()для конечной точки Bedrock с Messages API либоBedrockBackend.fromEnv()/BedrockBackend.builder()(путьbedrock-runtime). - Claude Platform on AWS:
com.anthropic:anthropic-java-aws: используйтеAwsBackend.fromEnv()(считываетANTHROPIC_AWS_WORKSPACE_IDи регион/цепочку учётных данных AWS по умолчанию) илиAwsBackend.builder(). Доступно в бета-версии. - Foundry:
com.anthropic:anthropic-java-foundry: используйтеFoundryBackend.fromEnv()илиFoundryBackend.builder().
Используйте BedrockMantleBackend для новых проектов; BedrockBackend сохраняется для существующих приложений, использующих API Bedrock InvokeModel.
Java SDK также поддерживает Claude Models on Google Cloud (Anthropic managed) через GoogleCloudBackend из зависимости com.anthropic:anthropic-java-google-cloud. Этот бэкенд находится в стадии бета-тестирования. Создайте его с помощью GoogleCloudBackend.builder() или GoogleCloudBackend.fromEnv(). fromEnv() считывает ANTHROPIC_GOOGLE_CLOUD_WORKSPACE_ID, ANTHROPIC_GOOGLE_CLOUD_PROJECT и учётные данные Google Application Default Credentials. См. Определение проекта, расположения и рабочего пространства.
Артефакты платформ являются дополнениями к базовой зависимости com.anthropic:anthropic-java, которая предоставляет AnthropicOkHttpClient, поэтому установите обе. Каждая реализация Backend передаётся клиенту с помощью .backend() в AnthropicOkHttpClient.builder(). Каждый облачный бэкенд подключает классы SDK соответствующей облачной платформы в качестве транзитивных зависимостей.
Расширенное использование
Доступ к необработанному ответу
Чтобы получить доступ к HTTP-заголовкам, кодам состояния и необработанному телу ответа, добавьте withRawResponse() перед вызовом любого HTTP-метода:
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_5_5)
.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 зависит от Jackson для сериализации/десериализации JSON. Он совместим с версией 2.13.4 или выше, но по умолчанию зависит от версии 2.19.4.
SDK выбрасывает исключение, если во время выполнения обнаруживает несовместимую версию Jackson (например, если версия по умолчанию была переопределена в вашей конфигурации Maven или Gradle).
Если SDK выбросил исключение, но вы уверены, что версия совместима, отключите проверку версии с помощью checkJacksonVersionCompatibility в AnthropicOkHttpClient или AnthropicOkHttpClientAsync.
В старых версиях Jackson также есть ошибки, которые могут влиять на SDK. SDK не обходит все ошибки Jackson и ожидает, что пользователи обновят Jackson для их устранения.
Хотя SDK использует рефлексию, его всё равно можно использовать с ProGuard и R8, поскольку anthropic-java-core публикуется с файлом конфигурации, содержащим правила keep.
ProGuard и R8 должны автоматически обнаруживать и использовать опубликованные правила, но при необходимости вы также можете скопировать правила keep вручную.
Трассировка OpenTelemetry
Когда ваше приложение регистрирует провайдер трассировщика OpenTelemetry, SDK создаёт спан для каждого отправляемого запроса. Чтобы отправлять спаны на вашу платформу наблюдаемости, см. Настройка OpenTelemetry с Claude SDK.
Недокументированная функциональность API
SDK типизирован для удобного использования документированного API. Однако он также поддерживает работу с недокументированными или ещё не поддерживаемыми частями API.
Недокументированные параметры запроса
Чтобы задать недокументированные параметры запроса, используйте методы putAdditionalHeader, putAdditionalQueryParam или putAdditionalBodyProperty, как описано в разделе Недокументированные параметры.
Недокументированные свойства ответа
Чтобы получить доступ к недокументированным свойствам ответа, используйте метод _additionalProperties(), как описано в разделе Свойства ответа.
Новые или ещё не выпущенные значения перечислений
Классы SDK, подобные перечислениям, такие как Model и AnthropicBeta, не являются закрытыми типами 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");Методы builder, принимающие эти типы, часто также предоставляют перегрузку для String, которая вызывает of(...) за вас:
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_5), чтобы получать автодополнение и предупреждения об устаревании. Перегрузки для String и of(...) предназначены в первую очередь для установки поля в недокументированное или ещё не поддерживаемое значение в ожидании выпуска SDK, который его включает.
Бета-функции
Бета-функции становятся доступны до общего выпуска, чтобы получить ранние отзывы и протестировать новую функциональность. Доступность всех возможностей и инструментов Claude можно проверить в обзоре функций.
Доступ к большинству бета-функций API можно получить через метод beta() клиента. Чтобы включить определённую бета-функцию, добавьте соответствующий бета-заголовок с помощью .addBeta() при создании параметров сообщения.
Например, чтобы включить редактирование контекста:
import com.anthropic.models.beta.AnthropicBeta;
import com.anthropic.models.beta.messages.BetaMessage;
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_5_5)
.maxTokens(1024L)
.addBeta(AnthropicBeta.CONTEXT_MANAGEMENT_2025_06_27)
.addUserMessage("Hello, Claude")
.build());
}Часто задаваемые вопросы
Классы Java enum не обладают простой прямой совместимостью. Их использование в SDK могло бы вызывать исключения во время выполнения, если API будет обновлён и начнёт возвращать новое значение перечисления.
Поскольку эти классы открыты, вы также можете создавать их с любым строковым значением через их фабричный метод of(String). См. раздел Новые или ещё не выпущенные значения перечислений, если вам нужно использовать значение, которого ещё нет в вашей версии SDK.
Использование JsonField<T> обеспечивает несколько возможностей:
- Возможность использования недокументированной функциональности API
- Ленивая проверка ответа API на соответствие ожидаемой структуре
- Различение отсутствующих и явно заданных как null значений
Добавление новых полей в data-класс нарушает обратную совместимость, а SDK избегает внесения критических изменений каждый раз, когда в класс добавляется поле.
Проверяемые исключения широко считаются ошибкой в языке программирования Java. Фактически по этой причине они были исключены из Kotlin.
Проверяемые исключения:
- Требуют многословной обработки
- Поощряют обработку ошибок на неправильном уровне абстракции, где с ошибкой ничего нельзя сделать
- Утомительны в распространении из-за проблемы «окрашивания функций»
- Плохо сочетаются с лямбдами (также из-за проблемы «окрашивания функций»)
Семантическое версионирование
Каждая мажорная версия этого SDK по умолчанию отправляет одну версию API в заголовке anthropic-version, и с каждой новой версией API выходит новая мажорная версия. Первая мажорная версия, отправляющая 2026-10-21, — 3.0.0; см. Переход на версию API 2026-10-21.
Этот пакет в целом следует соглашениям SemVer, хотя некоторые обратно несовместимые изменения могут выпускаться в минорных версиях:
- Изменения во внутренних компонентах библиотеки, которые технически являются публичными, но не предназначены или не задокументированы для внешнего использования.
- Изменения, которые, как ожидается, на практике не затронут подавляющее большинство пользователей.
Дополнительные ресурсы
Was this page helpful?