Build a Research Agent with Claude API
Build a CLI AI agent that uses tools to answer complex questions.
Introduction
30 Second Summary
Every time you ask an AI assistant to look something up, calculate a number, or fetch information from the web, an invisible loop is running behind the scenes. The AI decides what it needs, calls the right tool, reads the result, and decides what to do next.
In this project, you will build that loop from scratch. You will create a command-line research agent in Python that reasons about your questions, calls tools like a calculator and web fetcher, and chains their results into a complete answer.
What You'll Build
You type a question into your terminal, the agent figures out which tools it needs, calls them one by one, and prints a natural-language answer alongside a real-time trace of every tool call it made.
By the end of this project, you'll have:
- A working CLI agent that decides when to call external tools and chains their results to answer complex questions. You can ask a precise math question and watch the agent call its calculator to get an exact answer instead of guessing.
- Hands-on understanding of the ReAct loop pattern (reason-act-observe) that powers production AI agents like Claude, ChatGPT, and Copilot.
- The exact mental model for how tool definitions, stop reasons, and message threading work under the hood. You can ask multi-step questions that require chaining tools and watch the agent solve them step by step.
- Secret Mission: Add conversation memory so your agent remembers previous turns.
Are there any prerequisites?
You should be comfortable with Python basics (functions, dictionaries, loops). You should also have Python and VS Code already installed on your machine.
No prior experience with AI APIs or agent frameworks is needed. You will learn everything from scratch.
Before We Start
Before we dive in, let's get clear on what you're about to build and why it matters. Taking a moment to articulate your goal makes the hands-on steps ahead more intentional.
Set Up Your Environment
Your research agent needs to communicate with Claude's brain in the cloud. That means you need three things: an account with Anthropic, an API key that authenticates your requests, and the Python SDK that handles the connection.
In this step, you will create your Anthropic Console account, set up a clean project folder with its own isolated Python environment, and install everything needed to make your first API call.
In this step, get ready to:
- Create an Anthropic Console account and generate an API key.
- Set up the project directory with a virtual environment.
- Install the Anthropic SDK and verify it works.
Create your Anthropic account and API key
An API key is a secret string that proves your identity to Anthropic's servers. Every request your agent makes will include this key so Claude knows who is calling.
- Open your browser and go to console.anthropic.com.
- Create a new account (or sign in if you already have one).
- Once signed in, navigate to Settings in the sidebar, then select API Keys.
- Click Create Key.
- Give your key a name (e.g. research-agent) and confirm.
- Copy the key immediately and paste it somewhere safe (a temporary note or password manager). You will not be able to see it again after closing this dialog.
What is an API key?
An API key is like a password that identifies your application to a service. The Anthropic SDK reads it from an environment variable so you never have to hard-code it into your scripts.
New Anthropic accounts receive free starter credits, so this project costs under $0.10 to complete.
Keep your API key private
Never commit your API key to version control or share it publicly. Anyone who has it can make API calls on your account.
Create the project folder and install the SDK
A virtual environment gives your project its own isolated set of Python packages. This prevents version conflicts with other projects on your machine.
- Press Cmd+Space (macOS) or the Windows key (Windows) to open your search bar.
- Type Terminal and press Enter to open it.
- Move to your Desktop by running this command:
cd ~/Desktop
- Create your project folder and move into it by running these commands:
mkdir research-agent && cd research-agent
- Create a virtual environment and activate it, then install the Anthropic SDK by running:
python3 -m venv .venv && source .venv/bin/activate
pip install anthropic
You will see pip downloading and installing the package. When it finishes, you should see a line that includes Successfully installed anthropic- followed by a version number.
What do these commands do?
- mkdir research-agent creates a new folder on your Desktop.
- python3 -m venv .venv creates an isolated Python environment inside a hidden .venv folder.
- source .venv/bin/activate activates the environment so pip install installs packages into it instead of globally.
- pip install anthropic downloads the official Anthropic Python SDK.
Seeing a permission error or command not found?
- If python3 is not found, confirm Python is installed by running python3 --version. You need Python 3.9 or higher.
- If pip install fails with a permissions error, make sure you activated the virtual environment first. Your terminal prompt should show (.venv) at the beginning.
Still stuck? Help me troubleshoot my Python environment setup.
Set your API key and verify the installation
The Anthropic SDK automatically reads your API key from an environment variable called ANTHROPIC_API_KEY. Setting it in your terminal session makes it available to every Python script you run in that session.
- Set your API key as an environment variable by running this command (replace your-api-key-here with the key you copied earlier):
export ANTHROPIC_API_KEY="your-api-key-here"
Why an environment variable?
Storing secrets in environment variables keeps them out of your source code. The SDK reads ANTHROPIC_API_KEY automatically, so you never need to paste the key into a Python file.
Before you run the next command, what do you expect to see if the SDK installed correctly?
- Verify the SDK loads by running:
python -c "import anthropic; print(anthropic.__version__)"
You should see a version number printed, such as 0.117.0. This confirms the SDK is installed and Python can find it.
Seeing ModuleNotFoundError?
- Make sure your virtual environment is still active. Look for (.venv) at the start of your terminal prompt. If it disappeared, re-activate by running source .venv/bin/activate from inside the research-agent folder.
- If you used python3 to create the venv but python to run the check, try python3 -c "import anthropic; print(anthropic.__version__)" instead.
Still stuck? Help me fix my anthropic SDK import error.
- Open VS Code in your project folder by running:
code .
VS Code opens with the research-agent folder loaded. You are ready to start writing code.
Use VS Code's integrated terminal
From here on, you can use the terminal inside VS Code (open it with Ctrl+`). Make sure the virtual environment is active in that terminal. You should see (.venv) in the prompt.
Your environment is ready. Next up, you will build a basic chatbot and discover firsthand why Claude needs tools to give accurate answers.
Build a Basic Chatbot
Your environment is ready with the SDK installed and your API key set. Now it is time to write actual code that talks to Claude.
Before giving an agent tools, you need a working chatbot as the foundation. You will also discover a critical limitation firsthand: Claude can reason about math, but it cannot compute. That gap is the exact problem tools will solve in the next step.
In this step, get ready to:
- Create agent.py with a conversation loop that sends messages to the Claude API.
- Run the chatbot and see it answer general knowledge questions correctly.
- Ask a precise math question and observe Claude get it wrong.
Create the chatbot script
The chatbot has a simple structure: a loop that reads your input, sends it to Claude, and prints the reply. It also keeps a messages list so Claude can see the full conversation history each turn.
- Create a new file called agent.py inside your research-agent folder by running:
touch agent.py
- Open agent.py in VS Code and paste the following code:
import anthropic
# Create client (reads ANTHROPIC_API_KEY from environment)
client = anthropic.Anthropic()
MODEL = "claude-sonnet-5"
def main():
print("Research Agent (type 'quit' to exit)")
print("-" * 40)
messages = [] # Conversation history
while True:
user_input = input("\nYou: ").strip()
if user_input.lower() in ("quit", "exit"):
print("Goodbye!")
break
if not user_input:
continue
# Send message to Claude and print the reply
messages.append({"role": "user", "content": user_input})
response = client.messages.create(
model=MODEL,
max_tokens=1024,
messages=messages,
)
reply = response.content[0].text
messages.append({"role": "assistant", "content": reply})
print(f"\nAgent: {reply}")
if __name__ == "__main__":
main()
What does this code do?
- anthropic.Anthropic() creates an API client that automatically reads your ANTHROPIC_API_KEY environment variable.
- messages stores the full conversation so Claude sees prior context on every turn.
- client.messages.create() sends your message list to Claude and returns a response object.
- response.content[0].text extracts the text reply from the first content block Claude returns.
- Save agent.py.
Seeing a syntax error on save?
- Check that the quotes around "quit" and "exit" are straight quotes, not curly quotes that word processors sometimes insert.
- Make sure the f in f"\nAgent: {reply}" is directly before the opening quote with no space.
Help me fix a syntax error in my agent.py chatbot script.
✔️ Awesome, I've got everything!
Great. Double check you have saved agent.py and you are ready to run it.
ⓧ I'd like to double check the full code
Scroll up and confirm your agent.py contains these pieces in order:
- The import anthropic line at the top.
- client = anthropic.Anthropic() and MODEL = "claude-sonnet-5" below the import.
- The main() function containing the while True loop with input handling, the API call, and the print statement.
- The if __name__ == "__main__" guard at the very bottom calling main().
Run the chatbot and test its limits
Time to see your chatbot in action. You will ask it two questions: one it can handle, and one that exposes its weakness.
- Start the chatbot by running:
python agent.py
You should see the header Research Agent (type 'quit' to exit) followed by a You: prompt waiting for your input.
- Type this question and press Enter:
What is the capital of France?
Claude responds with the correct answer: Paris. General knowledge is no problem.
Now try something harder. Before you ask the next question, do you think Claude can do precise arithmetic on its own?
- Type this math question and press Enter:
What is 847 * 293 + 156?
Look at the answer Claude gives. The correct answer is 248,227. Claude either gives a wrong number or hedges with phrases like "approximately."
Why did Claude get it wrong?
Large language models predict the most likely next token. They do not have a calculator running inside them. For simple math like 2 + 2, the training data contains enough examples that the model gets it right by pattern matching.
For multi-step arithmetic like 847 * 293 + 156, pattern matching breaks down. This is Claude without tools: it can reason but cannot compute. That gap is exactly what you will fix in the next step.
- Type quit and press Enter to exit the chatbot.
You have a working chatbot, and you have seen its blind spot firsthand. Next up, you will give Claude a calculator tool and build the agent loop so it can request computations and receive exact results.
Add the Calculator Tool and Agent Loop
In the last step, you asked Claude a precise math question and watched it get the answer wrong. That's the gap you're about to close.
You'll define a calculator tool that Claude can call when it needs exact arithmetic. Then you'll build the ReAct loop (reason-act-observe) that powers every production AI agent: Claude reasons about what it needs, acts by calling a tool, observes the result, and responds.
In this step, get ready to:
- Define a calculator tool using JSON Schema so Claude knows how to call it.
- Build the agent loop that lets Claude request tool calls and receive results.
- Test that Claude now computes exact math answers instead of guessing.
Define the calculator tool
Tools in the Claude API are defined as dictionaries with a JSON Schema that tells Claude what parameters the tool accepts. Claude reads this schema and decides when to use the tool based on the user's question.
- In agent.py, find the first line:
import anthropic
- Add import json on a new line directly below it, so the top of your file looks like this:
import anthropic
import json
You'll use json later to print tool call details in a readable format.
- Now add the tool definition below the MODEL = "claude-sonnet-5" line by pasting this code:
# Define the tools Claude can use
tools = [
{
"name": "calculator",
"description": "Evaluate a mathematical expression. Use this for any arithmetic, algebra, or math calculations.",
"input_schema": {
"type": "object",
"properties": {
"expression": {
"type": "string",
"description": "The mathematical expression to evaluate, e.g. '2 + 2' or '(847 * 293) + 156'"
}
},
"required": ["expression"]
}
}
]
What does this code do?
The tools list contains one tool definition. Each tool has a name Claude uses to request it, a description that helps Claude decide when to use it, and an input_schema that defines what parameters Claude must provide.
The schema tells Claude that calculator expects a single string called expression. Claude will format its math request into this field when it decides to call the tool.
- Below the tools list, add the function that actually runs the calculation by pasting this code:
def execute_tool(name, input_data):
if name == "calculator":
try:
expression = input_data["expression"]
# Only allow safe math characters
allowed_chars = set("0123456789+-*/.() ")
if not all(c in allowed_chars for c in expression):
return "Error: Expression contains invalid characters. Only numbers and +-*/.() are allowed."
result = eval(expression)
return str(result)
except Exception as e:
return f"Error evaluating expression: {e}"
return f"Error: Unknown tool '{name}'"
What does this code do?
The execute_tool function receives the tool name and the input Claude provided. It checks which tool was called, then runs the appropriate logic.
For the calculator, it first validates the expression using an allowlist of safe characters (digits, operators, parentheses, spaces). This prevents code injection since eval() could otherwise run arbitrary Python. After validation, it evaluates the math and returns the result as a string.
- Save agent.py.
- Verify the tool works by running this quick test:
python -c "from agent import execute_tool; print(execute_tool('calculator', {'expression': '2 + 2'}))"
You should see 4 printed in your terminal.
Seeing an ImportError or SyntaxError?
- Check that import json is on its own line directly below import anthropic.
- Make sure the tools list has matching brackets and commas. JSON Schema uses nested dictionaries, so double-check every closing brace.
- Confirm your virtual environment is still active (you should see (.venv) in your terminal prompt).
Still stuck? Help me debug this ImportError when testing my execute_tool function
Build the agent loop
The tool definition tells Claude what it can call, but you still need the loop that sends requests, checks if Claude wants a tool, runs it, and feeds the result back. This is the ReAct loop pattern: reason, act, observe, repeat.
- In agent.py, find your existing def main(): function. Add the following run_agent function directly ABOVE def main(): by pasting this code:
def run_agent(user_message):
# Start a fresh conversation with the user's question
messages = [{"role": "user", "content": user_message}]
max_iterations = 10
for i in range(max_iterations):
# Send messages to Claude, including our tool definitions
response = client.messages.create(
model=MODEL,
max_tokens=1024,
tools=tools,
messages=messages,
)
# If Claude is done talking, extract and return the text
if response.stop_reason == "end_turn":
final_text = next(
(block.text for block in response.content if block.type == "text"),
"No response generated."
)
return final_text
What does this code do?
- The function starts by putting the user's message into a messages list that will grow as the conversation continues.
- A max_iterations guard of 10 prevents infinite loops if Claude keeps requesting tools endlessly.
- Each iteration calls client.messages.create() with the tools list included so Claude knows what it can call.
- If response.stop_reason is "end_turn", Claude is finished and the function returns the text response.
- Directly below the code you just pasted (still inside the run_agent function, inside the for loop), add the tool execution logic:
# Claude wants to use tools - execute each one
tool_results = []
for block in response.content:
if block.type == "tool_use":
print(f" [Tool call: {block.name}({json.dumps(block.input)})]")
result = execute_tool(block.name, block.input)
print(f" [Result: {result[:100]}{'...' if len(result) > 100 else ''}]")
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": result
})
# Thread the tool results back into the conversation
messages.append({"role": "assistant", "content": response.content})
messages.append({"role": "user", "content": tool_results})
return "Max iterations reached. The agent could not complete the task."
What does this code do?
When Claude's response contains tool_use blocks instead of finishing, this code executes each requested tool and collects the results.
- Each tool call is printed in real time so you can watch the agent think.
- The results are packaged as tool_result messages with the matching tool_use_id so Claude knows which call each result belongs to.
- Both the assistant's tool request and the tool results are appended to messages, then the loop continues so Claude can process the results and either call another tool or respond.
- Save agent.py and confirm there are no syntax errors by running:
python -c "import agent"
If no error prints, your syntax is correct.
Seeing an IndentationError?
- The second code block must be indented at the same level as the if response.stop_reason check above it (two levels of indentation inside run_agent and inside the for loop).
- Make sure return "Max iterations reached..." is at the same indent level as the for line (one level inside run_agent).
Need more help? Help me fix this IndentationError in my run_agent function
Update main and test the agent
The run_agent function handles the full conversation loop now, so main() just needs to pass user input to it.
- Replace your existing def main(): function and everything below it with this updated version:
def main():
print("Research Agent (type 'quit' to exit)")
print("-" * 40)
while True:
user_input = input("\nYou: ").strip()
if user_input.lower() in ("quit", "exit"):
print("Goodbye!")
break
if not user_input:
continue
print()
response = run_agent(user_input)
print(f"\nAgent: {response}")
if __name__ == "__main__":
main()
What changed in main?
The old main() called client.messages.create() directly and managed messages itself. The new version delegates everything to run_agent(), keeping main() focused on the user input loop.
- Save agent.py.
Before you run the agent, think about this: if you ask "What is 847 * 293 + 156?", do you think the agent will compute the answer directly or call the calculator tool first?
- Run the agent:
python agent.py
- When you see the You: prompt, type:
What is 847 * 293 + 156?
You should see the tool call trace print in real time, followed by the correct answer:
[Tool call: calculator({"expression": "(847 * 293) + 156"})]
[Result: 248227]
Agent: 847 * 293 + 156 = 248,227
Claude recognized it needed exact arithmetic, called the calculator tool, received the result, and presented the answer naturally. That's the ReAct loop in action.
- Type quit to exit the agent.
Agent not calling the calculator?
- Make sure you passed tools=tools in the client.messages.create() call inside run_agent. Without this, Claude does not know any tools exist.
- Check that response.stop_reason == "end_turn" uses a double equals sign, not a single one.
- Verify the tools list is defined at the module level (below MODEL), not inside a function.
Still not working? Help me figure out why my agent is not calling the calculator tool
✔️ Awesome, I've got everything!
Great. Double check you've saved agent.py and that the calculator is working.
ⓧ I'd like to double check the full code
Your agent.py should have these sections in order. Scroll up and confirm each is present:
- Imports: import anthropic and import json at the top.
- Client and model: client = anthropic.Anthropic() and MODEL = "claude-sonnet-5".
- The tools list with the calculator tool definition.
- The execute_tool(name, input_data) function with the character allowlist and eval().
- The run_agent(user_message) function with the loop, stop_reason check, tool execution, and message threading.
- The updated main() function that calls run_agent() and the if __name__ == "__main__" guard.
Your agent can now compute exact answers to any math question. Next up, you'll add a second tool that fetches live web pages, letting you see how Claude picks the right tool for the job.
Add the Web Fetcher Tool
Your agent can do math now. But a calculator alone limits it to arithmetic. What about accessing live information from the web?
Adding a second tool lets you see how Claude selects the right tool for the job. It also enables multi-step reasoning where tools chain together to solve problems neither could handle alone.
In this step, get ready to:
- Define a web fetcher tool schema that Claude can understand.
- Implement the handler using Python's built-in urllib library.
- Test multi-step queries that chain the web fetcher with reasoning.
Define the web fetcher tool
Every tool in your agent has two parts: a JSON Schema definition that tells Claude what the tool does and what inputs it accepts, and a handler function that actually executes the work.
- In agent.py, find the closing ] of your tools list (after the calculator tool definition).
- Add a comma after the calculator's closing }, then add this new tool definition before the ]:
{
"name": "web_fetcher",
"description": "Fetch the text content of a web page given its URL. Use this to retrieve information from websites.",
"input_schema": {
"type": "object",
"properties": {
"url": {
"type": "string",
"description": "The URL of the web page to fetch"
}
},
"required": ["url"]
}
}
What does this code do?
This is the tool's "menu entry" for Claude. It tells the model:
- name is the identifier Claude uses when requesting the tool.
- description helps Claude decide WHEN to use this tool (fetching web pages).
- input_schema defines exactly what parameters the tool accepts. Here it needs one string: a URL.
Implement the web fetcher handler
The tool definition tells Claude the tool exists. Now you need the actual code that fetches a web page when Claude calls it.
- At the top of agent.py, find the line import json and add these two imports directly below it:
import urllib.request
import urllib.error
- Now scroll down to the execute_tool function. Find the last line of the function:
return f"Error: Unknown tool '{name}'"
- Add this elif block directly above that line (between the calculator's except block and the final return):
elif name == "web_fetcher":
try:
url = input_data["url"]
# Build the request with a User-Agent header
req = urllib.request.Request(url, headers={"User-Agent": "ResearchAgent/1.0"})
# Fetch the page with a timeout to prevent hanging
with urllib.request.urlopen(req, timeout=10) as response:
content = response.read().decode("utf-8", errors="replace")
# Truncate to stay within token limits
return content[:5000]
except urllib.error.URLError as e:
return f"Error fetching URL: {e}"
except Exception as e:
return f"Error: {e}"
What does this code do?
The handler fetches a real web page when Claude requests it:
- urllib.request.Request builds the HTTP request with a custom User-Agent header so servers don't reject it as a bot.
- urlopen with timeout=10 prevents the agent from hanging forever on a slow server.
- content[:5000] truncates the response to 5000 characters. This keeps the text within Claude's context window without burning excessive tokens.
Why does the agent loop not need changes?
Your run_agent function already handles any number of tools. It checks response.stop_reason, iterates over all tool_use blocks, and calls execute_tool for each one. Adding a new tool just means adding a new branch in execute_tool. The loop stays the same.
- Save agent.py.
Before you run this, what do you think will happen if you ask the agent to fetch a web page? Will it use the new tool or try to answer from memory?
- Run your agent by executing this command:
python agent.py
- Type this prompt:
Fetch https://httpbin.org/html and tell me what the page is about
You should see the tool call trace printed in your terminal, something like:
[Tool call: web_fetcher({"url": "https://httpbin.org/html"})]
[Result: <!DOCTYPE html>\n<html>\n <head>\n </head>\n <body>...]
Then the agent responds with a summary of the page content. The page contains an excerpt from Herman Melville's Moby-Dick.
Seeing a URL error or timeout?
- Make sure you have an internet connection. The agent fetches real web pages live.
- Check that your imports are exactly import urllib.request and import urllib.error on separate lines at the top of the file.
- If you see NameError: name 'urllib' is not defined, the imports are missing or misspelled.
Still stuck? Help me debug my web_fetcher tool. I'm getting an error when trying to fetch a URL.
Test multi-step reasoning
A single fetch is useful, but the real power emerges when Claude chains tools and reasoning together to answer questions that require multiple steps.
What do you think will happen if you ask a question that requires fetching a page AND counting something in it? Will Claude call one tool or multiple?
- In the same running session (or restart with python agent.py), type this prompt:
Fetch https://httpbin.org/html and count how many paragraphs are in it
Watch what happens. Claude calls the web fetcher first to get the page content, then uses its own reasoning (or the calculator) to count the paragraphs. You can see each step printed in the trace.
What is multi-step reasoning?
This is the ReAct loop in action. Claude reasons about what it needs, acts by calling a tool, observes the result, then reasons again about what to do next. Each iteration through the loop is one reason-act-observe cycle.
Your agent handles this automatically because the loop keeps running until stop_reason is end_turn. Claude can take as many tool-calling steps as it needs (up to your max_iterations guard of 10).
- Type quit to exit the agent.
✔️ Awesome, I've got everything!
Great. Double check you have saved agent.py with both the new tool definition and the handler.
ⓧ I'd like to double check the full code
Your agent.py should now have these sections in order. Scroll up and confirm each one is present:
- Imports: anthropic, json, urllib.request, urllib.error.
- Client and model setup (client = anthropic.Anthropic() and MODEL = "claude-sonnet-5").
- tools list with two tool definitions: calculator and web_fetcher.
- execute_tool() function with an if branch for calculator, an elif branch for web_fetcher, and the fallback return at the end.
- run_agent() function (unchanged from the previous step).
- main() function (unchanged from the previous step).
Your agent now has two tools and can chain them together to solve complex problems. Next up, you will push it even further in the Secret Mission by adding conversation memory.
Secret mission
Add Conversation Memory
Right now your agent forgets everything between questions. A real assistant remembers what you said two minutes ago. Can you give your agent multi-turn memory so it can answer follow-up questions like "Double that result"?
Clean Up Your Resources
Clean Up Your Resources
Decide whether to keep your resources running, pause them to come back later, or delete them entirely.
This project runs entirely locally, so there are no ongoing costs. Your Anthropic API key only incurs charges when you make API calls.
Resources you used:
- Anthropic Console account with an API key (charges only accrue on API usage).
- Local project directory research-agent on your Desktop (includes virtual environment and agent.py).
Keep everything running
No action needed. Choose this if you plan to keep experimenting with your agent or building more projects with the Anthropic API.
- Your API key stays active. Set a spend limit in the Anthropic Console under Settings > Limits to avoid surprises.
- Your research-agent folder stays on your Desktop, ready to use anytime.
- The ANTHROPIC_API_KEY environment variable only lasts for your current terminal session. You will need to export it again next time you open a new terminal.
Pause - I'll come back to this later
Shut down running processes and deactivate your key to prevent accidental charges while keeping your code intact.
- Deactivate your API key in the Anthropic Console. Your account stays active, but the key cannot make API calls until you reactivate it.
- Your local research-agent folder stays untouched. When you come back, reactivate the key and export it in a new terminal session.
Delete - I don't want to use this again
Remove all project resources and revoke API access.
- Revoke your API key in the Anthropic Console. Your account persists but cannot make API calls.
- Delete the project folder by running this command in your terminal:
rm -rf ~/Desktop/research-agent
- Confirm the folder is gone by running:
ls ~/Desktop | grep research-agent
You should see no output, confirming the folder has been removed.
Nice Work!
Nice Work!
You just built a fully functional AI agent from scratch in about 100 lines of Python. Your research agent uses the same architecture that powers production systems like Claude, ChatGPT, and Copilot.
You've learned how to:
- Implement the ReAct loop (reason-act-observe) pattern that powers every major AI agent, wiring Claude into a loop where it decides when to call tools and when to respond.
- Define tools using JSON Schema and connect them to the conversation flow so Claude can request a calculation or fetch a web page and receive real results.
- Experience firsthand why tool use exists by watching Claude fail at exact math without tools, then solve it perfectly with the calculator tool wired in.
- Secret Mission: Added conversation memory so your agent remembers previous turns and can answer follow-up questions using prior context.
Ready to quiz yourself?