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 | 系統屬性 | 環境變數 | 必填 | 預設值 |
|---|---|---|---|---|
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)
.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- 所有例外的基底類別。
狀態碼對應
| 狀態碼 | 例外 |
|---|---|
| 400 | BadRequestException |
| 401 | UnauthorizedException |
| 403 | PermissionDeniedException |
| 404 | NotFoundException |
| 422 | UnprocessableEntityException |
| 429 | RateLimitException |
| 5xx | InternalServerException |
| 其他 | 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 類別上呼叫 putAdditionalHeader、putAdditionalQueryParam 或 putAdditionalBodyProperty 方法:
import com.anthropic.core.JsonValue;
import com.anthropic.models.messages.MessageCreateParams;
MessageCreateParams params = MessageCreateParams.builder()
.putAdditionalHeader("Secret-Header", "42")
.putAdditionalQueryParam("secret_query_param", "42")
.putAdditionalBodyProperty("secretProperty", JsonValue.from("42"))
.build();之後可以在已建構的物件上使用 _additionalHeaders()、_additionalQueryParams() 和 _additionalBodyProperties() 方法存取這些值。
若要在巢狀的標頭、查詢參數或主體類別上設定未記載的參數:
import com.anthropic.core.JsonValue;
import com.anthropic.models.messages.MessageCreateParams;
import com.anthropic.models.messages.Metadata;
MessageCreateParams params = MessageCreateParams.builder()
.metadata(
Metadata.builder().putAdditionalProperty("secretProperty", JsonValue.from("42")).build()
)
.build();之後可以在巢狀的已建構物件上使用 _additionalProperties() 方法存取這些屬性。
若要將已記載的參數或屬性設定為未記載或尚未支援的值,請將 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。公開AnthropicClient、AnthropicClientAsync及其實作類別,這些全都可以搭配任何 HTTP 用戶端運作。anthropic-java-client-okhttp- 依賴 OkHttp。公開AnthropicOkHttpClient與AnthropicOkHttpClientAsync。anthropic-java- 依賴並公開anthropic-java-core與anthropic-java-client-okhttp兩者的 API。本身沒有自己的邏輯。
此結構允許在不引入不必要相依性的情況下替換 SDK 的預設 HTTP 用戶端。
自訂的 OkHttpClient
若要使用自訂的 OkHttpClient:
- 將您的
anthropic-java相依性替換為anthropic-java-core。 - 將
anthropic-java-client-okhttp的OkHttpClient類別複製到您的程式碼中並加以自訂。 - 使用您自訂的用戶端建構
AnthropicClientImpl或AnthropicClientAsyncImpl。
完全自訂的 HTTP 用戶端
若要使用完全自訂的 HTTP 用戶端:
- 將您的
anthropic-java相依性替換為anthropic-java-core。 - 撰寫一個實作
HttpClient介面的類別。 - 使用您的新用戶端類別建構
AnthropicClientImpl或AnthropicClientAsyncImpl。
平台整合
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()。
新專案請使用 BedrockMantleBackend;BedrockBackend 則保留給使用 Bedrock InvokeModel API 的既有應用程式。
每個 Backend 實作都透過 AnthropicOkHttpClient.builder() 上的 .backend() 傳遞給用戶端。每個雲端後端都會將其各自的雲端平台 SDK 類別作為遞移相依性引入。
進階用法
原始回應存取
若要存取 HTTP 標頭、狀態碼與原始回應主體,請在任何 HTTP 方法呼叫前加上 withRawResponse():
import com.anthropic.core.http.Headers;
import com.anthropic.core.http.HttpResponseFor;
import com.anthropic.models.messages.Message;
import com.anthropic.models.messages.MessageCreateParams;
import com.anthropic.models.messages.Model;
MessageCreateParams params = MessageCreateParams.builder()
.maxTokens(1024L)
.addUserMessage("Hello, Claude")
.model(Model.CLAUDE_OPUS_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 拋出了例外,但您確定版本是相容的,則可在 AnthropicOkHttpClient 或 AnthropicOkHttpClientAsync 上使用 checkJacksonVersionCompatibility 停用版本檢查。
較舊的 Jackson 版本中也存在可能影響 SDK 的錯誤。SDK 不會繞過所有 Jackson 錯誤,而是期望使用者針對這些問題升級 Jackson。
雖然 SDK 使用反射,但它仍可搭配 ProGuard 與 R8 使用,因為 anthropic-java-core 發布時附帶了包含 keep 規則的設定檔。
ProGuard 與 R8 應會自動偵測並使用已發布的規則,但如有必要,您也可以手動複製這些 keep 規則。
未記載的 API 功能
SDK 的型別設計是為了便利地使用已記載的 API。然而,它也支援使用 API 中未記載或尚未支援的部分。
未記載的請求參數
若要設定未記載的請求參數,請依照未記載的參數中所述,使用 putAdditionalHeader、putAdditionalQueryParam 或 putAdditionalBodyProperty 方法。
未記載的回應屬性
若要存取未記載的回應屬性,請依照回應屬性中所述,使用 _additionalProperties() 方法。
新的或尚未發布的列舉值
SDK 中類似列舉的類別,例如 Model 與 AnthropicBeta,並非封閉的 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());
}常見問題
Java enum 類別並非天生就具備向前相容性。在 SDK 中使用它們,可能會在 API 更新為回應新的列舉值時導致執行階段例外。
由於這些類別是開放的,您也可以透過其 of(String) 工廠方法以任意字串值建構它們。如果您需要使用尚未包含在您 SDK 版本中的值,請參閱新的或尚未發布的列舉值。
使用 JsonField<T> 可實現幾項功能:
- 允許使用未記載的 API 功能
- 延遲驗證 API 回應是否符合預期的結構
- 區分不存在的值與明確為 null 的值
在資料類別中新增欄位並不具備向後相容性,而 SDK 希望避免每次在類別中新增欄位時都引入破壞性變更。
受檢例外被廣泛認為是 Java 程式語言中的一個錯誤。事實上,Kotlin 正是因為這個原因而省略了它們。
受檢例外:
- 處理起來很冗長
- 鼓勵在錯誤的抽象層級處理錯誤,而在該層級對錯誤無能為力
- 由於函式著色問題,傳播起來很繁瑣
- 與 lambda 搭配不佳(同樣是因為函式著色問題)
語意化版本
此套件大致遵循 SemVer 慣例,但某些向後不相容的變更可能會以次要版本發布:
- 對函式庫內部的變更,這些內部在技術上是公開的,但並非預期或記載供外部使用。
- 預期在實務上不會影響絕大多數使用者的變更。
其他資源
Was this page helpful?