How to implement tool calling on Claude
Tool calling on Claude allows the AI to interact with external functions and APIs to perform specific tasks. You implement it by defining tool schemas in your API requests and handling the tool use responses from Claude.
Prerequisites
- Basic understanding of API integration
- Python or JavaScript programming knowledge
- Claude API access key
- Familiarity with JSON data structures
Step-by-Step Instructions
Set up Claude API client
pip install anthropic. Initialize the client with your API key:import anthropic
client = anthropic.Anthropic(
api_key="your-api-key-here"
)Alternatively, set your API key as an environment variable
ANTHROPIC_API_KEY.Define your tool functions
def get_weather(location: str) -> dict:
# Your weather API logic here
return {
"location": location,
"temperature": "22°C",
"condition": "sunny"
}
def calculate_sum(a: float, b: float) -> float:
return a + bCreate tool schemas
tools = [
{
"name": "get_weather",
"description": "Get current weather for a location",
"input_schema": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "City name or location"
}
},
"required": ["location"]
}
}
]Send message with tools
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1024,
tools=tools,
messages=[
{
"role": "user",
"content": "What's the weather like in Paris?"
}
]
)Claude will analyze your message and determine if any tools should be used.
Handle tool use responses
if response.content[0].type == "tool_use":
tool_use = response.content[0]
tool_name = tool_use.name
tool_input = tool_use.input
tool_use_id = tool_use.id
# Execute the corresponding function
if tool_name == "get_weather":
result = get_weather(**tool_input)
print(f"Tool {tool_name} called with: {tool_input}")
print(f"Result: {result}")Send tool results back to Claude
follow_up = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1024,
messages=[
{"role": "user", "content": "What's the weather like in Paris?"},
{"role": "assistant", "content": response.content},
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": tool_use_id,
"content": str(result)
}
]
}
],
tools=tools
)Implement conversation loop
def chat_with_tools(user_message):
messages = [{"role": "user", "content": user_message}]
while True:
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1024,
tools=tools,
messages=messages
)
if response.content[0].type == "text":
return response.content[0].text
# Handle tool use and continue loop
# ... tool execution logic ...Add error handling and logging
import logging
try:
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1024,
tools=tools,
messages=messages
)
except anthropic.APIError as e:
logging.error(f"Claude API error: {e}")
return "Sorry, I encountered an error."
except Exception as e:
logging.error(f"Tool execution error: {e}")
return "Tool execution failed."Common Issues & Troubleshooting
Claude doesn't call the tool when expected
Check your tool description and input schema. Make sure the description clearly explains when to use the tool and that parameter types match exactly. Also verify your user message provides enough context for Claude to understand a tool is needed.
Getting 'tool_use_id not found' errors
Ensure you're passing the exact tool_use_id from Claude's response back in your tool result. The ID must match character-for-character, and you must include it in the same conversation thread.
Tool parameters are incorrect or missing
Validate your JSON schema in the input_schema field. Make sure all required parameters are marked in the required array and parameter types are correctly specified as string, number, boolean, etc.
API rate limiting or timeout errors
Implement exponential backoff retry logic and respect rate limits. Add timeout handling to your tool functions and consider caching results for expensive operations. Use time.sleep() between requests if hitting rate limits.