intermediate Engineers
Build Your First AI Agent from Scratch
Step-by-step tutorial for building a simple AI agent in Python with Claude API — from zero to working prototype.
What We’re Building
A simple AI agent that can:
- Search for information in files
- Perform calculations
- Answer questions with context
Prerequisites
- Python 3.10+
- Claude API key (get one at console.anthropic.com)
Step 1: Project Setup
mkdir my-agent && cd my-agent
python -m venv venv
source venv/bin/activate
pip install anthropic
Step 2: Define the Tools
# agent.py
import anthropic
import json
import os
client = anthropic.Anthropic()
tools = [
{
"name": "read_file",
"description": "Reads the contents of a file at the given path",
"input_schema": {
"type": "object",
"properties": {
"path": {
"type": "string",
"description": "Path to the file"
}
},
"required": ["path"]
}
},
{
"name": "calculate",
"description": "Evaluates a mathematical expression",
"input_schema": {
"type": "object",
"properties": {
"expression": {
"type": "string",
"description": "Math expression, e.g.: 2 + 2 * 3"
}
},
"required": ["expression"]
}
},
{
"name": "list_files",
"description": "Lists files in a directory",
"input_schema": {
"type": "object",
"properties": {
"directory": {
"type": "string",
"description": "Path to the directory"
}
},
"required": ["directory"]
}
}
]
Step 3: Implement Tool Execution
def execute_tool(name: str, input_data: dict) -> str:
"""Execute a tool and return the result."""
if name == "read_file":
try:
with open(input_data["path"], "r") as f:
return f.read()
except FileNotFoundError:
return f"File not found: {input_data['path']}"
elif name == "calculate":
try:
result = eval(input_data["expression"], {"__builtins__": {}})
return str(result)
except Exception as e:
return f"Calculation error: {e}"
elif name == "list_files":
try:
files = os.listdir(input_data["directory"])
return "\n".join(files)
except FileNotFoundError:
return f"Directory not found: {input_data['directory']}"
return f"Unknown tool: {name}"
Step 4: The Agentic Loop — The Heart of the Agent
def run_agent(user_message: str, max_iterations: int = 10):
"""Run the agent loop."""
messages = [{"role": "user", "content": user_message}]
system = """You are a helpful AI agent. You can read files,
perform calculations, and answer questions.
Use tools when needed. Be concise."""
for i in range(max_iterations):
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=4096,
system=system,
tools=tools,
messages=messages,
)
messages.append({"role": "assistant", "content": response.content})
# If the model finished — return text
if response.stop_reason == "end_turn":
for block in response.content:
if hasattr(block, "text"):
return block.text
return "Agent finished without a text response."
# If the model wants to call tools
if response.stop_reason == "tool_use":
tool_results = []
for block in response.content:
if block.type == "tool_use":
print(f" Tool: {block.name}({json.dumps(block.input)})")
result = execute_tool(block.name, block.input)
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": result,
})
messages.append({"role": "user", "content": tool_results})
return "Max iterations reached."
Step 5: Run It
if __name__ == "__main__":
while True:
user_input = input("\nYou: ")
if user_input.lower() in ("quit", "exit"):
break
print(f"\nAgent: {run_agent(user_input)}")
Testing
export ANTHROPIC_API_KEY=sk-ant-...
python agent.py
You: List the files in the current directory and count them
Tool: list_files({"directory": "."})
Tool: calculate({"expression": "5"})
Agent: There are 5 files in the current directory:
1. agent.py
2. venv
3. requirements.txt
4. data.csv
5. README.md
What’s Next
This is a basic agent. To make it production-ready:
- Add error handling and retry logic
- Add logging
- Restrict filesystem access
- Add more tools (HTTP requests, database)
- Consider MCP servers for standardized integration