How to handle tool calls from Claude in python
anthropic Python SDK to send messages to Claude models and parse tool call instructions from the response content. Implement logic to detect and execute tool calls based on the model's output, then feed results back into subsequent client.messages.create calls for a seamless tool integration.model_behavior Why this happens
Claude models can generate responses that include instructions to call external tools or APIs. However, the anthropic SDK itself does not automatically execute these tool calls. If your code only sends messages and prints responses without parsing or handling tool call instructions, the tool calls won't be executed, causing incomplete or stalled workflows.
Example of broken code that ignores tool calls:
import anthropic
import os
client = anthropic.Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=500,
system="You are a helpful assistant.",
messages=[{"role": "user", "content": "Call the weather API for New York."}]
)
print(response.content[0].text) Assistant: To get the weather for New York, you can call the weather API at https://api.weather.com/... (But no actual API call is made.)
The fix
Detect tool call instructions in the model's response, then implement Python code to execute those calls. After obtaining the tool's output, send it back to Claude in a follow-up message to continue the conversation. This approach enables dynamic tool integration.
Example with a simple tool call handler:
import anthropic
import os
import requests
client = anthropic.Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])
# Step 1: Ask Claude for a tool call
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=500,
system="You are a helpful assistant.",
messages=[{"role": "user", "content": "Get the current weather in New York City."}]
)
text = response.content[0].text
print("Claude response:", text)
# Step 2: Parse tool call instruction (simplified example)
if "weather API" in text.lower():
# Call a mock weather API
weather_response = requests.get("https://api.mockweather.com/current?city=New+York")
weather_data = weather_response.json().get("weather", "No data")
# Step 3: Send tool output back to Claude
followup = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=500,
system="You are a helpful assistant.",
messages=[
{"role": "user", "content": "Get the current weather in New York City."},
{"role": "assistant", "content": text},
{"role": "user", "content": f"The weather API returned: {weather_data}. What should I do next?"}
]
)
print("Follow-up response:", followup.content[0].text) Claude response: To get the current weather in New York City, I will call the weather API. Follow-up response: The current weather in New York City is sunny with 72°F. Would you like me to provide a forecast or other details?
Preventing it in production
Implement robust parsing of tool call instructions using structured formats like JSON or special delimiters to reliably detect tool calls. Use exponential backoff retry logic around API calls to handle transient errors. Validate tool outputs before sending them back to Claude to avoid cascading errors. Consider fallback responses if tool calls fail.
import time
import requests
MAX_RETRIES = 3
for attempt in range(MAX_RETRIES):
try:
weather_response = requests.get("https://api.mockweather.com/current?city=New+York")
weather_response.raise_for_status()
weather_data = weather_response.json().get("weather", "No data")
break
except requests.RequestException as e:
if attempt < MAX_RETRIES - 1:
time.sleep(2 ** attempt) # exponential backoff
else:
weather_data = "Weather service unavailable."
# Proceed with sending weather_data back to Claude Key Takeaways
- Parse Claude's response to detect tool call instructions explicitly in your Python code.
- Execute external tool calls separately and feed results back to Claude for continued interaction.
- Use retries with exponential backoff to handle transient API errors during tool calls.