LLMs are incredibly smart, but they suffer from a major limitation: they are frozen in time. They don't know today's stock prices, they can't access your private database, and they can't execute calculations reliably.
To bridge this gap, we use Tool Use (also known as function calling).
By giving Claude access to external tools, we transform it from a passive text generator into an autonomous agent capable of fetching real-time data, executing code, and solving complex workflows step-by-step.
In this tutorial, we will build a fully autonomous financial agent in under 50 lines of clean Python code using the official Anthropic SDK and Claude 3.5 Sonnet.
The Agent Blueprint
An autonomous agent operates in a loop:
- Receive a user prompt.
- Decide if an external tool is needed to answer the prompt.
- Execute the tool locally if requested, and capture the output.
- Feed the tool results back to Claude.
- Repeat until Claude has enough information to deliver the final answer.
Let’s write the code to make this happen.
Step 1: Define the Tools and Client
First, we need to set up our Anthropic client and define the tools our agent can use. For this example, we'll create a mock tool that retrieves stock prices.
Make sure you have the SDK installed:
pip install anthropic
Here is the setup code:
import os
import json
import anthropic
# Initialize the client (Make sure ANTHROPIC_API_KEY is in your environment)
client = anthropic.Anthropic()
# Define the local Python function the agent can call
def get_stock_price(ticker: str) -> str:
mock_market = {"AAPL": "175.50", "MSFT": "420.20", "GOOG": "150.10"}
price = mock_market.get(ticker.upper(), "unknown")
return json.dumps({"ticker": ticker, "price": price})
# Define the schema Claude needs to understand how to use the tool
tools = [{
"name": "get_stock_price",
"description": "Get the current stock price for a given ticker symbol.",
"input_schema": {
"type": "object",
"properties": {
"ticker": {"type": "string", "description": "The stock ticker symbol, e.g. AAPL"}
},
"required": ["ticker"]
}
}]
Step 2: Build the Autonomous Loop
Now, let's write the core execution loop. This function will continuously handle Claude’s requests to run tools until Claude decides it has enough information to formulate a final response.
def run_agent(prompt: str):
messages = [{"role": "user", "content": prompt}]
print(f"User: {prompt}\n" + "="*40)
while True:
# Send current conversation context to Claude
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1024,
tools=tools,
messages=messages
)
# Append Claude's response to the conversation history
messages.append({"role": "assistant", "content": response.content})
# Check if Claude requested a tool call
tool_use = next((block for block in response.content if block.type == "tool_use"), None)
if not tool_use:
# No tool call requested; Claude has answered the prompt
final_text = next((b.text for b in response.content if b.type == "text"), "")
print(f"Agent: {final_text}")
break
# Execute the tool requested by Claude
print(f"[Tool Call] Running {tool_use.name} with arguments: {tool_use.input}")
if tool_use.name == "get_stock_price":
tool_result = get_stock_price(tool_use.input["ticker"])
else:
tool_result = "Error: Tool not found."
# Send the tool output back to Claude
messages.append({
"role": "user",
"content": [{
"type": "tool_result",
"tool_use_id": tool_id := tool_use.id,
"content": tool_result
}]
})
# Execute the agent
run_agent("I own 10 shares of AAPL and 5 shares of MSFT. What is my total portfolio value?")
How It Works Under the Hood
When you run this script, here is what happens step-by-step:
-
The Prompt: You ask Claude to calculate your portfolio value. Claude doesn't know the current prices of Apple or Microsoft, but it notices it has access to the
get_stock_pricetool. -
The Decision: Claude responds with a
tool_userequest forAAPL. -
The Execution: Our Python code intercepts this request, runs the local
get_stock_price("AAPL")function, and sends the output back to Claude. -
The Loop Continues: Claude realizes it still needs the price of
MSFT. It requests a second tool call. Our code executes it and sends the result back. - The Resolution: With both prices in hand, Claude performs the math autonomously and prints the final, accurate calculation.
Why Claude 3.5 Sonnet?
While other models support function calling, Claude 3.5 Sonnet is uniquely suited for autonomous agents because of its:
- High Tool Accuracy: It rarely hallucinates arguments or formats JSON incorrectly.
- Complex Multi-Step Reasoning: It handles nested logic and multiple sequential tool calls with ease.
- Speed: It processes context quickly, keeping the agent's response loop feeling snappy and real-time.
Practical Takeaways
- Always Validate Input: Never trust tool arguments blindly. If a tool writes to a database or runs a shell command, validate and sanitize the input first.
-
Handle Errors Gracefully: If your local function fails, send the error back to Claude as the
tool_result. Claude can often self-correct and try a different approach. - Set Iteration Limits: In production, use a counter to limit the maximum number of loops (e.g., max 5 tool calls) to prevent infinite loops and runaway API costs.
What Will You Build Next?
Now that you have a working agent template in under 50 lines of code, the possibilities are endless. You can swap out the stock price tool for a database query tool, a web scraper, or an API client for Slack or GitHub.
What tools are you going to build for your Claude agent? Let me know in the comments below!
Top comments (0)