mirror of
https://github.com/Piebald-AI/claude-code-system-prompts.git
synced 2026-05-30 21:54:18 +08:00
436 lines
15 KiB
Markdown
436 lines
15 KiB
Markdown
<!--
|
|
name: 'Data: Claude API reference — Java'
|
|
description: Java SDK reference including installation, client initialization, basic requests, streaming, and beta tool use
|
|
ccVersion: 2.1.78
|
|
-->
|
|
# Claude API — Java
|
|
|
|
> **Note:** The Java SDK supports the Claude API and beta tool use with annotated classes. Agent SDK is not yet available for Java.
|
|
|
|
## Installation
|
|
|
|
Maven:
|
|
|
|
\`\`\`xml
|
|
<dependency>
|
|
<groupId>com.anthropic</groupId>
|
|
<artifactId>anthropic-java</artifactId>
|
|
<version>2.16.1</version>
|
|
</dependency>
|
|
\`\`\`
|
|
|
|
Gradle:
|
|
|
|
\`\`\`groovy
|
|
implementation("com.anthropic:anthropic-java:2.16.1")
|
|
\`\`\`
|
|
|
|
## Client Initialization
|
|
|
|
\`\`\`java
|
|
import com.anthropic.client.AnthropicClient;
|
|
import com.anthropic.client.okhttp.AnthropicOkHttpClient;
|
|
|
|
// Default (reads ANTHROPIC_API_KEY from environment)
|
|
AnthropicClient client = AnthropicOkHttpClient.fromEnv();
|
|
|
|
// Explicit API key
|
|
AnthropicClient client = AnthropicOkHttpClient.builder()
|
|
.apiKey("your-api-key")
|
|
.build();
|
|
\`\`\`
|
|
|
|
---
|
|
|
|
## Basic Message Request
|
|
|
|
\`\`\`java
|
|
import com.anthropic.models.messages.MessageCreateParams;
|
|
import com.anthropic.models.messages.Message;
|
|
import com.anthropic.models.messages.Model;
|
|
|
|
MessageCreateParams params = MessageCreateParams.builder()
|
|
.model(Model.CLAUDE_OPUS_4_6)
|
|
.maxTokens(16000L)
|
|
.addUserMessage("What is the capital of France?")
|
|
.build();
|
|
|
|
Message response = client.messages().create(params);
|
|
response.content().stream()
|
|
.flatMap(block -> block.text().stream())
|
|
.forEach(textBlock -> System.out.println(textBlock.text()));
|
|
\`\`\`
|
|
|
|
---
|
|
|
|
## Streaming
|
|
|
|
\`\`\`java
|
|
import com.anthropic.core.http.StreamResponse;
|
|
import com.anthropic.models.messages.RawMessageStreamEvent;
|
|
|
|
MessageCreateParams params = MessageCreateParams.builder()
|
|
.model(Model.CLAUDE_OPUS_4_6)
|
|
.maxTokens(64000L)
|
|
.addUserMessage("Write a haiku")
|
|
.build();
|
|
|
|
try (StreamResponse<RawMessageStreamEvent> streamResponse = client.messages().createStreaming(params)) {
|
|
streamResponse.stream()
|
|
.flatMap(event -> event.contentBlockDelta().stream())
|
|
.flatMap(deltaEvent -> deltaEvent.delta().text().stream())
|
|
.forEach(textDelta -> System.out.print(textDelta.text()));
|
|
}
|
|
\`\`\`
|
|
|
|
---
|
|
|
|
## Thinking
|
|
|
|
**Adaptive thinking is the recommended mode for Claude 4.6+ models.** Claude decides dynamically when and how much to think. The builder has a direct \`.thinking(ThinkingConfigAdaptive)\` overload — no manual union wrapping.
|
|
|
|
\`\`\`java
|
|
import com.anthropic.models.messages.ContentBlock;
|
|
import com.anthropic.models.messages.MessageCreateParams;
|
|
import com.anthropic.models.messages.Model;
|
|
import com.anthropic.models.messages.ThinkingConfigAdaptive;
|
|
|
|
MessageCreateParams params = MessageCreateParams.builder()
|
|
.model(Model.CLAUDE_SONNET_4_6)
|
|
.maxTokens(16000L)
|
|
.thinking(ThinkingConfigAdaptive.builder().build())
|
|
.addUserMessage("Solve this step by step: 27 * 453")
|
|
.build();
|
|
|
|
for (ContentBlock block : client.messages().create(params).content()) {
|
|
block.thinking().ifPresent(t -> System.out.println("[thinking] " + t.thinking()));
|
|
block.text().ifPresent(t -> System.out.println(t.text()));
|
|
}
|
|
\`\`\`
|
|
|
|
> **Deprecated:** \`ThinkingConfigEnabled.builder().budgetTokens(N)\` (and the \`.enabledThinking(N)\` shortcut) still works on Claude 4.6 but is deprecated. Use adaptive thinking above.
|
|
|
|
\`ContentBlock\` narrowing: \`.thinking()\` / \`.text()\` return \`Optional<T>\` — use \`.ifPresent(...)\` or \`.stream().flatMap(...)\`. Alternative: \`isThinking()\` / \`asThinking()\` boolean+unwrap pairs (throws on wrong variant).
|
|
|
|
---
|
|
|
|
## Tool Use (Beta)
|
|
|
|
The Java SDK supports beta tool use with annotated classes. Tool classes implement \`Supplier<String>\` for automatic execution via \`BetaToolRunner\`.
|
|
|
|
### Tool Runner (automatic loop)
|
|
|
|
\`\`\`java
|
|
import com.anthropic.models.beta.messages.MessageCreateParams;
|
|
import com.anthropic.models.beta.messages.BetaMessage;
|
|
import com.anthropic.helpers.BetaToolRunner;
|
|
import com.fasterxml.jackson.annotation.JsonClassDescription;
|
|
import com.fasterxml.jackson.annotation.JsonPropertyDescription;
|
|
import java.util.function.Supplier;
|
|
|
|
@JsonClassDescription("Get the weather in a given location")
|
|
static class GetWeather implements Supplier<String> {
|
|
@JsonPropertyDescription("The city and state, e.g. San Francisco, CA")
|
|
public String location;
|
|
|
|
@Override
|
|
public String get() {
|
|
return "The weather in " + location + " is sunny and 72°F";
|
|
}
|
|
}
|
|
|
|
BetaToolRunner toolRunner = client.beta().messages().toolRunner(
|
|
MessageCreateParams.builder()
|
|
.model("{{OPUS_ID}}")
|
|
.maxTokens(16000L)
|
|
.putAdditionalHeader("anthropic-beta", "structured-outputs-2025-11-13")
|
|
.addTool(GetWeather.class)
|
|
.addUserMessage("What's the weather in San Francisco?")
|
|
.build());
|
|
|
|
for (BetaMessage message : toolRunner) {
|
|
System.out.println(message);
|
|
}
|
|
\`\`\`
|
|
|
|
### Memory Tool
|
|
|
|
The Java SDK provides \`BetaMemoryToolHandler\` for implementing the memory tool backend. You supply a handler that manages file storage, and the \`BetaToolRunner\` handles memory tool calls automatically.
|
|
|
|
\`\`\`java
|
|
import com.anthropic.helpers.BetaMemoryToolHandler;
|
|
import com.anthropic.helpers.BetaToolRunner;
|
|
import com.anthropic.models.beta.messages.BetaMemoryTool20250818;
|
|
import com.anthropic.models.beta.messages.BetaMessage;
|
|
import com.anthropic.models.beta.messages.MessageCreateParams;
|
|
import com.anthropic.models.beta.messages.ToolRunnerCreateParams;
|
|
|
|
// Implement BetaMemoryToolHandler with your storage backend (e.g., filesystem)
|
|
BetaMemoryToolHandler memoryHandler = new FileSystemMemoryToolHandler(sandboxRoot);
|
|
|
|
MessageCreateParams createParams = MessageCreateParams.builder()
|
|
.model("{{OPUS_ID}}")
|
|
.maxTokens(4096L)
|
|
.addTool(BetaMemoryTool20250818.builder().build())
|
|
.addUserMessage("Remember that my favorite color is blue")
|
|
.build();
|
|
|
|
BetaToolRunner toolRunner = client.beta().messages().toolRunner(
|
|
ToolRunnerCreateParams.builder()
|
|
.betaMemoryToolHandler(memoryHandler)
|
|
.initialMessageParams(createParams)
|
|
.build());
|
|
|
|
for (BetaMessage message : toolRunner) {
|
|
System.out.println(message);
|
|
}
|
|
\`\`\`
|
|
|
|
See the [shared memory tool concepts](../shared/tool-use-concepts.md) for more details on the memory tool.
|
|
|
|
### Non-Beta Tool Declaration (manual JSON schema)
|
|
|
|
\`Tool.InputSchema.Properties\` is a freeform \`Map<String, JsonValue>\` wrapper — build property schemas via \`putAdditionalProperty\`. \`type: "object"\` is the default. The builder has a direct \`.addTool(Tool)\` overload that wraps in \`ToolUnion\` automatically.
|
|
|
|
\`\`\`java
|
|
import com.anthropic.core.JsonValue;
|
|
import com.anthropic.models.messages.Tool;
|
|
|
|
Tool tool = Tool.builder()
|
|
.name("get_weather")
|
|
.description("Get the current weather in a given location")
|
|
.inputSchema(Tool.InputSchema.builder()
|
|
.properties(Tool.InputSchema.Properties.builder()
|
|
.putAdditionalProperty("location", JsonValue.from(Map.of("type", "string")))
|
|
.build())
|
|
.required(List.of("location"))
|
|
.build())
|
|
.build();
|
|
|
|
MessageCreateParams params = MessageCreateParams.builder()
|
|
.model(Model.CLAUDE_SONNET_4_6)
|
|
.maxTokens(16000L)
|
|
.addTool(tool)
|
|
.addUserMessage("Weather in Paris?")
|
|
.build();
|
|
\`\`\`
|
|
|
|
For manual tool loops, handle \`tool_use\` blocks in the response, send \`tool_result\` back, loop until \`stop_reason\` is \`"end_turn"\`. See [shared tool use concepts](../shared/tool-use-concepts.md).
|
|
|
|
### Building \`MessageParam\` with Content Blocks (Tool Result Round-Trip)
|
|
|
|
\`MessageParam.Content\` is an inner union class (string | list). Use the builder's \`.contentOfBlockParams(List<ContentBlockParam>)\` alias — there is NO separate \`MessageParamContent\` class with a static \`ofBlockParams\`:
|
|
|
|
\`\`\`java
|
|
import com.anthropic.models.messages.MessageParam;
|
|
import com.anthropic.models.messages.ContentBlockParam;
|
|
import com.anthropic.models.messages.ToolResultBlockParam;
|
|
|
|
List<ContentBlockParam> results = List.of(
|
|
ContentBlockParam.ofToolResult(ToolResultBlockParam.builder()
|
|
.toolUseId(toolUseBlock.id())
|
|
.content(yourResultString)
|
|
.build())
|
|
);
|
|
|
|
MessageParam toolResultMsg = MessageParam.builder()
|
|
.role(MessageParam.Role.USER)
|
|
.contentOfBlockParams(results) // builder alias for Content.ofBlockParams(...)
|
|
.build();
|
|
\`\`\`
|
|
|
|
---
|
|
|
|
## Effort Parameter
|
|
|
|
Effort is nested inside \`OutputConfig\` — there is NO \`.effort()\` directly on \`MessageCreateParams.Builder\`.
|
|
|
|
\`\`\`java
|
|
import com.anthropic.models.messages.OutputConfig;
|
|
|
|
.outputConfig(OutputConfig.builder()
|
|
.effort(OutputConfig.Effort.HIGH) // or LOW, MEDIUM, MAX
|
|
.build())
|
|
\`\`\`
|
|
|
|
Combine with \`Thinking = ThinkingConfigAdaptive\` for cost-quality control.
|
|
|
|
---
|
|
|
|
## Prompt Caching
|
|
|
|
System message as a list of \`TextBlockParam\` with \`CacheControlEphemeral\`. Use \`.systemOfTextBlockParams(...)\` — the plain \`.system(String)\` overload can't carry cache control.
|
|
|
|
\`\`\`java
|
|
import com.anthropic.models.messages.TextBlockParam;
|
|
import com.anthropic.models.messages.CacheControlEphemeral;
|
|
|
|
.systemOfTextBlockParams(List.of(
|
|
TextBlockParam.builder()
|
|
.text(longSystemPrompt)
|
|
.cacheControl(CacheControlEphemeral.builder()
|
|
.ttl(CacheControlEphemeral.Ttl.TTL_1H) // optional; also TTL_5M
|
|
.build())
|
|
.build()))
|
|
\`\`\`
|
|
|
|
There's also a top-level \`.cacheControl(CacheControlEphemeral)\` on \`MessageCreateParams.Builder\` and on \`Tool.builder()\`.
|
|
|
|
---
|
|
|
|
## Token Counting
|
|
|
|
\`\`\`java
|
|
import com.anthropic.models.messages.MessageCountTokensParams;
|
|
|
|
long tokens = client.messages().countTokens(
|
|
MessageCountTokensParams.builder()
|
|
.model(Model.CLAUDE_SONNET_4_6)
|
|
.addUserMessage("Hello")
|
|
.build()
|
|
).inputTokens();
|
|
\`\`\`
|
|
|
|
---
|
|
|
|
## Structured Output
|
|
|
|
The class-based overload auto-derives the JSON schema from your POJO and gives you a typed \`.text()\` return — no manual schema, no manual parsing.
|
|
|
|
\`\`\`java
|
|
import com.anthropic.models.messages.StructuredMessageCreateParams;
|
|
|
|
record Book(String title, String author) {}
|
|
record BookList(List<Book> books) {}
|
|
|
|
StructuredMessageCreateParams<BookList> params = MessageCreateParams.builder()
|
|
.model(Model.CLAUDE_SONNET_4_6)
|
|
.maxTokens(16000L)
|
|
.outputConfig(BookList.class) // returns a typed builder
|
|
.addUserMessage("List 3 classic novels")
|
|
.build();
|
|
|
|
client.messages().create(params).content().stream()
|
|
.flatMap(cb -> cb.text().stream())
|
|
.forEach(typed -> {
|
|
// typed.text() returns BookList, not String
|
|
for (Book b : typed.text().books()) System.out.println(b.title());
|
|
});
|
|
\`\`\`
|
|
|
|
Supports Jackson annotations: \`@JsonPropertyDescription\`, \`@JsonIgnore\`, \`@ArraySchema(minItems=...)\`. Manual schema path: \`OutputConfig.builder().format(JsonOutputFormat.builder().schema(...).build())\`.
|
|
|
|
---
|
|
|
|
## PDF / Document Input
|
|
|
|
\`DocumentBlockParam\` builder has source shortcuts. Wrap in \`ContentBlockParam.ofDocument()\` and pass via \`.addUserMessageOfBlockParams()\`.
|
|
|
|
\`\`\`java
|
|
import com.anthropic.models.messages.DocumentBlockParam;
|
|
import com.anthropic.models.messages.ContentBlockParam;
|
|
import com.anthropic.models.messages.TextBlockParam;
|
|
|
|
DocumentBlockParam doc = DocumentBlockParam.builder()
|
|
.base64Source(base64String) // or .urlSource("https://...") or .textSource("...")
|
|
.title("My Document") // optional
|
|
.build();
|
|
|
|
.addUserMessageOfBlockParams(List.of(
|
|
ContentBlockParam.ofDocument(doc),
|
|
ContentBlockParam.ofText(TextBlockParam.builder().text("Summarize this").build())))
|
|
\`\`\`
|
|
|
|
---
|
|
|
|
## Server-Side Tools
|
|
|
|
Version-suffixed types; \`name\`/\`type\` auto-set by builder. Direct \`.addTool()\` overloads exist for every type — no manual \`ToolUnion\` wrapping.
|
|
|
|
\`\`\`java
|
|
import com.anthropic.models.messages.WebSearchTool20260209;
|
|
import com.anthropic.models.messages.ToolBash20250124;
|
|
import com.anthropic.models.messages.ToolTextEditor20250728;
|
|
import com.anthropic.models.messages.CodeExecutionTool20260120;
|
|
|
|
.addTool(WebSearchTool20260209.builder()
|
|
.maxUses(5L) // optional
|
|
.allowedDomains(List.of("example.com")) // optional
|
|
.build())
|
|
.addTool(ToolBash20250124.builder().build())
|
|
.addTool(ToolTextEditor20250728.builder().build())
|
|
.addTool(CodeExecutionTool20260120.builder().build())
|
|
\`\`\`
|
|
|
|
Also available: \`WebFetchTool20260209\`, \`MemoryTool20250818\`, \`ToolSearchToolBm25_20251119\`.
|
|
|
|
### Beta namespace (MCP, compaction)
|
|
|
|
For beta-only features use \`com.anthropic.models.beta.messages.*\` — class names have a \`Beta\` prefix AND live in the beta package. The beta \`MessageCreateParams.Builder\` has direct \`.addTool(BetaToolBash20250124)\` overloads AND \`.addMcpServer()\`:
|
|
|
|
\`\`\`java
|
|
import com.anthropic.models.beta.messages.MessageCreateParams;
|
|
import com.anthropic.models.beta.messages.BetaToolBash20250124;
|
|
import com.anthropic.models.beta.messages.BetaCodeExecutionTool20260120;
|
|
import com.anthropic.models.beta.messages.BetaRequestMcpServerUrlDefinition;
|
|
|
|
MessageCreateParams params = MessageCreateParams.builder()
|
|
.model(Model.CLAUDE_OPUS_4_6)
|
|
.maxTokens(16000L)
|
|
.addBeta("mcp-client-2025-11-20")
|
|
.addTool(BetaToolBash20250124.builder().build())
|
|
.addTool(BetaCodeExecutionTool20260120.builder().build())
|
|
.addMcpServer(BetaRequestMcpServerUrlDefinition.builder()
|
|
.name("my-server")
|
|
.url("https://example.com/mcp")
|
|
.build())
|
|
.addUserMessage("...")
|
|
.build();
|
|
|
|
client.beta().messages().create(params);
|
|
\`\`\`
|
|
|
|
\`BetaTool*\` types are NOT interchangeable with non-beta \`Tool*\` — pick one namespace per request.
|
|
|
|
**Reading server-tool blocks in the response:** \`ServerToolUseBlock\` has \`.id()\`, \`.name()\` (enum), and \`._input()\` returning raw \`JsonValue\` — there is NO typed \`.input()\`. For code execution results, unwrap two levels:
|
|
|
|
\`\`\`java
|
|
for (ContentBlock block : response.content()) {
|
|
block.serverToolUse().ifPresent(stu -> {
|
|
System.out.println("tool: " + stu.name() + " input: " + stu._input());
|
|
});
|
|
block.codeExecutionToolResult().ifPresent(r -> {
|
|
r.content().resultBlock().ifPresent(result -> {
|
|
System.out.println("stdout: " + result.stdout());
|
|
System.out.println("stderr: " + result.stderr());
|
|
System.out.println("exit: " + result.returnCode());
|
|
});
|
|
});
|
|
}
|
|
\`\`\`
|
|
|
|
---
|
|
|
|
## Files API (Beta)
|
|
|
|
Under \`client.beta().files()\`. File references in messages need the beta message types (non-beta \`DocumentBlockParam.Source\` has no file-ID variant).
|
|
|
|
\`\`\`java
|
|
import com.anthropic.models.beta.files.FileUploadParams;
|
|
import com.anthropic.models.beta.files.FileMetadata;
|
|
import com.anthropic.models.beta.messages.BetaRequestDocumentBlock;
|
|
import java.nio.file.Paths;
|
|
|
|
FileMetadata meta = client.beta().files().upload(
|
|
FileUploadParams.builder()
|
|
.file(Paths.get("/path/to/doc.pdf")) // or .file(InputStream) or .file(byte[])
|
|
.build());
|
|
|
|
// Reference in a beta message:
|
|
BetaRequestDocumentBlock doc = BetaRequestDocumentBlock.builder()
|
|
.fileSource(meta.id())
|
|
.build();
|
|
\`\`\`
|
|
|
|
Other methods: \`.list()\`, \`.delete(String fileId)\`, \`.download(String fileId)\`, \`.retrieveMetadata(String fileId)\`.
|