Claude Platform Docs
CLI、SDK 與函式庫用戶端 SDK

Java SDK

安裝並設定 Anthropic Java SDK,支援建構器模式與非同步操作

Anthropic Java SDK 讓以 Java 撰寫的應用程式能夠便利地存取 Claude API。它使用「builder pattern」(建構器模式)來建立請求,並同時支援同步與非同步操作。

安裝

implementation("com.anthropic:anthropic-java:2.58.0")

需求

此函式庫需要 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)
  .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 請求標頭中設定工作區 ID;選擇工作區說明了此 SDK 的逐請求選項。

設定選項

Setter系統屬性環境變數必填預設值
apiKeyanthropic.apiKeyANTHROPIC_API_KEYfalse-
authTokenanthropic.authTokenANTHROPIC_AUTH_TOKENfalse-
baseUrlanthropic.baseUrlANTHROPIC_BASE_URLtrue"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)
  .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)
  .build();

CompletableFuture<Message> message = client.messages().create(params);

非同步用戶端支援與同步用戶端相同的選項,差別在於大多數方法會回傳 CompletableFuture

串流

SDK 定義了會回傳回應「chunk」(區塊)串流的方法,每個區塊一抵達即可個別處理,而不必等待完整回應。

同步串流

對於同步用戶端,這些「streaming」(串流)方法會回傳 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)讓您能將外部工具與函式直接整合到 AI 模型的回應中。模型不再只是產生純文字,而是能在適當時機輸出呼叫工具或函式的指令(附帶參數)。您為工具定義 JSON schema,模型則使用這些 schema 來判斷何時以及如何使用這些工具。

工具使用功能支援「strict」(嚴格)模式,可保證 AI 模型的 JSON 輸出符合您在輸入參數中提供的 JSON schema。

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>) 將它們加入訊息參數中,然後在 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_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
              // 新增一則訊息,表示已請求工具使用。
              .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");
}

工具名稱轉換

工具名稱是從 camel case 的工具類別名稱(例如 GetWeather)推導而來,並轉換為 snake case(例如 get_weather)。單字邊界的起點為:目前字元不是第一個字元、為大寫,且前一個字元為小寫或後一個字元為小寫。例如,MyJSONParser 會變成 my_json_parser,而 ParseJSON 會變成 parse_json。此轉換可使用 @JsonTypeName 註解加以覆寫。

本機工具 JSON schema 驗證

您可以執行本機驗證,以檢查從工具類別推導出的 JSON schema 是否符合 Anthropic 的限制。本機驗證預設為啟用,但可以停用:

MessageCreateParams.Builder createParamsBuilder = MessageCreateParams.builder()
  .model(Model.CLAUDE_OPUS_5)
  .maxTokens(2048)
  .addTool(GetWeather.class, JsonSchemaLocalValidation.NO)
  .addUserMessage("What's the temperature in New York?");

為工具類別加上註解

您可以使用註解在 JSON schema 中加入更多關於工具的資訊:

  • @JsonClassDescription - 為工具類別加入描述,詳細說明何時以及如何使用該工具。
  • @JsonTypeName - 將工具名稱設定為類別簡單名稱轉換為 snake case 以外的其他名稱。
  • @JsonPropertyDescription - 為工具參數加入詳細描述。
  • @JsonIgnore - 將 public 欄位或 getter 方法從為工具參數產生的 JSON schema 中排除。
  • @JsonProperty - 將非 public 的欄位或 getter 方法納入為工具參數產生的 JSON schema 中。

訊息批次

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

二進位回應

對於不一定會被解析為 JSON 的 API 回應,SDK 定義了回傳二進位回應的方法:

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 - I/O 網路錯誤。
  • AnthropicRetryableException - 表示可重試之失敗的通用錯誤。
  • AnthropicInvalidDataException - 無法解讀已成功解析的資料(例如,存取一個應為必填的屬性,但 API 意外地省略了它)。
  • AnthropicException - 所有例外的基底類別。

狀態碼對應

狀態碼例外
400BadRequestException
401UnauthorizedException
403PermissionDeniedException
404NotFoundException
422UnprocessableEntityException
429RateLimitException
5xxInternalServerException
其他UnexpectedStatusCodeException

在初始 HTTP 回應成功之後,若於 SSE 串流期間遇到錯誤,則會拋出 SseException

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

請求 ID

使用原始回應時,您可以透過 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 次,請求之間採用短暫的指數退避。

只有下列錯誤類型會被重試:

  • 連線錯誤(例如,因網路連線問題所致)
  • 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 參數縮放。

對於非串流請求,動態逾時會依據 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 會定期 ping API 以保持連線存活,並降低這類網路的影響。

如果預期非串流請求會花費超過 10 分鐘,SDK 會拋出錯誤。使用串流方法或在用戶端或請求層級覆寫逾時即可停用此錯誤。

分頁

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_5)
  .build();

// 使用 toBuilder() 建立修改後的副本
MessageCreateParams modified = params.toBuilder().maxTokens(2048L).build();

由於每個類別都是不可變的,修改建構器絕不會影響已建構的類別實例。

請求與回應

若要向 Claude API 傳送請求,請建構某個 Params 類別的實例,並將其傳遞給對應的用戶端方法。收到回應後,它會被反序列化為某個 Java 類別的實例。

例如,client.messages().create(...) 應以 MessageCreateParams 的實例呼叫,並回傳 Message 的實例。

未記載的參數

若要設定未記載的參數,請在任何 Params 類別上呼叫 putAdditionalHeaderputAdditionalQueryParamputAdditionalBodyProperty 方法:

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 物件傳遞給其 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_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!");

// 建立等同於 `["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_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);
}

回應驗證

預設情況下,當 API 回傳與預期型別不符的回應時,SDK 不會拋出例外。只有在您直接存取該屬性時,它才會拋出 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 用戶端自訂

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

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 由三個 artifact 組成:

  • anthropic-java-core - 包含核心 SDK 邏輯,不依賴 OkHttp。公開 AnthropicClientAnthropicClientAsync 及其實作類別,這些全都可以搭配任何 HTTP 用戶端運作。
  • anthropic-java-client-okhttp - 依賴 OkHttp。公開 AnthropicOkHttpClientAnthropicOkHttpClientAsync
  • anthropic-java - 依賴並公開 anthropic-java-coreanthropic-java-client-okhttp 兩者的 API。本身沒有自己的邏輯。

此結構允許在不引入不必要相依性的情況下替換 SDK 的預設 HTTP 用戶端。

自訂的 OkHttpClient

若要使用自訂的 OkHttpClient

  1. 將您的 anthropic-java 相依性替換為 anthropic-java-core
  2. anthropic-java-client-okhttpOkHttpClient 類別複製到您的程式碼中並加以自訂。
  3. 使用您自訂的用戶端建構 AnthropicClientImplAnthropicClientAsyncImpl

完全自訂的 HTTP 用戶端

若要使用完全自訂的 HTTP 用戶端:

  1. 將您的 anthropic-java 相依性替換為 anthropic-java-core
  2. 撰寫一個實作 HttpClient 介面的類別。
  3. 使用您的新用戶端類別建構 AnthropicClientImplAnthropicClientAsyncImpl

平台整合

Java SDK 透過提供平台專屬 Backend 實作的獨立相依性來支援下列平台:

  • Agent Platform: com.anthropic:anthropic-java-vertex:使用 VertexBackend.fromEnv()VertexBackend.builder()
  • Bedrock: com.anthropic:anthropic-java-bedrock:針對 Messages-API Bedrock 端點使用 BedrockMantleBackend.fromEnv()BedrockMantleBackend.builder(),或使用 BedrockBackend.fromEnv() / BedrockBackend.builder()bedrock-runtime 路徑)。
  • Claude Platform on AWS: com.anthropic:anthropic-java-aws:使用 AwsBackend.fromEnv()(讀取 ANTHROPIC_AWS_WORKSPACE_ID 以及 AWS 預設區域/憑證鏈)或 AwsBackend.builder()。目前為 beta 版。
  • Foundry: com.anthropic:anthropic-java-foundry:使用 FoundryBackend.fromEnv()FoundryBackend.builder()

新專案請使用 BedrockMantleBackendBedrockBackend 則保留給使用 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_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=debug

未記載的 API 功能

SDK 的型別設計是為了便利地使用已記載的 API。然而,它也支援使用 API 中未記載或尚未支援的部分。

未記載的請求參數

若要設定未記載的請求參數,請依照未記載的參數中所述,使用 putAdditionalHeaderputAdditionalQueryParamputAdditionalBodyProperty 方法。

未記載的回應屬性

若要存取未記載的回應屬性,請依照回應屬性中所述,使用 _additionalProperties() 方法。

新的或尚未發布的列舉值

SDK 中類似列舉的類別,例如 ModelAnthropicBeta,並非封閉的 Java enum 型別。每一個都提供接受任意字串的 of(String) 工廠方法,因此您可以使用尚未加入 SDK 的值,例如在您的 SDK 版本之後才發布的模型或 beta 標頭:

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_5),以便獲得自動完成與棄用警告。String 多載與 of(...) 主要用於在等待包含該值的 SDK 版本發布期間,將欄位設定為未記載或尚未支援的值。

Beta 功能

Beta 功能會在正式發布前提供,以取得早期回饋並測試新功能。您可以在使用 Claude 進行建構概覽中查看 Claude 所有功能與工具的可用性。

您可以透過用戶端上的 beta() 方法存取大多數 beta API 功能。若要啟用特定的 beta 功能,請在建構訊息參數時使用 .addBeta() 加入適當的 beta 標頭

例如,若要啟用上下文編輯

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)
            .maxTokens(1024L)
            .addBeta(AnthropicBeta.CONTEXT_MANAGEMENT_2025_06_27)
            .addUserMessage("Hello, Claude")
            .build());
}

常見問題

語意化版本

此套件大致遵循 SemVer 慣例,但某些向後不相容的變更可能會以次要版本發布:

  1. 對函式庫內部的變更,這些內部在技術上是公開的,但並非預期或記載供外部使用。
  2. 預期在實務上不會影響絕大多數使用者的變更。

其他資源

Was this page helpful?