Building Your First AI Agent from scratch in Python
I build systems that blend AI and automation to solve real-world problems
How to Build an AI Agent in Under 200 Lines of Python
Building an AI agent is actually easier than you might think. Forget the complex diagrams and abstract theories for a moment. At its core, an agent is just a clever loop that gives a language model superpowers. In this post, I’ll show you how to build a functional AI agent that can interact with your computer's file system, all in about 175 lines of Python code.
The Core Idea: What is an Agent?
Before we write any code, let's get the definitions right. For our purposes, an AI agent system boils down to two things:
Tools: These are special skills you give the AI model. Think of them as functions the AI can ask our program to run, like listing files, reading their contents, or even running a command in your terminal. We describe these tools to the AI using simple JSON.
Agent Loop: This is the process where the AI decides what to do, our code executes it, we feed the results back, and repeat until the task is complete.
Here’s what that loop looks like in simple pseudo-code.
# The basic logic of an agent loop
def run_agent(prompt, tools):
messages = [{"role": "user", "content": prompt}]
while True:
# 1. Get a response from the AI, telling it what tools are available
response = call_ai(messages, tools)
messages.append(response)
# 2. Check if the AI wants to use a tool
if response.has_tool_calls:
# 3. If yes, execute the tool
results = execute_tools(response.tool_calls)
# 4. Add the results back to the conversation
messages.append({"role": "tool", "content": results})
else:
# 5. If no, the AI is done. Return the final response.
return response.content
The AI decides, we execute, we report back. That's the magic. Now, let's build it.
Step 1: Setting Up Your Environment
First, let's get our project set up. We'll use uv for this tutorial because it's incredibly fast, but pip works just as well.
Create a Project Directory and Virtual Environment:
mkdir python-agent cd python-agent uv venv source .venv/bin/activateInstall the Anthropic Library:
Our agent will be powered by a Claude model, so we need the Anthropic Python library.uv pip install anthropicSet Your API Key:
You'll need an Anthropic API key. Once you have it, set it as an environment variable so our script can access it securely.export ANTHROPIC_API_KEY="your-anthropic-api-key-here"
Step 2: Defining the Agent's Tools
Create a new file called agent.py. The first thing we'll do is define the tools our agent can use. This is just a Python list of dictionaries, where each dictionary is a JSON schema describing a tool. The description field is the most important part—it's how the AI knows when to use a tool.
# In agent.py
import os
import json
import subprocess
from anthropic import Anthropic
# Tool definitions
TOOLS = [
{
"name": "list_files",
"description": "List files and directories at a given path.",
"input_schema": {
"type": "object",
"properties": {
"path": {
"type": "string",
"description": "Path to list (defaults to current directory)"
}
}
}
},
{
"name": "edit_file",
"description": "Edit a file by replacing old text with new text.",
"input_schema": {
"type": "object",
"properties": {
"path": {"type": "string", "description": "Path to the file to edit"},
"old_text": {"type": "string", "description": "Text to search for and replace"},
"new_text": {"type": "string", "description": "Text to replace with"}
},
"required": ["path", "old_text", "new_text"]
}
},
# ... other tools like read_file and run_bash go here ...
]```
#### Step 3: Creating the Tool Executor
Now that we've described the tools, we need a way to actually run them. The `execute_tool` function acts as a simple router. It takes the name of the tool and its arguments (as decided by the AI) and runs the corresponding Python code.
```python
# In agent.py
def execute_tool(name, arguments):
"""Execute a tool and return the result"""
if name == "list_files":
path = arguments.get("path", ".")
files = os.listdir(path)
return json.dumps(files, indent=2)
elif name == "edit_file":
path = arguments["path"]
old_text = arguments["old_text"]
new_text = arguments["new_text"]
# Read existing file
with open(path, 'r') as f:
content = f.read()
# Replace text and write back
new_content = content.replace(old_text, new_text)
with open(path, 'w') as f:
f.write(new_content)
return "File edited successfully."
# ... implementation for other tools ...
Step 4: Building the Agent Loop
This is where we bring it all together. The run_agent function implements the loop we discussed earlier. It takes a user's prompt, manages the conversation history, and coordinates between the AI and our tool executor.
# In agent.py
def run_agent(prompt):
"""Run the agent with a given prompt"""
client = Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])
messages = [{"role": "user", "content": prompt}]
print(f"🤖 Working on: {prompt}\n")
while True:
# Call the AI with the conversation and tools
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1024,
messages=messages,
tools=TOOLS
)
messages.append({"role": "assistant", "content": response.content})
# Check if the AI wants to use a tool
tool_calls = [c for c in response.content if c.type == "tool_use"]
if tool_calls:
# If yes, execute the tool(s)
tool_results = []
for call in tool_calls:
print(f"🔧 Using tool: {call.name}")
result = execute_tool(call.name, call.input)
tool_results.append({
"type": "tool_result",
"tool_use_id": call.id,
"content": result
})
# Add the results back to the conversation
messages.append({"role": "user", "content": tool_results})
else:
# If no tools are called, we're done
text_blocks = [c for c in response.content if c.type == "text"]
if text_blocks:
print(f"\n✅ Done: {text_blocks[0].text}")
break
Step 5: Running Your Agent
Finally, we just need a bit of boilerplate code at the end of agent.py to create a simple, interactive command line for our users.
# At the end of agent.py
if __name__ == "__main__":
while True:
try:
prompt = input("\n💬 What would you like me to do? (or 'quit' to exit)\n> ")
if prompt.lower() == 'quit':
break
run_agent(prompt)
except KeyboardInterrupt:
print("\n👋 Goodbye!")
break
Now, run it from your terminal:
python agent.py
Try giving it a task.
\> Create a simple hello.py file that prints "Hello, Agent!"
You’ll see the agent think, identify the edit_file tool as the right one to use, and execute it. It correctly deduces that to create a file, it can use the edit_file tool with an empty old_text string.
For a more complex task, try:
\> List all the python files in my directory and count the total lines of code in them.
Here, you'll see the agent chain its thoughts. It will first use list_files, see the output, and then use the run_bash tool with a command like wc -l agent.py hello.py to get the line counts and sum them up.
That's it! You've successfully built an AI agent. This simple pattern is the foundation for much more complex systems. You can add more tools, introduce better error handling, or even build a web interface around it. Happy building