tool_use
ToolsDefinition
A content block type in Claude's response indicating the model wants to call a specific tool. Contains 'id', 'name', and 'input' fields. The agent must execute the tool and return results in a tool_result content block for the conversation to continue.
Example Usage
When response.content[0].type == 'tool_use', extract the tool name and inputs, execute the function, and return results.
Why It Matters for the CCA-F Exam
The CCA-F exam tests whether you know the exact fields of a `tool_use` block (`id`, `name`, `input`) and that `stop_reason: "tool_use"` is what signals a pending call. Questions frequently probe the ID-matching requirement between `tool_use` and `tool_result`, and whether you handle multiple `tool_use` blocks in a single response correctly.
In Depth
A tool_use content block is Claude's mechanism for requesting an external function call mid-conversation. When Claude determines it needs to invoke a tool, its response will contain one or more content blocks of type: "tool_use". Each block carries three required fields:
id— a unique identifier (e.g.,"toolu_01XmpZ…") that you must echo back in the correspondingtool_result.name— the exact name of the tool Claude has chosen to invoke.input— a JSON object conforming to the tool's declared input schema.
The conversation only moves forward once you return the result. Practically, this means your agent loop must check response.stop_reason === "tool_use", iterate over response.content to find every block where block.type === "tool_use", execute each call, then append a new user message whose content array holds a tool_result block for every requested tool.
A critical accuracy point: always parse input as a JSON object. Never string-match against the serialized form. Claude constructs valid JSON per your schema, and your code should deserialize it accordingly.
Another common mistake is mismatching IDs. The tool_use_id in the tool_result must equal the id from the tool_use block — even in parallel tool use scenarios where multiple blocks arrive simultaneously. ID mismatches cause the API to return a validation error.
The agentic loop continues until Claude emits a stop_reason of end_turn (or another terminal reason like max_tokens). tool_use stop_reason signals that Claude has more work to do and is waiting on your execution layer.
Beyond simple scalar results, tool_result content can include images and structured data. This makes tool_use versatile for tasks ranging from database queries to screenshot capture. See the Tool Use Flow & Mechanics concept guide for the full lifecycle diagram.
Example
Minimal agentic loop: handle tool_use stop_reason, collect every tool_use block, and return all results in one user message.
// Minimal agentic loop handling tool_use
async function runLoop(client, messages, tools) {
while (true) {
const response = await client.messages.create({
model: "claude-opus-4-8",
max_tokens: 4096,
tools,
messages,
});
if (response.stop_reason === "end_turn") {
return response;
}
if (response.stop_reason === "tool_use") {
// Append assistant turn
messages.push({ role: "assistant", content: response.content });
// Collect all tool_use blocks and execute them
const toolResults = [];
for (const block of response.content) {
if (block.type === "tool_use") {
// Always parse input as JSON object — never string-match
const result = await executeTool(block.name, block.input);
toolResults.push({
type: "tool_result",
tool_use_id: block.id, // Must match exactly
content: result,
});
}
}
// Return ALL results in one user message
messages.push({ role: "user", content: toolResults });
}
}
}Frequently Asked Questions
What happens if I return tool results in separate messages instead of one?
The API requires all `tool_result` blocks for a given assistant turn to be returned together in a single user message. Splitting them across multiple user messages violates the conversation structure and will result in an API validation error.
Can `input` ever be a string rather than an object?
No. The `input` field is always a JSON object whose structure matches the tool's declared `input_schema`. If your schema defines an object with properties, `input` will be that object. You should always deserialize and access properties — never treat the value as a raw string to be parsed or matched against.
Does `stop_reason: "tool_use"` mean Claude is done thinking?
Not necessarily. It means Claude has decided it needs external information or action before it can continue. After you return the `tool_result`, Claude will resume reasoning and may issue more tool calls, produce text, or complete with `end_turn`. The loop continues until a terminal stop_reason is reached.