Your First Tool-Calling Agent
Build a Simple Agent
Let's build a weather research agent. It will search for weather information and fetch weather websites.
Step 1: Define Your Tools
Your agent needs tools to call. Let's define two tools:
def search_weather(query):
"""Search for weather information.
Args:
query: What to search for. Example: "weather in San Francisco today"
Returns:
List of dicts with 'title' and 'snippet'
"""
# Imagine this calls a real API
return [
{"title": "Weather in SF", "snippet": "Sunny, 72F"},
{"title": "10 Day Forecast SF", "snippet": "Next 10 days..."},
]
def fetch_weather_page(url):
"""Fetch a weather page and get the full text.
Args:
url: The URL to fetch
Returns:
Dict with 'title' and 'text'
"""
# Imagine this calls a real API
return {
"title": "Weather in SF",
"text": "San Francisco weather: Sunny, 72 degrees, light wind..."
}
Step 2: Register Your Tools
Tell the agent which tools exist:
tools = {
"search_weather": search_weather,
"fetch_weather_page": fetch_weather_page,
}
tool_descriptions = {
"search_weather": "Search the web for weather information. Use this first to find relevant weather pages.",
"fetch_weather_page": "Fetch the full text of a weather website. Use this to get detailed weather data after you find a page.",
}
Step 3: Write the Agent Loop
def run_agent(user_question):
conversation = []
# System message tells the model what tools are available
system_message = f"""You are a weather research assistant.
You have these tools:
- search_weather: Search for weather information
- fetch_weather_page: Fetch the full text of a weather page
User question: {user_question}
Think step by step. First search for information, then fetch the best result.
"""
max_iterations = 5
for iteration in range(max_iterations):
# Think: Ask the model what to do
response = call_model(system_message, conversation)
print(f"Agent: {response}")
# Check if the model is done
if "<tool_use>" not in response:
# No tool call, model returned final answer
return response
# Act: Extract tool call from response
tool_call = parse_tool_call(response)
tool_name = tool_call["name"]
tool_args = tool_call["args"]
# Call the tool
if tool_name not in tools:
result = {"error": f"Unknown tool: {tool_name}"}
else:
result = tools[tool_name](**tool_args)
print(f"Tool result: {result}")
# Observe: Add to conversation
conversation.append({
"role": "assistant",
"content": response
})
conversation.append({
"role": "user",
"content": f"Tool {tool_name} returned: {result}"
})
return "Max iterations reached"
Step 4: Test It
result = run_agent("What is the weather in San Francisco right now?")
print(f"Final answer: {result}")
How the Agent Works
- User asks: "What is the weather in San Francisco?"
- Model sees the question and the available tools.
- Model decides: "I should search for weather in San Francisco."
- Agent calls: search_weather("San Francisco weather today")
- Agent gets results: [search result 1, search result 2]
- Model sees results and decides: "I found a result. Let me fetch it."
- Agent calls: fetch_weather_page("https://...")
- Agent gets: Full weather page text
- Model reads the page and returns a summary to the user.
Using Real APIs
To make this real, replace the dummy functions with actual API calls.
Using OpenAI API with web search:
from openai import OpenAI
client = OpenAI(api_key="your-api-key")
def search_with_openai_api(query):
# This would call a real search API
import requests
response = requests.get(f"https://api.search.example.com/search?q={query}")
return response.json()
Using Anthropic API: Use Claude with the tool_use feature (https://docs.anthropic.com).
Using LangChain: LangChain handles the agent loop for you. You just define tools and let LangChain run the loop (https://www.langchain.com).
Using LangGraph: For more control, use LangGraph. It's a framework for building agent workflows (https://langchain-ai.github.io/langgraph/).
Common Mistakes
Mistake 1: Tool descriptions are too vague.
- Bad: "search" (unclear what it searches)
- Good: "Search the web for current weather information"
Mistake 2: Not handling tool errors. If a tool returns an error, tell the model. The model might try a different approach.
Mistake 3: No iteration limit. Without a max, the agent can loop forever. Always set a max_iterations.
Mistake 4: No cost tracking. Each API call costs money. Track your total cost and set a budget.
Next Steps
Now that you have a basic agent, let's learn how to write better tool descriptions. That's the key to making agents work well.
Discussion
Sign in to comment. Your account must be at least 1 day old.