mirror of
https://github.com/Piebald-AI/claude-code-system-prompts.git
synced 2026-06-19 11:30:17 +08:00
234 lines
9.5 KiB
Markdown
234 lines
9.5 KiB
Markdown
<!--
|
|
name: 'Data: Tool use reference — Java'
|
|
description: Java tool use reference including defining tools and the manual agentic loop
|
|
ccVersion: 2.1.182
|
|
-->
|
|
# Tool Use — Java
|
|
|
|
For conceptual overview (tool definitions, tool choice, tips), see [shared/tool-use-concepts.md](../../shared/tool-use-concepts.md).
|
|
|
|
## 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();
|
|
```
|
|
|
|
---
|
|
|
|
## 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())`.
|
|
|
|
---
|
|
|
|
## Anthropic-Defined Tools
|
|
|
|
Version-suffixed types; `name`/`type` auto-set by builder. Direct `.addTool()` overloads exist for most tool types; where one is missing (newer or less-common tools — see the advisor note below), wrap via the union type's static factory: `.addTool(BetaToolUnion.of<ToolName>(builder…build()))`. Web search and code execution are server-executed; bash and text editor are client-executed (you handle the `tool_use` locally — see `shared/tool-use-concepts.md`).
|
|
|
|
```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`. For the advisor tool, use `BetaAdvisorTool20260301` in the beta namespace with `.addBeta("advisor-tool-2026-03-01")` (server-side; advisor model ≥ executor model). There is no direct `.addTool(BetaAdvisorTool20260301)` overload on the beta builder — wrap it via the `BetaToolUnion` static factory for the advisor type; if `javac` rejects the specific factory method name, `javap com.anthropic.models.beta.messages.BetaToolUnion | grep -i advisor` shows the exact one.
|
|
|
|
### 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_8)
|
|
.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());
|
|
});
|
|
});
|
|
}
|
|
```
|
|
|
|
---
|
|
|