Claude Tool Use Tutorial
Claude Tool Use and Function Calling Tutorial
Tool use (also called function calling) lets Claude interact with external systems by calling functions you define. Instead of just generating text, Claude can decide to call a calculator, search a database, fetch weather data, or perform any action you expose as a tool. This tutorial covers implementation from basics to advanced patterns.
How Tool Use Works
The tool use flow follows three steps:
- Define tools — You describe available functions with names, descriptions, and parameter schemas in your API request.
- Claude decides — Based on the conversation, Claude decides whether and which tool to call, providing structured arguments.
- Return results — You execute the function, then send the result back to Claude in a follow-up message so it can formulate its final response.
Basic Python Example
import anthropic
import json
client = anthropic.Anthropic()
# Define a tool
tools = [
{
"name": "get_weather",
"description": "Get the current weather for a given city. Use this when the user asks about weather conditions.",
"input_schema": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "The city name, e.g. 'San Francisco'"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "Temperature unit"
}
},
"required": ["city"]
}
}
]
# First API call — Claude decides to use the tool
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
tools=tools,
messages=[{"role": "user", "content": "What's the weather in Tokyo?"}]
)
# Check if Claude wants to use a tool
if response.stop_reason == "tool_use":
tool_block = next(b for b in response.content if b.type == "tool_use")
print(f"Claude wants to call: {tool_block.name}")
print(f"With arguments: {json.dumps(tool_block.input, indent=2)}")
# Execute your function (simulated here)
weather_result = {"temperature": 22, "condition": "Partly cloudy", "unit": "celsius"}
# Second API call — send the tool result back
final_response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
tools=tools,
messages=[
{"role": "user", "content": "What's the weather in Tokyo?"},
{"role": "assistant", "content": response.content},
{
"role": "user",
"content": [{
"type": "tool_result",
"tool_use_id": tool_block.id,
"content": json.dumps(weather_result)
}]
}
]
)
print(final_response.content[0].text)
Node.js Example
import Anthropic from '@anthropic-ai/sdk';
const client = new Anthropic();
const tools = [
{
name: 'search_database',
description: 'Search the product database by query string',
input_schema: {
type: 'object',
properties: {
query: { type: 'string', description: 'Search query' },
limit: { type: 'number', description: 'Max results to return' },
},
required: ['query'],
},
},
];
async function runWithTools() {
const response = await client.messages.create({
model: 'claude-sonnet-4-20250514',
max_tokens: 1024,
tools,
messages: [{ role: 'user', content: 'Find laptops under $1000' }],
});
if (response.stop_reason === 'tool_use') {
const toolUse = response.content.find((b) => b.type === 'tool_use');
console.log(`Calling ${toolUse.name} with:`, toolUse.input);
// Execute your function and return results
const results = [
{ name: 'ThinkPad T14', price: 899 },
{ name: 'MacBook Air M3', price: 999 },
];
const finalResponse = await client.messages.create({
model: 'claude-sonnet-4-20250514',
max_tokens: 1024,
tools,
messages: [
{ role: 'user', content: 'Find laptops under $1000' },
{ role: 'assistant', content: response.content },
{
role: 'user',
content: [
{
type: 'tool_result',
tool_use_id: toolUse.id,
content: JSON.stringify(results),
},
],
},
],
});
console.log(finalResponse.content[0].text);
}
}
runWithTools();
Multiple Tools in One Request
You can define multiple tools and Claude will choose the most appropriate one. Claude can even call multiple tools in a single response when needed:
tools = [
{"name": "get_weather", "description": "Get weather for a city", ...},
{"name": "search_flights", "description": "Search for flights between cities", ...},
{"name": "book_hotel", "description": "Book a hotel in a city", ...},
]
# Claude will call the appropriate tool based on the user's request
Agentic Tool Use Loop
For complex tasks, implement an agentic loop where Claude can call tools multiple times:
def run_agent(user_message):
messages = [{"role": "user", "content": user_message}]
while True:
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=4096,
tools=tools,
messages=messages
)
# If Claude is done (no more tool calls), return
if response.stop_reason == "end_turn":
return response.content[0].text
# Process tool calls
messages.append({"role": "assistant", "content": response.content})
tool_results = []
for block in response.content:
if block.type == "tool_use":
result = execute_tool(block.name, block.input)
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": json.dumps(result)
})
messages.append({"role": "user", "content": tool_results})
Best Practices
- Use descriptive names — Tool names like
search_productsare better thanquery. - Validate inputs — Always validate tool arguments before executing functions.
- Handle errors gracefully — Return error messages as tool results so Claude can inform the user.
- Use enums for constrained values — Enums in the schema prevent invalid inputs.
- Keep tools focused — Each tool should do one thing well rather than being a multi-purpose function.
Tool use through a relay service like claude4u.com works identically to the direct API. Simply set your ANTHROPIC_BASE_URL and the relay transparently handles the tool use request-response cycle.
Get Started with 轻舟 AI
Stable, fast AI API relay — supports Claude, OpenAI, Gemini and more
Sign Up Free
轻舟 AI