Implementation:Anthropics Anthropic sdk python ToolUseBlock Detection
| Knowledge Sources | |
|---|---|
| Domains | Tool_Use, LLM, Function_Calling |
| Last Updated | 2026-02-15 00:00 GMT |
Overview
The ToolUseBlock is a Pydantic model representing a tool invocation request within a Claude API response. Detection involves checking the Message.stop_reason field and filtering the Message.content array for blocks with type == "tool_use".
API: ToolUseBlock
class ToolUseBlock(BaseModel):
id: str
input: Dict[str, object]
name: str
type: Literal["tool_use"]
Source Location
File: src/anthropic/types/tool_use_block.py, lines 11-18
Import
from anthropic.types import ToolUseBlock
Fields
| Field | Type | Description |
|---|---|---|
id |
str |
Unique identifier for this tool call (e.g., "toolu_01A09q90qw90lq917835lq9"). Used to correlate with ToolResultBlockParam.tool_use_id.
|
input |
Dict[str, object] |
The arguments the model generated for the tool call, conforming to the tool's input_schema.
|
name |
str |
The name of the tool the model wants to invoke. Matches the name field from the tool definition.
|
type |
Literal["tool_use"] |
Discriminator field, always "tool_use". Used to distinguish from other content block types.
|
StopReason Type
The Message.stop_reason field uses the StopReason type alias, defined in src/anthropic/types/stop_reason.py:
StopReason: TypeAlias = Literal[
"end_turn", "max_tokens", "stop_sequence", "tool_use", "pause_turn", "refusal"
]
When stop_reason == "tool_use", the response contains at least one ToolUseBlock in its content array.
Detection Pattern
The standard pattern for detecting and extracting tool calls from a response:
import anthropic
from anthropic.types import ToolUseBlock
client = anthropic.Anthropic()
message = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
tools=[get_weather.to_dict()],
messages=[{"role": "user", "content": "What's the weather in London?"}]
)
# Step 1: Quick check via stop_reason
if message.stop_reason == "tool_use":
# Step 2: Filter content blocks
tool_use_blocks = [
block for block in message.content
if block.type == "tool_use"
]
# Step 3: Process each tool call
for block in tool_use_blocks:
print(f"Tool: {block.name}")
print(f"ID: {block.id}")
print(f"Input: {block.input}")
Type-Safe Detection with isinstance
For type-narrowing in strict type-checking environments, use isinstance:
from anthropic.types import ToolUseBlock, TextBlock
for block in message.content:
if isinstance(block, ToolUseBlock):
# block is narrowed to ToolUseBlock
result = dispatch_tool(block.name, block.input)
elif isinstance(block, TextBlock):
# block is narrowed to TextBlock
print(block.text)
Content Block Union
The message.content array can contain multiple block types. The full union (from src/anthropic/types/content_block.py) includes:
TextBlock--type: "text"ToolUseBlock--type: "tool_use"ThinkingBlock--type: "thinking"RedactedThinkingBlock--type: "redacted_thinking"
A single response can contain a mix of these types. For example, the model may emit a TextBlock with reasoning text followed by one or more ToolUseBlock entries.
Handling Multiple Tool Calls
When the model requests parallel tool use, the content array contains multiple ToolUseBlock entries:
# Example response content with parallel tool calls:
# message.content = [
# TextBlock(type="text", text="I'll check both for you."),
# ToolUseBlock(type="tool_use", id="toolu_abc", name="get_weather", input={"city": "London"}),
# ToolUseBlock(type="tool_use", id="toolu_def", name="get_weather", input={"city": "Paris"}),
# ]
tool_results = []
for block in message.content:
if block.type == "tool_use":
result = execute_tool(block.name, block.input)
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id, # Must match each block's unique ID
"content": str(result),
})
Complete Detection Loop Example
import anthropic
from anthropic import beta_tool
@beta_tool
def get_weather(city: str, unit: str = "celsius") -> str:
"""Get the current weather for a city.
Args:
city: The city name
unit: Temperature unit (celsius or fahrenheit)
"""
return f"The weather in {city} is 22 degrees {unit}"
client = anthropic.Anthropic()
messages = [{"role": "user", "content": "What's the weather in London?"}]
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
tools=[get_weather.to_dict()],
messages=messages,
)
while response.stop_reason == "tool_use":
tool_results = []
for block in response.content:
if block.type == "tool_use":
result = get_weather.call(block.input)
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": str(result),
})
messages.append({"role": "assistant", "content": response.content})
messages.append({"role": "user", "content": tool_results})
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
tools=[get_weather.to_dict()],
messages=messages,
)
# Final text response
for block in response.content:
if block.type == "text":
print(block.text)
Dependencies
- pydantic:
ToolUseBlockinherits fromBaseModel