codeflash-agent/.tessl/tiles/tessl/pypi-anthropic/docs/guides/tool-usage.md
codeflash-ci-bot[bot] c249bcd0ce
chore: update tessl tiles 2026-04-23 (#35)
Co-authored-by: codeflash-ci-bot[bot] <codeflash-ci-bot[bot]@users.noreply.github.com>
2026-04-23 08:15:44 -05:00

342 lines
7.6 KiB
Markdown

# Tool Usage Guide
Comprehensive guide to using tools (function calling) with Claude for building agentic workflows.
## Tool Basics
Tools let Claude call functions you define, enabling it to take actions and retrieve information.
### Manual Tool Definition
```python
message = client.messages.create(
model="claude-sonnet-4-5-20250929",
max_tokens=1024,
tools=[{
"name": "get_weather",
"description": "Get weather for a location",
"input_schema": {
"type": "object",
"properties": {
"location": {"type": "string", "description": "City and state"}
},
"required": ["location"]
}
}],
messages=[{"role": "user", "content": "What's the weather in SF?"}]
)
```
### Using Tool Decorators
```python
from anthropic import beta_tool
@beta_tool
def get_weather(location: str, unit: str = "fahrenheit") -> dict:
"""
Get weather for a location.
Args:
location: City and state, e.g. San Francisco, CA
unit: Temperature unit (celsius or fahrenheit)
"""
# Implementation
return {"temperature": 72, "condition": "sunny", "unit": unit}
message = client.beta.messages.create(
model="claude-sonnet-4-5-20250929",
max_tokens=1024,
tools=[get_weather],
messages=[{"role": "user", "content": "What's the weather in NYC?"}]
)
```
## Tool Execution Flow
### Manual Execution
```python
# 1. Send initial request
message = client.messages.create(
model="claude-sonnet-4-5-20250929",
max_tokens=1024,
tools=[...],
messages=[{"role": "user", "content": "What's the weather in Paris?"}]
)
# 2. Extract tool use
tool_use = next(block for block in message.content if block.type == "tool_use")
# 3. Execute function
result = get_weather(location=tool_use.input["location"])
# 4. Send result back
message = client.messages.create(
model="claude-sonnet-4-5-20250929",
max_tokens=1024,
tools=[...],
messages=[
{"role": "user", "content": "What's the weather in Paris?"},
{"role": "assistant", "content": message.content},
{
"role": "user",
"content": [{
"type": "tool_result",
"tool_use_id": tool_use.id,
"content": str(result)
}]
}
]
)
```
### Automatic Execution with Tool Runner
```python
@beta_tool
def get_weather(location: str) -> dict:
"""Get weather for location."""
return {"temp": 72, "condition": "sunny"}
@beta_tool
def get_time(timezone: str = "UTC") -> str:
"""Get current time in timezone."""
from datetime import datetime
return datetime.now().strftime("%H:%M")
for message in client.beta.messages.tool_runner(
model="claude-sonnet-4-5-20250929",
max_tokens=1024,
tools=[get_weather, get_time],
messages=[{"role": "user", "content": "What's the weather and time in SF?"}]
):
if message.stop_reason == "end_turn":
print(message.content[0].text)
```
## Tool Choice Control
### Auto (Default)
Let Claude decide whether to use tools:
```python
message = client.messages.create(
model="claude-sonnet-4-5-20250929",
max_tokens=1024,
tools=[...],
tool_choice={"type": "auto"},
messages=[...]
)
```
### Force Any Tool
Require Claude to use at least one tool:
```python
message = client.messages.create(
model="claude-sonnet-4-5-20250929",
max_tokens=1024,
tools=[...],
tool_choice={"type": "any"},
messages=[...]
)
```
### Force Specific Tool
Require Claude to use a specific tool:
```python
message = client.messages.create(
model="claude-sonnet-4-5-20250929",
max_tokens=1024,
tools=[...],
tool_choice={"type": "tool", "name": "get_weather"},
messages=[...]
)
```
### Disable All Tools
```python
message = client.messages.create(
model="claude-sonnet-4-5-20250929",
max_tokens=1024,
tools=[...],
tool_choice={"type": "none"},
messages=[...]
)
```
### Disable Parallel Tool Use
Force sequential tool calls:
```python
message = client.messages.create(
model="claude-sonnet-4-5-20250929",
max_tokens=1024,
tools=[...],
tool_choice={
"type": "auto",
"disable_parallel_tool_use": True
},
messages=[...]
)
```
## Advanced Patterns
### Stateful Tools
```python
class Calculator:
def __init__(self):
self.memory = 0
@beta_tool
def calculate(self, expression: str) -> float:
"""Evaluate mathematical expression."""
result = eval(expression)
self.memory = result
return result
@beta_tool
def recall(self) -> float:
"""Recall last calculation result."""
return self.memory
calc = Calculator()
for message in client.beta.messages.tool_runner(
model="claude-sonnet-4-5-20250929",
max_tokens=1024,
tools=[calc.calculate, calc.recall],
messages=[{"role": "user", "content": "Calculate 5*8, then add 10"}]
):
if message.stop_reason == "end_turn":
print(message.content[0].text)
```
### Error Handling in Tools
```python
@beta_tool
def divide(a: float, b: float) -> float:
"""Divide two numbers."""
if b == 0:
raise ValueError("Cannot divide by zero")
return a / b
# In tool result
try:
result = divide(10, 0)
tool_result = str(result)
is_error = False
except Exception as e:
tool_result = str(e)
is_error = True
message = client.messages.create(
model="claude-sonnet-4-5-20250929",
max_tokens=1024,
tools=[...],
messages=[
...,
{
"role": "user",
"content": [{
"type": "tool_result",
"tool_use_id": tool_use.id,
"content": tool_result,
"is_error": is_error
}]
}
]
)
```
### Async Tools
```python
from anthropic import beta_async_tool
@beta_async_tool
async def fetch_data(url: str) -> dict:
"""Fetch data from URL."""
async with httpx.AsyncClient() as client:
response = await client.get(url)
return response.json()
# Use with async tool runner
async for message in client.beta.messages.tool_runner(
model="claude-sonnet-4-5-20250929",
max_tokens=1024,
tools=[fetch_data],
messages=[...]
):
if message.stop_reason == "end_turn":
print(message.content[0].text)
```
## Best Practices
### 1. Clear Tool Descriptions
```python
@beta_tool
def search_database(
query: str,
limit: int = 10,
category: str | None = None
) -> list[dict]:
"""
Search database for items matching query.
Args:
query: Search keywords or phrase
limit: Maximum results to return (1-100)
category: Optional category filter (e.g., "electronics", "books")
Returns:
List of matching items with id, name, price
"""
...
```
### 2. Validate Tool Inputs
```python
@beta_tool
def set_temperature(degrees: float, unit: str = "celsius") -> dict:
"""Set thermostat temperature."""
if unit not in ["celsius", "fahrenheit"]:
raise ValueError(f"Invalid unit: {unit}")
if degrees < -50 or degrees > 50:
raise ValueError(f"Temperature out of range: {degrees}")
# Set temperature
return {"status": "success", "temperature": degrees, "unit": unit}
```
### 3. Return Structured Data
```python
@beta_tool
def get_user_info(user_id: str) -> dict:
"""Get user information."""
return {
"id": user_id,
"name": "Alice Smith",
"email": "alice@example.com",
"created_at": "2024-01-15"
}
```
## See Also
- [Tool Use API](../api/tools.md) - Complete API reference
- [Beta Features](../beta/index.md) - Tool runner and advanced features
- [Messages API](../api/messages.md) - Message creation