Anthropic Java SDK 为使用 Java 编写的应用程序提供了便捷访问 Anthropic REST API 的方式。它使用构建器模式(builder pattern)创建请求,并同时支持同步和异步操作。
有关包含代码示例的 API 功能文档,请参阅 API 参考。本页面介绍 Java 特定的 SDK 功能和配置。
此库需要 Java 8 或更高版本。
该 SDK 支持 Java 8 及更高版本。本文档中的代码示例以 JDK 25 紧凑源文件的形式编写,使用裸 void main() 入口点和 IO.println() 进行输出。API 调用本身在所有受支持的 JDK 上都是相同的;如需在较早版本上编译示例,请将 IO.println(...) 替换为 System.out.println(...),并将方法体放入类中的 public static void main(String[] args) 内。
import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;
import com.anthropic.models.messages.Message;
import com.anthropic.models.messages.MessageCreateParams;
import com.anthropic.models.messages.Model;
// 使用 `anthropic.apiKey`、`anthropic.authToken` 和 `anthropic.baseUrl` 系统属性进行配置
// 或使用 `ANTHROPIC_API_KEY`、`ANTHROPIC_AUTH_TOKEN` 和 `ANTHROPIC_BASE_URL` 环境变量进行配置
AnthropicClient client = AnthropicOkHttpClient.fromEnv();
MessageCreateParams params = MessageCreateParams.builder()
.maxTokens(1024L)
.addUserMessage("Hello, Claude")
.model(Model.CLAUDE_OPUS_4_8)
.build();
Message message = client.messages().create(params);使用系统属性或环境变量配置客户端:
import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;
// 使用 `anthropic.apiKey`、`anthropic.authToken` 和 `anthropic.baseUrl` 系统属性进行配置
// 或使用 `ANTHROPIC_API_KEY`、`ANTHROPIC_AUTH_TOKEN` 和 `ANTHROPIC_BASE_URL` 环境变量进行配置
AnthropicClient client = AnthropicOkHttpClient.fromEnv();或手动配置:
import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;
AnthropicClient client = AnthropicOkHttpClient.builder()
.apiKey("my-anthropic-api-key")
.build();或结合使用两种方式:
import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;
AnthropicClient client = AnthropicOkHttpClient.builder()
// 使用系统属性或环境变量进行配置
.fromEnv()
.apiKey("my-anthropic-api-key")
.build();有关包括 Workload Identity Federation(工作负载身份联合)在内的身份验证选项,请参阅身份验证。
| Setter | 系统属性 | 环境变量 | 是否必需 | 默认值 |
|---|---|---|---|---|
apiKey | anthropic.apiKey | ANTHROPIC_API_KEY | false | - |
authToken | anthropic.authToken | ANTHROPIC_AUTH_TOKEN | false | - |
baseUrl | anthropic.baseUrl | ANTHROPIC_BASE_URL | true | "https://api.anthropic.com" |
系统属性优先于环境变量。
不要在同一个应用程序中创建多个客户端。每个客户端都有一个连接池和线程池,在请求之间共享这些资源会更高效。
要在复用相同连接池和线程池的同时临时使用修改后的客户端配置,请在任何客户端或服务上调用 withOptions():
import com.anthropic.client.AnthropicClient;
AnthropicClient clientWithOptions = client.withOptions(optionsBuilder -> {
optionsBuilder.baseUrl("https://example.com");
optionsBuilder.maxRetries(42);
});withOptions() 方法不会影响原始客户端或服务。
默认客户端是同步的。要切换到异步执行,请调用 async() 方法:
import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;
import com.anthropic.models.messages.Message;
import com.anthropic.models.messages.MessageCreateParams;
import com.anthropic.models.messages.Model;
AnthropicClient client = AnthropicOkHttpClient.fromEnv();
MessageCreateParams params = MessageCreateParams.builder()
.maxTokens(1024L)
.addUserMessage("Hello, Claude")
.model(Model.CLAUDE_OPUS_4_8)
.build();
CompletableFuture<Message> message = client.async().messages().create(params);或从一开始就创建异步客户端:
import com.anthropic.client.AnthropicClientAsync;
import com.anthropic.client.okhttp.AnthropicOkHttpClientAsync;
import com.anthropic.models.messages.Message;
import com.anthropic.models.messages.MessageCreateParams;
import com.anthropic.models.messages.Model;
AnthropicClientAsync client = AnthropicOkHttpClientAsync.fromEnv();
MessageCreateParams params = MessageCreateParams.builder()
.maxTokens(1024L)
.addUserMessage("Hello, Claude")
.model(Model.CLAUDE_OPUS_4_8)
.build();
CompletableFuture<Message> message = client.messages().create(params);异步客户端支持与同步客户端相同的选项,只是大多数方法返回 CompletableFuture。
SDK 定义了返回响应"块"(chunk)流的方法,每个块在到达时即可单独处理,而无需等待完整响应。
对于同步客户端,这些流式传输方法返回 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 的工具使用让您可以将外部工具和函数直接集成到 AI 模型的响应中。模型可以在适当的时候输出调用工具或函数的指令(带参数),而不是生成纯文本。您为工具定义 JSON schema,模型使用这些 schema 来确定何时以及如何使用这些工具。
工具使用功能支持"严格"(strict)模式,该模式保证 AI 模型的 JSON 输出符合您在输入参数中提供的 JSON schema。
SDK 可以从任意 Java 类的结构自动派生工具及其参数:类名(转换为蛇形命名法)提供工具名称,类的字段定义工具的参数。
请将您的工具类声明为顶级类或 static 嵌套类。此要求来自 Jackson Databind 库(com.fasterxml.jackson.databind),SDK 使用该库将工具输入反序列化为您的类实例,而该库无法实例化非静态内部类。
import com.fasterxml.jackson.annotation.JsonClassDescription;
import com.fasterxml.jackson.annotation.JsonPropertyDescription;
enum Unit {
CELSIUS,
FAHRENHEIT;
public String toString() {
switch (this) {
case CELSIUS:
return "C";
case FAHRENHEIT:
default:
return "F";
}
}
public double fromKelvin(double temperatureK) {
switch (this) {
case CELSIUS:
return temperatureK - 273.15;
case FAHRENHEIT:
default:
return (temperatureK - 273.15) * 1.8 + 32.0;
}
}
}
@JsonClassDescription("Get the weather in a given location")
static class GetWeather {
@JsonPropertyDescription("The city and state, e.g. San Francisco, CA")
public String location;
@JsonPropertyDescription("The unit of temperature")
public Unit unit;
public Weather execute() {
double temperatureK;
switch (location) {
case "San Francisco, CA":
temperatureK = 300.0;
break;
case "New York, NY":
temperatureK = 310.0;
break;
case "Dallas, TX":
temperatureK = 305.0;
break;
default:
temperatureK = 295;
break;
}
return new Weather(String.format("%.0f%s", unit.fromKelvin(temperatureK), unit));
}
}
static class Weather {
public String temperature;
public Weather(String temperature) {
this.temperature = temperature;
}
}定义工具类后,使用 MessageCreateParams.Builder.addTool(Class<T>) 将它们添加到消息参数中,然后在 AI 模型的响应中请求时调用它们。可以使用 BetaToolUseBlock.input(Class<T>) 将 JSON 形式的工具参数解析为您定义工具的类的实例。
调用工具后,使用 BetaToolResultBlockParam.Builder.contentAsJson(Object) 将工具的结果传回给 AI 模型:
import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;
import com.anthropic.models.beta.messages.*;
import com.anthropic.models.messages.Model;
AnthropicClient client = AnthropicOkHttpClient.fromEnv();
MessageCreateParams.Builder createParamsBuilder = MessageCreateParams.builder()
.model(Model.CLAUDE_OPUS_4_8)
.maxTokens(2048)
.addTool(GetWeather.class)
.addUserMessage("What's the temperature in New York?");
client.beta().messages().create(createParamsBuilder.build()).content().stream()
.flatMap(contentBlock -> contentBlock.toolUse().stream())
.forEach(toolUseBlock -> createParamsBuilder
// 添加一条消息,表明已请求工具使用。
.addAssistantMessageOfBetaContentBlockParams(
List.of(BetaContentBlockParam.ofToolUse(BetaToolUseBlockParam.builder()
.name(toolUseBlock.name())
.id(toolUseBlock.id())
.input(toolUseBlock._input())
.build())))
// 添加一条消息,包含所请求工具使用的结果。
.addUserMessageOfBetaContentBlockParams(
List.of(BetaContentBlockParam.ofToolResult(BetaToolResultBlockParam.builder()
.toolUseId(toolUseBlock.id())
.contentAsJson(callTool(toolUseBlock))
.build()))));
client.beta().messages().create(createParamsBuilder.build()).content().stream()
.flatMap(contentBlock -> contentBlock.text().stream())
.forEach(textBlock -> IO.println(textBlock.text()));
private static Object callTool(BetaToolUseBlock toolUseBlock) {
if (!"get_weather".equals(toolUseBlock.name())) {
throw new IllegalArgumentException("Unknown tool: " + toolUseBlock.name());
}
GetWeather tool = toolUseBlock.input(GetWeather.class);
return tool != null ? tool.execute() : new Weather("unknown");
}工具名称从驼峰式工具类名(例如 GetWeather)派生,并转换为蛇形命名法(例如 get_weather)。单词边界的判定规则为:当前字符不是第一个字符、是大写字母,并且前一个字符是小写字母,或后一个字符是小写字母。例如,MyJSONParser 变为 my_json_parser,ParseJSON 变为 parse_json。可以使用 @JsonTypeName 注解覆盖此转换。
您可以执行本地验证,以检查从您的工具类派生的 JSON schema 是否符合 Anthropic 的限制。本地验证默认启用,但可以禁用:
MessageCreateParams.Builder createParamsBuilder = MessageCreateParams.builder()
.model(Model.CLAUDE_OPUS_4_8)
.maxTokens(2048)
.addTool(GetWeather.class, JsonSchemaLocalValidation.NO)
.addUserMessage("What's the temperature in New York?");您可以使用注解向 JSON schema 添加有关工具的更多信息:
@JsonClassDescription - 为工具类添加描述,详细说明何时以及如何使用该工具。@JsonTypeName - 将工具名称设置为类的简单名称转换为蛇形命名法以外的其他名称。@JsonPropertyDescription - 为工具参数添加详细描述。@JsonIgnore - 从为工具参数生成的 JSON schema 中排除 public 字段或 getter 方法。@JsonProperty - 在为工具参数生成的 JSON schema 中包含非 public 字段或 getter 方法。SDK 在 client.messages().batches() 命名空间下提供对批处理的支持。有关如何列出批次并进行分页,请参阅分页。
SDK 定义了通过 MultipartField 类接受文件的方法:
import com.anthropic.core.MultipartField;
import com.anthropic.models.beta.files.FileMetadata;
import com.anthropic.models.beta.files.FileUploadParams;
FileUploadParams params = FileUploadParams.builder()
.file(
MultipartField.<InputStream>builder()
.value(Files.newInputStream(Paths.get("/path/to/file.pdf")))
.contentType("application/pdf")
.build()
)
.build();
FileMetadata fileMetadata = client.beta().files().upload(params);或从 InputStream:
import com.anthropic.core.MultipartField;
import com.anthropic.models.beta.files.FileMetadata;
import com.anthropic.models.beta.files.FileUploadParams;
FileUploadParams params = FileUploadParams.builder()
.file(
MultipartField.<InputStream>builder()
.value(new URL("https://example.com/path/to/file").openStream())
.filename("document.pdf")
.contentType("application/pdf")
.build()
)
.build();
FileMetadata fileMetadata = client.beta().files().upload(params);或从内存中的字节:
import com.anthropic.core.MultipartField;
import com.anthropic.models.beta.files.FileMetadata;
import com.anthropic.models.beta.files.FileUploadParams;
FileUploadParams params = FileUploadParams.builder()
.file(
MultipartField.<InputStream>builder()
.value(new ByteArrayInputStream("content".getBytes()))
.filename("document.txt")
.contentType("text/plain")
.build()
)
.build();
FileMetadata fileMetadata = client.beta().files().upload(params);对于不一定解析为 JSON 的 API 响应,SDK 定义了返回二进制响应的方法:
import com.anthropic.core.http.HttpResponse;
HttpResponse response = client.beta().files().download("file_id");将响应内容保存到文件:
import com.anthropic.core.http.HttpResponse;
try (HttpResponse response = client.beta().files().download(params)) {
Files.copy(
response.body(),
Paths.get(path),
StandardCopyOption.REPLACE_EXISTING
);
} catch (Exception e) {
IO.println("Something went wrong!");
throw new RuntimeException(e);
}或将响应内容传输到任何 OutputStream:
import com.anthropic.core.http.HttpResponse;
try (HttpResponse response = client.beta().files().download(params)) {
response.body().transferTo(Files.newOutputStream(Paths.get(path)));
} catch (Exception e) {
IO.println("Something went wrong!");
throw new RuntimeException(e);
}SDK 抛出自定义的非检查异常类型:
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());
}使用原始响应时,您可以使用 requestId() 方法访问 request-id 响应标头:
import com.anthropic.core.http.HttpResponseFor;
import com.anthropic.models.messages.Message;
HttpResponseFor<Message> message = client.messages().withRawResponse().create(params);
Optional<String> requestId = message.requestId();这可用于快速记录失败的请求并将其报告给 Anthropic。有关调试请求的更多信息,请参阅请求 ID。
SDK 默认自动重试 2 次,请求之间采用短暂的指数退避。
仅重试以下错误类型:
API 也可能明确指示 SDK 重试或不重试某个请求。
要设置自定义重试次数,请使用 maxRetries 方法配置客户端:
import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;
AnthropicClient client = AnthropicOkHttpClient.builder().fromEnv().maxRetries(4).build();请求默认在 10 分钟后超时。
但是,对于接受 maxTokens 的方法,如果您指定了较大的 maxTokens 值并且正在使用流式传输,则默认超时将使用以下公式动态计算:
Duration.ofSeconds(
Math.min(
60 * 60, // 1 hour max
Math.max(
10 * 60, // 10 minute minimum
60 * 60 * maxTokens / 128_000
)
)
)这会产生最长 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_4_8)
.build();
// 使用 toBuilder() 创建修改后的副本
MessageCreateParams modified = params.toBuilder().maxTokens(2048L).build();由于每个类都是不可变的,构建器的修改永远不会影响已构建的类实例。
要向 Claude API 发送请求,请构建某个 Params 类的实例并将其传递给相应的客户端方法。收到响应后,它会被反序列化为 Java 类的实例。
例如,应使用 MessageCreateParams 的实例调用 client.messages().create(...),它将返回 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_4_8)
.build();创建 JsonValue 最直接的方法是使用其 from(...) 方法:
import com.anthropic.core.JsonValue;
// 创建基本 JSON 值
JsonValue nullValue = JsonValue.from(null);
JsonValue booleanValue = JsonValue.from(true);
JsonValue numberValue = JsonValue.from(42);
JsonValue stringValue = JsonValue.from("Hello World!");
// 创建一个等价于 `["Hello", "World"]` 的 JSON 数组值
JsonValue arrayValue = JsonValue.from(List.of("Hello", "World"));
// 创建一个等价于 `{ "a": 1, "b": 2 }` 的 JSON 对象值
JsonValue objectValue = JsonValue.from(Map.of("a", 1, "b", 2));
// 创建一个任意嵌套的 JSON,等价于:
// { "a": [1, 2], "b": [3, 4] }
JsonValue complexValue = JsonValue.from(Map.of("a", List.of(1, 2), "b", List.of(3, 4)));通常,如果任何必需的参数或属性未设置,Builder 类的 build 方法将抛出 IllegalStateException。要强制省略必需的参数或属性,请传递 JsonMissing:
import com.anthropic.core.JsonMissing;
import com.anthropic.models.messages.MessageCreateParams;
import com.anthropic.models.messages.Model;
MessageCreateParams params = MessageCreateParams.builder()
.addUserMessage("Hello, world")
.model(Model.CLAUDE_OPUS_4_8)
.maxTokens(JsonMissing.of())
.build();要访问未记录的响应属性,请调用 _additionalProperties() 方法:
import com.anthropic.core.JsonValue;
Map<String, JsonValue> additionalProperties = client
.messages()
.create(params)
._additionalProperties();
JsonValue secretPropertyValue = additionalProperties.get("secretProperty");
String result = secretPropertyValue.accept(new JsonValue.Visitor<>() {
@Override
public String visitNull() {
return "It's null!";
}
@Override
public String visitBoolean(boolean value) {
return "It's a boolean!";
}
@Override
public String visitNumber(Number value) {
return "It's a number!";
}
// 其他方法包括 `visitMissing`、`visitString`、`visitArray` 和 `visitObject`
// 每个未实现方法的默认实现都会委托给 `visitDefault`,
// 该方法默认会抛出异常,但也可以被重写
});要访问属性的原始 JSON 值,请调用其带 _ 前缀的方法:
import com.anthropic.core.JsonField;
import com.anthropic.models.messages.StopReason;
JsonField<StopReason> stopReason = client.messages().create(params)._stopReason();
if (stopReason.isMissing()) {
// 该属性在 JSON 响应中不存在
} else if (stopReason.isNull()) {
// 该属性被设置为字面量 null
} else {
// 检查值是否以字符串形式提供
// 其他方法包括 `asNumber()`、`asBoolean()` 等
Optional<String> jsonString = stopReason.asString();
// 尝试反序列化为自定义类型
MyClass myObject = stopReason.asUnknown().orElseThrow().convert(MyClass.class);
}默认情况下,当 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();import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;
import java.net.Proxy;
AnthropicClient client = AnthropicOkHttpClient.builder()
.fromEnv()
.proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("https://example.com", 8080)))
.build();大多数应用程序不应调用这些方法,而应使用系统默认值。默认值包含特殊优化,如果修改实现可能会丢失这些优化。
import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;
AnthropicClient client = AnthropicOkHttpClient.builder()
.fromEnv()
.sslSocketFactory(yourSSLSocketFactory)
.trustManager(yourTrustManager)
.hostnameVerifier(yourHostnameVerifier)
.build();SDK 由三个构件组成:
anthropic-java-core - 包含核心 SDK 逻辑,不依赖 OkHttp。公开 AnthropicClient、AnthropicClientAsync 及其实现类,所有这些都可以与任何 HTTP 客户端配合使用。anthropic-java-client-okhttp - 依赖 OkHttp。公开 AnthropicOkHttpClient 和 AnthropicOkHttpClientAsync。anthropic-java - 依赖并公开 anthropic-java-core 和 anthropic-java-client-okhttp 的 API。没有自己的逻辑。这种结构允许替换 SDK 的默认 HTTP 客户端,而无需引入不必要的依赖项。
在替换默认客户端之前,请先尝试可用的网络选项。
要使用自定义的 OkHttpClient:
anthropic-java 依赖项替换为 anthropic-java-core。anthropic-java-client-okhttp 的 OkHttpClient 类复制到您的代码中并进行自定义。AnthropicClientImpl 或 AnthropicClientAsyncImpl。要使用完全自定义的 HTTP 客户端:
anthropic-java 依赖项替换为 anthropic-java-core。HttpClient 接口的类。AnthropicClientImpl 或 AnthropicClientAsyncImpl。有关包含代码示例的详细平台设置指南,请参阅:
Java SDK 通过提供平台特定 Backend 实现的独立依赖项支持以下平台:
com.anthropic:anthropic-java-bedrock:对于 Messages-API Bedrock 端点,使用 BedrockMantleBackend.fromEnv() 或 BedrockMantleBackend.builder();或使用 BedrockBackend.fromEnv() / BedrockBackend.builder()(bedrock-runtime 路径)。com.anthropic:anthropic-java-vertex:使用 VertexBackend.fromEnv() 或 VertexBackend.builder()。com.anthropic:anthropic-java-foundry:使用 FoundryBackend.fromEnv() 或 FoundryBackend.builder()。com.anthropic:anthropic-java-aws:使用 AwsBackend.fromEnv()(读取 ANTHROPIC_AWS_WORKSPACE_ID 以及 AWS 默认区域/凭证链)或 AwsBackend.builder()。目前处于测试阶段。新项目请使用 BedrockMantleBackend;BedrockBackend 保留用于使用 Bedrock InvokeModel API 的现有应用程序。
每个 Backend 实现都通过 AnthropicOkHttpClient.builder() 上的 .backend() 传递给客户端。每个云后端都会将其各自的云平台 SDK 类作为传递依赖项引入。
要访问 HTTP 标头、状态码和原始响应体,请在任何 HTTP 方法调用前加上 withRawResponse():
import com.anthropic.core.http.Headers;
import com.anthropic.core.http.HttpResponseFor;
import com.anthropic.models.messages.Message;
import com.anthropic.models.messages.MessageCreateParams;
import com.anthropic.models.messages.Model;
MessageCreateParams params = MessageCreateParams.builder()
.maxTokens(1024L)
.addUserMessage("Hello, Claude")
.model(Model.CLAUDE_OPUS_4_8)
.build();
HttpResponseFor<Message> message = client.messages().withRawResponse().create(params);
int statusCode = message.statusCode();
Headers headers = message.headers();如果需要,您仍然可以将响应反序列化为 Java 类的实例:
import com.anthropic.models.messages.Message;
Message parsedMessage = message.parse();SDK 使用标准的 OkHttp 日志拦截器。
通过将 ANTHROPIC_LOG 环境变量设置为 info 来启用日志记录:
export ANTHROPIC_LOG=info或设置为 debug 以获得更详细的日志记录:
export ANTHROPIC_LOG=debugSDK 针对已记录的 API 进行了类型化,以便于使用。但是,它也支持使用 API 中未记录或尚不支持的部分。
要设置未记录的请求参数,请使用未记录的参数中描述的 putAdditionalHeader、putAdditionalQueryParam 或 putAdditionalBodyProperty 方法。
要访问未记录的响应属性,请使用响应属性中描述的 _additionalProperties() 方法。
SDK 中类似枚举的类(例如 Model 和 AnthropicBeta)不是封闭的 Java enum 类型。每个类都提供一个接受任意字符串的 of(String) 工厂方法,因此您可以使用尚未添加到 SDK 中的值,例如在您的 SDK 版本之后发布的模型或测试版标头:
import com.anthropic.models.beta.AnthropicBeta;
import com.anthropic.models.messages.Model;
Model model = Model.of("some-new-model");
AnthropicBeta beta = AnthropicBeta.of("some-new-beta-2026-01-01");接受这些类型的构建器方法通常也提供 String 重载,该重载会为您调用 of(...):
import com.anthropic.models.messages.MessageCreateParams;
MessageCreateParams params = MessageCreateParams.builder()
.model("some-new-model") // same as .model(Model.of("some-new-model"))
.maxTokens(1024L)
.addUserMessage("Hello, Claude")
.build();优先使用类型明确的常量(例如 Model.CLAUDE_OPUS_4_7),以便获得自动补全和弃用警告。String 重载和 of(...) 主要用于在等待包含该值的 SDK 版本发布期间,将字段设置为未记录或尚不支持的值。
测试版功能在正式发布之前提供,以便获得早期反馈并测试新功能。您可以在使用 Claude 构建概述中查看 Claude 所有功能和工具的可用性。
您可以通过客户端上的 beta() 方法访问大多数测试版 API 功能。要启用特定的测试版功能,请在构建消息参数时使用 .addBeta() 添加相应的测试版标头。
例如,要使用 Files API:
import com.anthropic.models.beta.AnthropicBeta;
import com.anthropic.models.beta.messages.BetaContentBlockParam;
import com.anthropic.models.beta.messages.BetaMessage;
import com.anthropic.models.beta.messages.BetaRequestDocumentBlock;
import com.anthropic.models.beta.messages.BetaTextBlockParam;
import com.anthropic.models.beta.messages.MessageCreateParams;
void main() {
AnthropicClient client = AnthropicOkHttpClient.fromEnv();
BetaMessage message = client.beta().messages().create(
MessageCreateParams.builder()
.model(Model.CLAUDE_OPUS_4_8)
.maxTokens(1024L)
.addBeta(AnthropicBeta.FILES_API_2025_04_14)
.addUserMessageOfBetaContentBlockParams(List.of(
BetaContentBlockParam.ofText(
BetaTextBlockParam.builder()
.text("Please summarize this document for me.")
.build()),
BetaContentBlockParam.ofDocument(
BetaRequestDocumentBlock.builder()
.fileSource("file_abc123")
.build())))
.build());
}此包通常遵循 SemVer 约定,但某些向后不兼容的更改可能会作为次要版本发布:
Was this page helpful?