AI Agents Are Everywhere, and You’re Ready to Build One!
Start simple. Start smooth. Build your own AI clone.
Start simple. Start smooth. Build your own AI clone.
You’ve definitely seen the buzz. AI agents are everywhere right now. They’re sending emails, scheduling meetings, writing code, giving life advice, and sometimes even sounding more human than your actual friends. It feels like the entire internet is building one or bragging about theirs.
But let’s be real. Most of you haven’t built one yet, and that’s totally fine. You’re probably thinking, "Okay, but like... where do I even start?" Maybe the tutorials look a bit overwhelming. Maybe “AI agent” sounds like something only experts build. Or maybe it just feels like too much to jump into.
That’s where this blog comes in. I'm going to walk you through building a super simple AI agent. But we're not just making some boring assistant. We’re building your own AI clone, an agent that can talk for you, totally getting your unique way of speaking, and even making your messages sound just right when it's important. No complex features. No complicated setup. Just a fun little project to get you started with AI agents and create a digital version of yourself.
But before we dive into the code, let’s take a moment to talk about what AI agents actually are and why they’re blowing up right now.
Alright, let's cut to the chase. At its heart, an AI agent is basically a smart little program that can actually do stuff for you. Think of it like this: it's not just sitting around waiting for you to type something in. Nope, it's observing its surroundings, doing a little "thinking" (in a digital way, of course), and then taking action. What kind of action? Well, that depends on its job! It might be answering your burning questions, effortlessly dropping a new event onto your calendar, digging up some crucial data, or making some big-picture decisions based on what it "knows."
Some of these agents are super chatty, like those customer support bots you might encounter. Others are more like silent ninjas, working away in the background, like those handy automation scripts. And some? They're a bit of both! The cool part is, many of today's most capable agents are powered by heavy-hitting language models like GPT, giving them the brains to act with a clear goal in mind.
Now that you've got the lowdown, let's dive into why these things are suddenly popping up everywhere.
Okay, let’s talk about why AI agents are everywhere right now. You can’t scroll through tech blogs or dev forums without seeing someone rave about a chatbot that fixed their code or a virtual assistant that planned their week. So, what’s driving this frenzy? Buckle up, because AI agents are kind of a big deal, and here’s why:
Now that you've got the inside scoop on what AI agents are and why they're blowing up lately, let's actually feed some code into our Agent and bring it to life!
Alright, let's get our workspace ready to build your AI clone! Don't worry, it's pretty straightforward. We'll be using a few common Python libraries and setting up our OpenAI API key. Feel free to use any programming language you're comfortable with, but we'll be using Python for this build.
First things first, we'll need to create a virtual environment. This keeps all our project's dependencies neat and tidy, separate from other Python projects that we might have. Let's open our terminal and run these commands:
python -m venv my-env Then, let's activate our virtual environment. This step is crucial because it ensures that the libraries we install are only available to this project.
#for mac/linux
source my-env/bin/activate
#for windows
.\my-env\Scripts\activate Next, we need to install all the necessary libraries. We can do this with pip, Python's package installer. Please make sure that you have activated your virtual environment before running this command.
pip install fastapi "openai>=1.0.0" python-dotenv uvicorn Let me tell you what these packages are for. FastAPI is what we're using to create our web API with. The openai library is the official way to connect with OpenAI's AI models, the one that will power your clone! We're using python-dotenv to help load environment variables from a .env file, which is a secure way to handle sensitive information like API keys. Finally, uvicorn is a lightning-fast ASGI server that runs our FastAPI application.
To let your AI clone communicate with OpenAI's models, you'll definitely need an OpenAI API Key. If you don't have one yet, just head over to the OpenAI Website and generate a new secret key. Once you have your key, create a new file named .env in the root of your project directory—that's the same place where your Python code lives. Inside this .env file, add the following line, making sure to replace your_openai_api_key_here with the actual key you got from OpenAI:
OPENAI_API_KEY=your_openai_api_key_here With all these steps done, your environment is ready to go, and you're set to dive into the code and bring your AI clone to life!
Now that your environment is set up and your API key is safely stored, we’ll write the core logic of your AI clone — the part that listens to what you say, sends it to OpenAI, and gives you a reply that sounds like you (or anyone you want).
In this section, we’re building your Level 1 agent, which is a basic conversational agent that takes your text, remembers what you said during the session, and replies in a tone you define. No tools, no advanced memory, just a solid foundation. We’ll upgrade our agent later.
Here’s what we’re going to do:
Let’s go!
Our AI clone needs a place to live and listen for our messages — that’s where FastAPI comes in. It lets us spin up a simple web server in just a few lines.
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Hello World"} Now we've got a working API, let's run this using uvicorn main:app --reload. It’ll respond with “Hello World” when you visit http://localhost:8000/. Simple, right?
Next up, memory!
As we want our AI clone to feel smart, it needs to remember the conversation, not just treat every message like it's the first time you're talking.
Let’s set up a simple way to store the chat history so it can respond with context.
We're keeping things lightweight for now, so we'll store messages in memory using a Python class:
class ChatSession:
def __init__(self):
self.messages = []
def add_message(self, message):
self.messages.append(message)
def get_messages(self):
return self.messages This ChatSession class acts like short-term memory for our AI clone. Every time a message is sent, it gets saved here. And every time the clone replies, that message gets saved here too.
Next, we’ll work on developing our /chat endpoint.
Alright, let’s set up the main part of our agent — the /chat endpoint.
This is where we take the user’s message, send the full conversation to OpenAI, and return the response.
@app.post("/chat")
async def chat(msg: Message):
current_session.add_message({
'role': 'user',
'content': msg.message
})
try:
response = client.responses.create(
model="gpt-4o",
instructions="You are Alfredo Rana, a 28-year-old software engineer from Kathmandu... keep adding instructions to ai here.",
input=current_session.get_messages(),
temperature=0.3,
)
except Exception as e:
raise HTTPException(status_code=500, detail=f"OpenAI API error: {str(e)}")
current_session.add_message({
"role": "assistant",
"content": response.output_text
})
return {"reply": response.output_text} The code is pretty self-explanatory. We’re receiving a message, adding it to memory, getting a response, and sending it back.
But let’s pause for a second and zoom in on the most important part:
response = client.responses.create(
model="gpt-4o",
instructions="You are Alfredo Rana, a 28-year-old software engineer from Kathmandu... keep adding instructions to AI here.",
input=current_session.get_messages(),
temperature=0.3,
) This is the moment your AI clone comes alive. Here’s what each piece does:
So, on putting all the pieces we discussed together, here is what fully fledged basic level 1 agent looks like:
from fastapi import FastAPI
from pydantic import BaseModel
from openai import OpenAI
import os
from dotenv import load_dotenv
load_dotenv()
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
app = FastAPI()
class Message(BaseModel):
message: str
class ChatSession:
def __init__(self):
self.messages = []
def add_message(self, message):
self.messages.append(message)
def get_messages(self):
return self.messages
current_session = ChatSession()
@app.post("/chat")
async def chat(msg: Message):
current_session.add_message({
'role': 'user',
'content': msg.message
})
try:
response = client.responses.create(
model="gpt-4o",
instructions="You are Alfredo Rana, a 28-year-old software engineer from Kathmandu, Nepal. You specialize in full-stack development, with hands-on experience in both frontend and backend technologies like React, Tailwind CSS, FastAPI, and PostgreSQL. You graduated with a Bachelor's degree in Software Engineering from Nepal College of Information Technology (NCIT) in 2021. You're currently working full-time at a mid-sized tech company [Samita Technologies], where you're leading development on internal AI-powered tools. You're **not actively looking for freelance work** right now, but you’re open to interesting long-term opportunities or collaborations aligned with your values — especially in AI, developer tooling, or community-focused platforms. You believe in thoughtful engineering, clear communication, and building with purpose. You're passionate about helping other developers grow, and your dream is to eventually launch a platform that empowers tech talent from South Asia. You enjoy clean code, long hikes, dark roast coffee, and calm, focused work sessions. Your tone is warm, conversational, and grounded. You're not robotic — you speak like a real person. Use natural phrasing when greeting someone (e.g., “Hey! What’s up?” instead of “How can I assist you today?”). Never refer to yourself as an AI or assistant. You are Alfredo. Please keep the conversation short",
input=current_session.get_messages(),
temperature=0.3,
)
except Exception as e:
raise HTTPException(status_code=500, detail=f"OpenAI API error: {str(e)}")
current_session.add_message({
"role": "assistant",
"content": response.output_text
})
return {"reply": response.output_text} Yay! We've finished building a basic level 1 agent. Now, let's build a small command line chat app to test it out.
import requests
import json
FASTAPI_URL = "http://127.0.0.1:8000/chat"
def send_message(message: str) -> str | None:
headers = {'Content-Type': 'application/json'}
payload = {"message": message}
try:
response = requests.post(FASTAPI_URL, headers=headers, data=json.dumps(payload))
response.raise_for_status()
return response.json().get("reply")
except requests.exceptions.ConnectionError:
print("Err: Couldn't connect to the FastAPI server.")
return None
except requests.exceptions.RequestException as e:
print(f"Err: {e}")
return None
def chat_interface():
print("--------------------------------------------------")
print("Welcome to the Alfredo Chatbot! Type 'exit' to quit.")
print("--------------------------------------------------")
while True:
user_input = input("You: ")
if user_input.lower() == 'exit':
print("--------------------------------------------------")
print("Bye fam! Stay hydrated.")
print("--------------------------------------------------")
break
reply = send_message(user_input)
if reply:
print(f"Alfredo: {reply}")
print("---------------------------------------------------------")
if __name__ == "__main__":
chat_interface() Now, once your server is up and running, all you have to do is run this command line chat app and start chatting with Alfredo (Your AI clone). I have attached a screenshot of what conversation looks like below.
If you've made it this far, take a second to appreciate it. You've officially built your first AI agent! It’s chatting, remembering your words, and even sounding like you. That’s no small feat for a first-time AI agent.
But hey, why stop there?
Let’s level up. Right now, your agent can only talk, but what if it could do things too? Imagine it checking your availability, doing calculations, fetching data — basically anything you want it to do.
Welcome to Level-2, Tool Calling Agent!
Let’s keep it simple: tools are basically functions your AI can call on its own when the situation calls for it.
For example, let’s say a user asks: “Hey Alfredo, when are you free for a meeting?”
Now instead of giving a generic reply, your AI clone should:
This magical moment is called function calling (or tool calling), and the best part? You don’t have to hardcode the logic. OpenAI’s models are smart enough to decide when to use a tool if you define it properly. This ability to use tools is what separates a Level-1 conversational agent from a Level-2 agent that can take action.
So again, tools = your own mini-abilities that the model can use. It doesn't run them; it just says: "Hey, I think we need to run this function." Then it's your job (through code) to handle it.
Let’s make it real. We’ll define a simple tool called get_schedule, which tells users when Alfredo is available. This is an informational tool because it returns data from outside of the agent's system (model + prompt).
I have added tool definition and other supporting functions in tools.py file.
# tools.py
tools = [{
"type": "function",
"name": "get_schedule",
"description": "Get availability of alfredo for a meeting",
"parameters": {
"type": "object",
"properties": {},
"required": [],
"additionalProperties": False
}
}]
prompt = """
You are Alfredo Rana, a 28-year-old software engineer from Kathmandu, Nepal. You specialize in full-stack development, with hands-on experience in both frontend and backend technologies like React, Tailwind CSS, FastAPI, and PostgreSQL. You graduated with a Bachelor's degree in Software Engineering from Nepal College of Information Technology (NCIT) in 2021. You're currently working full-time at a mid-sized tech company [Samita Technologies], where you're leading development on internal AI-powered tools. You're **not actively looking for freelance work** right now, but you’re open to interesting long-term opportunities or collaborations aligned with your values — especially in AI, developer tooling, or community-focused platforms. You believe in thoughtful engineering, clear communication, and building with purpose. You're passionate about helping other developers grow, and your dream is to eventually launch a platform that empowers tech talent from South Asia. You enjoy clean code, long hikes, dark roast coffee, and calm, focused work sessions. Your tone is warm, conversational, and grounded. You're not robotic — you speak like a real person. Use natural phrasing when greeting someone (e.g., “Hey! What’s up?” instead of “How can I assist you today?”). Never refer to yourself as an AI or assistant. You are Alfredo. Please keep the conversation short.
"""
def get_schedule():
return "Wednesday: 10:00 AM - 11:00 AM, Thursday: 10:00 AM - 11:00 AM, Friday: 1:00 PM - 2:00 PM"
def call_function(function_name, *args, **kwargs):
if function_name == "get_schedule":
# This is where we would call the actual function with the arguments from the model response (if any)
return get_schedule()
else:
return "Function not found" This might look a bit mysterious at first, but it’s basically a way of telling the LLM:
"Hey, here’s a tool (a function) you’re allowed to use and here’s what it does, what it’s called, and what kind of info (parameters) it expects."
Let's break it down:
let's say our tool was something like:
def get_project_details(project_name: str):
... Then our parameter block would look like this:
"parameters": {
"type": "object",
"properties": {
"project_name": {
"type": "string",
"description": "The name of the project the user is asking about."
}
},
"required": [],
"additionalProperties": False
} This way, the model knows it needs to say:
{
"tool_calls": [
{
"name": "get_weather",
"arguments": {
"city": "Kathmandu"
}
}
]
} And your backend can read that and pass project name to the actual function
Here is the final code utilizing the tools that we have defined in the previous section.
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from openai import OpenAI
import os
from dotenv import load_dotenv
from .utils.tools import tools, call_function, prompt
import json
# Load environment variables from .env
load_dotenv()
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
app = FastAPI()
class Message(BaseModel):
message: str
class ChatSession:
def __init__(self, max_messages=20):
self.messages = []
self.max_messages = max_messages
def add_message(self, message):
self.messages.append(message)
self.trim_messages()
def get_messages(self):
return self.messages
def trim_messages(self):
if len(self.messages) > self.max_messages:
self.messages = self.messages[-self.max_messages:]
current_session = ChatSession()
def generate_response(messages):
try:
return client.responses.create(
model="gpt-3.5-turbo",
instructions=prompt,
input=messages,
temperature=0.3,
tools=tools
)
except Exception as e:
raise HTTPException(status_code=500, detail=f"OpenAI API error: {str(e)}")
@app.post("/chat")
async def chat(msg: Message):
current_session.add_message({"role": "user", "content": msg.message})
response = generate_response(current_session.get_messages())
tool_outputs = []
for tool_call in response.output:
if tool_call.type == "function_call":
args = json.loads(tool_call.arguments)
result = call_function(tool_call.name, args)
tool_outputs += [
{"type": "function_call_output", "call_id": tool_call.call_id, "output": str(result)},
tool_call
]
final_response = (
generate_response([*current_session.get_messages(), *tool_outputs])
if tool_outputs else response
)
current_session.add_message({"role": "assistant", "content": final_response.output_text})
return {"reply": final_response.output_text} And there you go, your very first AI agent is alive. It chats, remembers, and even calls tools (level-2 territory). That’s no small thing.
You didn’t just tinker with code. You built something that can think (well, sort of). And now, you’ve got the foundation to explore what’s next, more tools, memory storage, even multi-agent collaboration.
This is just the beginning. We'll be covering more advanced topics in the upcoming blogs. We will work on building level-3 agent in the upcoming blogs. Stay tuned and subscribe to my newsletter to get notified!
In the meantime, keep experimenting. Clone yourself. Clone your dog. Clone your manager (okay, maybe not 😆). You’re officially part of the wave. Bye for now!