• Mensagens
  • Agentes Gerenciados
  • Administração
Search...
⌘K
CLI, SDKs e bibliotecas
Visão geral
CLI ant
Início rápidoOpções de autenticaçãoUsando a CLIScripts e automação
SDKs de cliente
MiddlewarePythonTypeScriptC#GoJavaPHPRuby
Bibliotecas e integrações
Apple Foundation ModelsCompatibilidade com o SDK da OpenAI
Log in
Java
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...

Solutions

  • AI agents
  • Code modernization
  • Coding
  • Customer support
  • Education
  • Financial services
  • Government
  • Life sciences

Partners

  • Amazon Bedrock
  • Google Cloud's Vertex AI

Learn

  • Blog
  • Courses
  • Use cases
  • Connectors
  • Customer stories
  • Engineering at Anthropic
  • Events
  • Powered by Claude
  • Service partners
  • Startups program

Company

  • Anthropic
  • Careers
  • Economic Futures
  • Research
  • News
  • Responsible Scaling Policy
  • Security and compliance
  • Transparency

Learn

  • Blog
  • Courses
  • Use cases
  • Connectors
  • Customer stories
  • Engineering at Anthropic
  • Events
  • Powered by Claude
  • Service partners
  • Startups program

Help and security

  • Availability
  • Status
  • Support
  • Discord

Terms and policies

  • Privacy policy
  • Responsible disclosure policy
  • Terms of service: Commercial
  • Terms of service: Consumer
  • Usage policy
CLI, SDKs e bibliotecas/SDKs de cliente

SDK Java

Instale e configure o SDK Java da Anthropic com padrões builder e suporte assíncrono

O SDK Java da Anthropic fornece acesso conveniente à API REST da Anthropic a partir de aplicações escritas em Java. Ele usa o padrão builder para criar requisições e suporta operações síncronas e assíncronas.

Para documentação de recursos da API com exemplos de código, consulte a referência da API. Esta página aborda recursos e configurações do SDK específicos para Java.

Instalação

Requisitos

Esta biblioteca requer Java 8 ou posterior.

O SDK suporta Java 8 e posterior. Os exemplos de código nesta documentação são escritos como arquivos de código-fonte compactos do JDK 25, usando um ponto de entrada void main() simples e IO.println() para saída. As chamadas de API em si são idênticas em todos os JDKs suportados; para compilar um exemplo em uma versão anterior, substitua IO.println(...) por System.out.println(...) e coloque o corpo dentro de public static void main(String[] args) em uma classe.

Início rápido

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;

// Configura usando as propriedades de sistema `anthropic.apiKey`, `anthropic.authToken` e `anthropic.baseUrl`
// Ou configura usando as variáveis de ambiente `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN` e `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);

Configuração do cliente

Configuração da chave de API

Configure o cliente usando propriedades do sistema ou variáveis de ambiente:

import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;

// Configura usando as propriedades de sistema `anthropic.apiKey`, `anthropic.authToken` e `anthropic.baseUrl`
// Ou configura usando as variáveis de ambiente `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN` e `ANTHROPIC_BASE_URL`
AnthropicClient client = AnthropicOkHttpClient.fromEnv();

Ou configure manualmente:

import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;

AnthropicClient client = AnthropicOkHttpClient.builder()
  .apiKey("my-anthropic-api-key")
  .build();

Ou use uma combinação de ambas as abordagens:

import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;

AnthropicClient client = AnthropicOkHttpClient.builder()
  // Configura usando propriedades do sistema ou variáveis de ambiente
  .fromEnv()
  .apiKey("my-anthropic-api-key")
  .build();

Para opções de autenticação, incluindo Workload Identity Federation, consulte Autenticação.

Opções de configuração

SetterPropriedade do sistemaVariável de ambienteObrigatórioValor padrão
apiKeyanthropic.apiKeyANTHROPIC_API_KEYfalse-
authTokenanthropic.authTokenANTHROPIC_AUTH_TOKENfalse-
baseUrlanthropic.baseUrlANTHROPIC_BASE_URLtrue"https://api.anthropic.com"

Propriedades do sistema têm precedência sobre variáveis de ambiente.

Não crie mais de um cliente na mesma aplicação. Cada cliente tem um pool de conexões e pools de threads, que são mais eficientes quando compartilhados entre requisições.

Modificando a configuração

Para usar temporariamente uma configuração de cliente modificada enquanto reutiliza os mesmos pools de conexão e de threads, chame withOptions() em qualquer cliente ou serviço:

import com.anthropic.client.AnthropicClient;

AnthropicClient clientWithOptions = client.withOptions(optionsBuilder -> {
  optionsBuilder.baseUrl("https://example.com");
  optionsBuilder.maxRetries(42);
});

O método withOptions() não afeta o cliente ou serviço original.

Uso assíncrono

O cliente padrão é síncrono. Para alternar para execução assíncrona, chame o método 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);

Ou crie um cliente assíncrono desde o início:

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

O cliente assíncrono suporta as mesmas opções que o síncrono, exceto que a maioria dos métodos retorna CompletableFutures.

Streaming

O SDK define métodos que retornam streams de "chunks" (pedaços) de resposta, onde cada chunk pode ser processado individualmente assim que chega, em vez de esperar pela resposta completa.

Streaming síncrono

Esses métodos de streaming retornam StreamResponse para clientes síncronos:

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

Streaming assíncrono

Para clientes assíncronos, o método retorna AsyncStreamResponse:

import com.anthropic.core.http.AsyncStreamResponse;
import com.anthropic.models.messages.RawMessageStreamEvent;

client.async().messages().createStreaming(params).subscribe(chunk -> {
    IO.println(chunk);
});

// Se você precisar tratar erros ou a conclusão do stream
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!");
        }
    }
});

// Ou use 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!");
        }
    });

O streaming assíncrono usa um Executor de pool de threads em cache dedicado por cliente para fazer streaming sem bloquear a thread atual. Para usar um Executor diferente:

Executor executor = Executors.newFixedThreadPool(4);
client.async().messages().createStreaming(params).subscribe(
    chunk -> IO.println(chunk), executor
);

Ou configure o cliente globalmente usando o método streamHandlerExecutor:

import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;

AnthropicClient client = AnthropicOkHttpClient.builder()
  .fromEnv()
  .streamHandlerExecutor(Executors.newFixedThreadPool(4))
  .build();

Streaming com acumulador de mensagens

Um MessageAccumulator pode registrar o stream de eventos na resposta à medida que são processados e acumular um objeto Message semelhante ao que teria sido retornado pela API sem streaming.

Para uma resposta síncrona, adicione uma chamada Stream.peek() ao pipeline do stream para acumular cada evento:

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

Para uma resposta assíncrona, adicione o MessageAccumulator à chamada 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();

Um BetaMessageAccumulator também está disponível para a acumulação de um objeto BetaMessage. Ele é usado da mesma maneira que o MessageAccumulator.

Saídas estruturadas

Para documentação completa de saídas estruturadas incluindo exemplos em Java, consulte Saídas estruturadas.

Uso de ferramentas

O uso de ferramentas com Claude permite integrar ferramentas e funções externas diretamente nas respostas do modelo de IA. Em vez de produzir texto simples, o modelo pode gerar instruções (com parâmetros) para chamar uma ferramenta ou função quando apropriado. Você define esquemas JSON para as ferramentas, e o modelo usa os esquemas para determinar quando e como usar essas ferramentas.

O recurso de uso de ferramentas suporta um modo "strict" (estrito) que garante que a saída JSON do modelo de IA estará em conformidade com o esquema JSON que você fornece nos parâmetros de entrada.

O SDK pode derivar uma ferramenta e seus parâmetros automaticamente a partir da estrutura de uma classe Java arbitrária: o nome da classe (convertido para snake case) fornece o nome da ferramenta, e os campos da classe definem os parâmetros da ferramenta.

Declare suas classes de ferramentas como classes de nível superior ou classes aninhadas static. Esse requisito vem da biblioteca Jackson Databind (com.fasterxml.jackson.databind), que o SDK usa para desserializar entradas de ferramentas em instâncias de suas classes e não consegue instanciar classes internas não estáticas.

Definindo ferramentas com anotações

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

Chamando ferramentas

Quando suas classes de ferramentas estiverem definidas, adicione-as aos parâmetros da mensagem usando MessageCreateParams.Builder.addTool(Class<T>) e então chame-as se solicitado na resposta do modelo de IA. BetaToolUseBlock.input(Class<T>) pode ser usado para fazer o parse dos parâmetros de uma ferramenta em formato JSON para uma instância da sua classe que define a ferramenta.

Após chamar a ferramenta, use BetaToolResultBlockParam.Builder.contentAsJson(Object) para passar o resultado da ferramenta de volta ao modelo de IA:

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
              // Adicione uma mensagem indicando que o uso de ferramentas foi solicitado.
              .addAssistantMessageOfBetaContentBlockParams(
                      List.of(BetaContentBlockParam.ofToolUse(BetaToolUseBlockParam.builder()
                              .name(toolUseBlock.name())
                              .id(toolUseBlock.id())
                              .input(toolUseBlock._input())
                              .build())))
              // Adicione uma mensagem com o resultado do uso de ferramentas solicitado.
              .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");
}

Conversão de nomes de ferramentas

Os nomes das ferramentas são derivados dos nomes das classes de ferramentas em camel case (por exemplo, GetWeather) e convertidos para snake case (por exemplo, get_weather). Os limites de palavras começam onde o caractere atual não é o primeiro caractere, é maiúsculo, e o caractere anterior é minúsculo ou o caractere seguinte é minúsculo. Por exemplo, MyJSONParser se torna my_json_parser e ParseJSON se torna parse_json. Essa conversão pode ser substituída usando a anotação @JsonTypeName.

Validação local do esquema JSON da ferramenta

Você pode realizar validação local para verificar se o esquema JSON derivado da sua classe de ferramenta respeita as restrições da Anthropic. A validação local está habilitada por padrão, mas pode ser desabilitada:

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

Anotando classes de ferramentas

Você pode usar anotações para adicionar mais informações sobre ferramentas aos esquemas JSON:

  • @JsonClassDescription - Adiciona uma descrição a uma classe de ferramenta detalhando quando e como usar essa ferramenta.
  • @JsonTypeName - Define o nome da ferramenta como algo diferente do nome simples da classe convertido para snake case.
  • @JsonPropertyDescription - Adiciona uma descrição detalhada a um parâmetro de ferramenta.
  • @JsonIgnore - Exclui um campo public ou método getter do esquema JSON gerado para os parâmetros de uma ferramenta.
  • @JsonProperty - Inclui um campo não public ou método getter no esquema JSON gerado para os parâmetros de uma ferramenta.

Lotes de mensagens

O SDK fornece suporte para processamento em lote no namespace client.messages().batches(). Consulte Paginação para saber como listar e paginar através de lotes.

Upload de arquivos

O SDK define métodos que aceitam arquivos através da classe 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);

Ou a partir de um 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);

Ou a partir de bytes em memória:

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

Respostas binárias

O SDK define métodos que retornam respostas binárias para respostas da API que não são necessariamente interpretadas como JSON:

import com.anthropic.core.http.HttpResponse;

HttpResponse response = client.beta().files().download("file_id");

Para salvar o conteúdo da resposta em um arquivo:

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

Ou transferir o conteúdo da resposta para qualquer 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);
}

Tratamento de erros

O SDK lança tipos de exceção não verificadas personalizadas:

  • AnthropicServiceException - Classe base para erros HTTP.
  • AnthropicIoException - Erros de rede de I/O.
  • AnthropicRetryableException - Erro genérico indicando uma falha que pode ser repetida.
  • AnthropicInvalidDataException - Falha ao interpretar dados analisados com sucesso (por exemplo, ao acessar uma propriedade que deveria ser obrigatória, mas a API inesperadamente a omitiu).
  • AnthropicException - Classe base para todas as exceções.

Mapeamento de códigos de status

StatusExceção
400BadRequestException
401UnauthorizedException
403PermissionDeniedException
404NotFoundException
422UnprocessableEntityException
429RateLimitException
5xxInternalServerException
outrosUnexpectedStatusCodeException

SseException é lançada para erros encontrados durante streaming SSE após uma resposta HTTP inicial bem-sucedida.

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

IDs de requisição

Ao usar respostas brutas, você pode acessar o cabeçalho de resposta request-id usando o método 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();

Isso pode ser usado para registrar rapidamente requisições com falha e reportá-las à Anthropic. Para mais informações sobre depuração de requisições, consulte ID de requisição.

Novas tentativas

O SDK tenta novamente automaticamente 2 vezes por padrão, com um curto backoff exponencial entre as requisições.

Apenas os seguintes tipos de erro são repetidos:

  • Erros de conexão (por exemplo, devido a um problema de conectividade de rede)
  • 408 Request Timeout
  • 409 Conflict
  • 429 Rate Limit
  • 5xx Internal

A API também pode instruir explicitamente o SDK a repetir ou não uma requisição.

Para definir um número personalizado de novas tentativas, configure o cliente usando o método maxRetries:

import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;

AnthropicClient client = AnthropicOkHttpClient.builder().fromEnv().maxRetries(4).build();

Timeouts

As requisições expiram após 10 minutos por padrão.

No entanto, para métodos que aceitam maxTokens, se você especificar um valor grande de maxTokens e estiver usando streaming, o timeout padrão será calculado dinamicamente usando esta fórmula:

Duration.ofSeconds(
    Math.min(
        60 * 60, // 1 hour max
        Math.max(
            10 * 60, // 10 minute minimum
            60 * 60 * maxTokens / 128_000
        )
    )
)

Isso resulta em um timeout de até 60 minutos, escalado pelo parâmetro maxTokens, a menos que seja substituído.

Para requisições sem streaming, o timeout dinâmico escala de um mínimo de 30 segundos até um máximo de 10 minutos com base em maxTokens.

Para definir um timeout personalizado por requisição:

import com.anthropic.models.messages.Message;

Message message = client
  .messages()
  .create(params, RequestOptions.builder().timeout(Duration.ofSeconds(30)).build());

Ou configure o padrão para todas as chamadas de método no nível do cliente:

import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;

AnthropicClient client = AnthropicOkHttpClient.builder()
  .fromEnv()
  .timeout(Duration.ofSeconds(30))
  .build();

Requisições longas

Considere usar streaming para requisições de execução mais longa.

Evite definir um valor grande de maxTokens sem usar streaming. Algumas redes podem descartar conexões ociosas após um certo período de tempo, o que pode fazer com que a requisição falhe ou expire sem receber uma resposta da Anthropic. O SDK envia pings periodicamente à API para manter a conexão ativa e reduzir o impacto dessas redes.

O SDK lança um erro se for esperado que uma requisição sem streaming leve mais de 10 minutos. Usar um método de streaming ou substituir o timeout no nível do cliente ou da requisição desabilita o erro.

Paginação

O SDK fornece maneiras convenientes de acessar resultados paginados, seja uma página por vez ou item por item em todas as páginas.

Paginação automática

Para iterar por todos os resultados em todas as páginas, use o método autoPager(), que busca automaticamente mais páginas conforme necessário.

import com.anthropic.models.messages.batches.BatchListPage;
import com.anthropic.models.messages.batches.MessageBatch;

BatchListPage page = client.messages().batches().list();

// Processar como um Iterable
for (MessageBatch batch : page.autoPager()) {
    IO.println(batch);
}

// Processar como um Stream
page.autoPager()
    .stream()
    .limit(50)
    .forEach(batch -> IO.println(batch));

Ao usar o cliente assíncrono, o método retorna um 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);
}));

// Se você precisar tratar erros ou a conclusão do stream
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!");
        }
    }
}));

// Ou use 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!");
        }
    }));

Paginação manual

Para acessar itens de páginas individuais e solicitar manualmente a próxima página:

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

Sistema de tipos

Imutabilidade e builders

Cada classe no SDK tem um builder associado para construí-la. Cada classe é imutável uma vez construída. Se a classe tem um builder associado, então ela tem um método toBuilder(), que pode ser usado para convertê-la de volta em um builder para fazer uma cópia modificada.

MessageCreateParams params = MessageCreateParams.builder()
  .maxTokens(1024L)
  .addUserMessage("Hello, Claude")
  .model(Model.CLAUDE_OPUS_4_8)
  .build();

// Crie uma cópia modificada usando toBuilder()
MessageCreateParams modified = params.toBuilder().maxTokens(2048L).build();

Como cada classe é imutável, a modificação do builder nunca afetará instâncias de classe já construídas.

Requisições e respostas

Para enviar uma requisição à API do Claude, construa uma instância de alguma classe Params e passe-a para o método de cliente correspondente. Quando a resposta é recebida, ela é desserializada em uma instância de uma classe Java.

Por exemplo, client.messages().create(...) deve ser chamado com uma instância de MessageCreateParams, e retornará uma instância de Message.

Parâmetros não documentados

Para definir parâmetros não documentados, chame os métodos putAdditionalHeader, putAdditionalQueryParam ou putAdditionalBodyProperty em qualquer classe 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();

Esses podem ser acessados no objeto construído posteriormente usando os métodos _additionalHeaders(), _additionalQueryParams() e _additionalBodyProperties().

Os valores passados para esses métodos sobrescrevem valores passados para métodos anteriores. Por razões de segurança, garanta que esses métodos sejam usados apenas com dados de entrada confiáveis.

Para definir parâmetros não documentados em cabeçalhos aninhados, parâmetros de query ou classes de corpo:

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

Essas propriedades podem ser acessadas no objeto aninhado construído posteriormente usando o método _additionalProperties().

Para definir um parâmetro ou propriedade documentada com um valor não documentado ou ainda não suportado, passe um objeto JsonValue para seu setter:

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

Criação de JsonValue

A maneira mais direta de criar um JsonValue é usando seu método from(...):

import com.anthropic.core.JsonValue;

// Cria valores JSON primitivos
JsonValue nullValue = JsonValue.from(null);

JsonValue booleanValue = JsonValue.from(true);

JsonValue numberValue = JsonValue.from(42);

JsonValue stringValue = JsonValue.from("Hello World!");

// Cria um valor de array JSON equivalente a `["Hello", "World"]`
JsonValue arrayValue = JsonValue.from(List.of("Hello", "World"));

// Cria um valor de objeto JSON equivalente a `{ "a": 1, "b": 2 }`
JsonValue objectValue = JsonValue.from(Map.of("a", 1, "b", 2));

// Cria um JSON aninhado arbitrariamente equivalente a:
// { "a": [1, 2], "b": [3, 4] }
JsonValue complexValue = JsonValue.from(Map.of("a", List.of(1, 2), "b", List.of(3, 4)));

Omitindo forçadamente parâmetros obrigatórios

Normalmente, o método build de uma classe Builder lançará IllegalStateException se algum parâmetro ou propriedade obrigatória não estiver definida. Para omitir forçadamente um parâmetro ou propriedade obrigatória, passe 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();

Propriedades de resposta

Para acessar propriedades de resposta não documentadas, chame o método _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!";
    }

    // Outros métodos incluem `visitMissing`, `visitString`, `visitArray` e `visitObject`
    // A implementação padrão de cada método não implementado delega para `visitDefault`,
    // que lança uma exceção por padrão, mas também pode ser sobrescrito
});

Para acessar o valor JSON bruto de uma propriedade, chame seu método com prefixo _:

import com.anthropic.core.JsonField;
import com.anthropic.models.messages.StopReason;

JsonField<StopReason> stopReason = client.messages().create(params)._stopReason();

if (stopReason.isMissing()) {
  // A propriedade está ausente na resposta JSON
} else if (stopReason.isNull()) {
  // A propriedade foi definida como null literal
} else {
  // Verifica se o valor foi fornecido como uma string
  // Outros métodos incluem `asNumber()`, `asBoolean()`, etc.
  Optional<String> jsonString = stopReason.asString();

  // Tenta desserializar em um tipo personalizado
  MyClass myObject = stopReason.asUnknown().orElseThrow().convert(MyClass.class);
}

Validação de resposta

Por padrão, o SDK não lança uma exceção quando a API retorna uma resposta que não corresponde ao tipo esperado. Ele lança AnthropicInvalidDataException apenas se você acessar diretamente a propriedade.

Para verificar antecipadamente se a resposta está completamente bem tipada, chame validate():

import com.anthropic.models.messages.Message;

Message message = client.messages().create(params).validate();

Ou configure por requisição:

import com.anthropic.models.messages.Message;

Message message = client
  .messages()
  .create(params, RequestOptions.builder().responseValidation(true).build());

Ou configure o padrão para todas as chamadas de método no nível do cliente:

import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;

AnthropicClient client = AnthropicOkHttpClient.builder()
  .fromEnv()
  .responseValidation(true)
  .build();

Personalização do cliente HTTP

Configuração de proxy

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

Configuração de HTTPS / SSL

A maioria das aplicações não deve chamar esses métodos e, em vez disso, usar os padrões do sistema. Os padrões incluem otimizações especiais que podem ser perdidas se as implementações forem modificadas.

import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;

AnthropicClient client = AnthropicOkHttpClient.builder()
  .fromEnv()
  .sslSocketFactory(yourSSLSocketFactory)
  .trustManager(yourTrustManager)
  .hostnameVerifier(yourHostnameVerifier)
  .build();

Cliente HTTP personalizado

O SDK consiste em três artefatos:

  • anthropic-java-core - Contém a lógica principal do SDK, não depende do OkHttp. Expõe AnthropicClient, AnthropicClientAsync e suas classes de implementação, todas as quais podem funcionar com qualquer cliente HTTP.
  • anthropic-java-client-okhttp - Depende do OkHttp. Expõe AnthropicOkHttpClient e AnthropicOkHttpClientAsync.
  • anthropic-java - Depende e expõe as APIs de anthropic-java-core e anthropic-java-client-okhttp. Não tem lógica própria.

Essa estrutura permite substituir o cliente HTTP padrão do SDK sem incluir dependências desnecessárias.

OkHttpClient personalizado

Experimente as opções de rede disponíveis antes de substituir o cliente padrão.

Para usar um OkHttpClient personalizado:

  1. Substitua sua dependência anthropic-java por anthropic-java-core.
  2. Copie a classe OkHttpClient de anthropic-java-client-okhttp para seu código e personalize-a.
  3. Construa AnthropicClientImpl ou AnthropicClientAsyncImpl usando seu cliente personalizado.

Cliente HTTP completamente personalizado

Para usar um cliente HTTP completamente personalizado:

  1. Substitua sua dependência anthropic-java por anthropic-java-core.
  2. Escreva uma classe que implemente a interface HttpClient.
  3. Construa AnthropicClientImpl ou AnthropicClientAsyncImpl usando sua nova classe de cliente.

Integrações de plataforma

Para guias detalhados de configuração de plataforma com exemplos de código, consulte:

  • Amazon Bedrock
  • Amazon Bedrock (legado)
  • Vertex AI
  • Microsoft Foundry
  • Claude Platform na AWS

O SDK Java suporta as seguintes plataformas através de dependências separadas que fornecem implementações de Backend específicas da plataforma:

  • Bedrock: com.anthropic:anthropic-java-bedrock: Use BedrockMantleBackend.fromEnv() ou BedrockMantleBackend.builder() para o endpoint Bedrock da Messages API, ou BedrockBackend.fromEnv() / BedrockBackend.builder() (caminho bedrock-runtime).
  • Vertex AI: com.anthropic:anthropic-java-vertex: Use VertexBackend.fromEnv() ou VertexBackend.builder().
  • Foundry: com.anthropic:anthropic-java-foundry: Use FoundryBackend.fromEnv() ou FoundryBackend.builder().
  • Claude Platform na AWS: com.anthropic:anthropic-java-aws: Use AwsBackend.fromEnv() (lê ANTHROPIC_AWS_WORKSPACE_ID e a cadeia padrão de região/credenciais da AWS) ou AwsBackend.builder(). Disponível em beta.

Use BedrockMantleBackend para novos projetos; BedrockBackend permanece para aplicações existentes que usam a API InvokeModel do Bedrock.

Cada implementação de Backend é passada para o cliente com .backend() em AnthropicOkHttpClient.builder(). Cada backend de nuvem inclui suas respectivas classes de SDK da plataforma de nuvem como dependências transitivas.

Uso avançado

Acesso à resposta bruta

Para acessar cabeçalhos HTTP, códigos de status e o corpo bruto da resposta, prefixe qualquer chamada de método HTTP com 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();

Você ainda pode desserializar a resposta em uma instância de uma classe Java, se necessário:

import com.anthropic.models.messages.Message;

Message parsedMessage = message.parse();

Logging

O SDK usa o interceptor de logging padrão do OkHttp.

Habilite o logging definindo a variável de ambiente ANTHROPIC_LOG como info:

export ANTHROPIC_LOG=info

Ou como debug para logging mais detalhado:

export ANTHROPIC_LOG=debug

Funcionalidade de API não documentada

O SDK é tipado para uso conveniente da API documentada. No entanto, ele também suporta trabalhar com partes não documentadas ou ainda não suportadas da API.

Parâmetros de requisição não documentados

Para definir parâmetros de requisição não documentados, use os métodos putAdditionalHeader, putAdditionalQueryParam ou putAdditionalBodyProperty conforme descrito em Parâmetros não documentados.

Propriedades de resposta não documentadas

Para acessar propriedades de resposta não documentadas, use o método _additionalProperties() conforme descrito em Propriedades de resposta.

Valores de enum novos ou não lançados

Classes semelhantes a enum no SDK, como Model e AnthropicBeta, não são tipos enum fechados do Java. Cada uma fornece um método factory of(String) que aceita qualquer string, para que você possa usar valores que ainda não foram adicionados ao SDK, como um modelo ou cabeçalho beta lançado após a versão do seu 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");

Métodos de builder que aceitam esses tipos frequentemente também fornecem uma sobrecarga String que chama of(...) para você:

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

Prefira as constantes bem tipadas (por exemplo, Model.CLAUDE_OPUS_4_7) para obter autocompletar e avisos de depreciação. As sobrecargas String e of(...) servem principalmente para definir o campo com um valor não documentado ou ainda não suportado enquanto aguarda um lançamento do SDK que o inclua.

Recursos beta

Recursos beta estão disponíveis antes do lançamento geral para obter feedback antecipado e testar novas funcionalidades. Você pode verificar a disponibilidade de todas as capacidades e ferramentas do Claude na visão geral de construir com Claude.

Você pode acessar a maioria dos recursos beta da API através do método beta() no cliente. Para habilitar um recurso beta específico, adicione o cabeçalho beta apropriado com .addBeta() ao construir os parâmetros da mensagem.

Por exemplo, para usar a 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());
}

Perguntas frequentes

Versionamento semântico

Este pacote geralmente segue as convenções do SemVer, embora certas mudanças incompatíveis com versões anteriores possam ser lançadas como versões menores:

  1. Mudanças nos internos da biblioteca que são tecnicamente públicos, mas não destinados ou documentados para uso externo.
  2. Mudanças que não se espera que impactem a grande maioria dos usuários na prática.

Recursos adicionais

  • Repositório GitHub
  • Javadocs
  • Referência da API
  • Streaming de mensagens
  • Uso de ferramentas com Claude

Was this page helpful?

  • Instalação
  • Requisitos
  • Início rápido
  • Configuração do cliente
  • Configuração da chave de API
  • Opções de configuração
  • Modificando a configuração
  • Uso assíncrono
  • Streaming
  • Streaming síncrono
  • Streaming assíncrono
  • Streaming com acumulador de mensagens
  • Saídas estruturadas
  • Uso de ferramentas
  • Definindo ferramentas com anotações
  • Chamando ferramentas
  • Conversão de nomes de ferramentas
  • Validação local do esquema JSON da ferramenta
  • Anotando classes de ferramentas
  • Lotes de mensagens
  • Upload de arquivos
  • Respostas binárias
  • Tratamento de erros
  • Mapeamento de códigos de status
  • IDs de requisição
  • Novas tentativas
  • Timeouts
  • Requisições longas
  • Paginação
  • Paginação automática
  • Paginação manual
  • Sistema de tipos
  • Imutabilidade e builders
  • Requisições e respostas
  • Parâmetros não documentados
  • Criação de JsonValue
  • Omitindo forçadamente parâmetros obrigatórios
  • Propriedades de resposta
  • Validação de resposta
  • Personalização do cliente HTTP
  • Configuração de proxy
  • Configuração de HTTPS / SSL
  • Cliente HTTP personalizado
  • Integrações de plataforma
  • Uso avançado
  • Acesso à resposta bruta
  • Logging
  • Funcionalidade de API não documentada
  • Recursos beta
  • Perguntas frequentes
  • Versionamento semântico
  • Recursos adicionais