How to Build an AI Agent From Scratch: The Four Components Without Magic
An agent is not magic, but a while loop with good instructions. An engineering guide to building an AI agent from scratch: the model core, tools and function calling, the memory layer, and the ReAct loop, with code examples.
Everyone talks about "AI agents" as if they were mysterious magic. The truth is simpler and deeper at once: an agent is at its core a while loop that calls a language model, executes the tool it picks, then returns the result so it decides the next step — until it reaches its goal. What separates a "chatbot" from an "agent" is one word: decision. A chatbot generates text, while an agent generates text and takes actions (calling functions, querying databases, reading files), then uses their results to decide what to do next. Let's build a real engineering understanding of these components, not just marketing talk.
The First Component: The Model Core (The Engine)
At the heart of any agent is a language model (LLM) playing the role of the "brain" that receives inputs and makes decisions. But note a fundamental difference: here the model does not just generate text, but decides which tool to call, and with what arguments. For simple or cost-sensitive tasks, fast and economical models via the API suffice (like small fast models); for complex tasks requiring deep reasoning, you need more powerful models. The practical rule: do not use the most powerful model for everything; route the simple task to a cheap model, and save the powerful model for hard decisions.
The Second Component: Tools and "Function Calling"
The model alone is isolated: it does not browse the internet, read your database, or know today's weather. Tools are what give it "hands" to affect the world. In practice, a tool is an ordinary programming function (fetch weather, search a database) you describe to the model, which requests running it when needed via "function calling." The crucial point beginners overlook: a tool's description is no less important than its implementation. The model chooses the tool based on its description alone; a vague description leads to wrong choices, and a precise one with examples leads to reliable selection:
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Fetches the current weather for a given city. Use only when the user explicitly asks about weather.",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "City name, e.g., Riyadh"}
},
"required": ["city"]
}
}
}]
When the model decides it needs the tool, it returns a structured request with its name and arguments, your code runs it, and returns the result to it.
The Third Component: The Memory and Context Layer
The agent needs to know "what it did in the previous step," and here memory comes, in two kinds. Short-term memory is simply "chat history": every question, every tool call, and every result, within the current session. And the fundamental point that reveals how the agent actually works: the model has no memory between calls at all. You re-send the entire history on every iteration — the original question, every prior call, and every result — and it infers from them what to do next. The growing message list is the agent's memory.
As for long-term memory, it is for storing what goes beyond the session: user preferences, and prior project data. It is usually built via "vector databases," which store information as numerical vectors amenable to semantic search, so the agent retrieves what resembles its current context when it needs it. This is what distinguishes an agent that starts from scratch each time from one that "remembers."
The Fourth Component: The Agent Loop (ReAct)
Here everything comes together. The "agent loop" is the continuous cycle that makes it "think before acting." The most famous and most-used pattern in 2026 is called ReAct (short for Reason + Act), and it goes like this: Thought → Action → Observation → then a new Thought, and so on until the final answer:
Goal → Thought: what do I need?
→ Action: call a tool (search, calculate...)
→ Observation: the tool's result
→ Thought: is this enough? or do I need another step?
→ ... repeats ...
→ Final Answer
Why force the model to "think" first? For three practical reasons: reliability (thinking before acting reduces impulsive calls), auditability (the thought chain is a log of the agent's reasoning in production), and correction (if its reasoning is wrong, you catch it before the action executes). And the loop simply ends when the model stops requesting tools and responds with text — that is your signal to stop.
The Indispensable Safety Net: A Step Limit
Here is a crucial production lesson many overlook: an unguarded agent will loop forever. A confused model may keep calling tools in an endless loop, exhausting your API budget and prolonging the wait for nothing. The non-negotiable rule: always set a maximum step limit (max_steps). This simple control is the difference between a safe production agent and a billing disaster:
def run_agent(goal, max_steps=8):
messages = [{"role": "user", "content": goal}]
for step in range(max_steps):
response = call_llm(messages, tools)
if not response.tool_calls:
return response.content # no tools = done
result = execute_tool(response.tool_calls[0])
messages.append(response)
messages.append(result) # return the result to the history
return "The agent hit the step limit without completing the task"
This is complemented by the system prompt that sets "tool discipline": without good guidance, the model will overuse tools for things that do not need them. A simple phrase like "call a tool only when it directly answers a question the user asked" radically improves behavior.
The practical bottom line that sums up all of the above: building agents is not magic, but clear software engineering — a loop connecting a model to your environment via well-described tools, memory re-sent at every step, and limits preventing runaway. The next time someone talks about "agents" as a miracle, you'll smile, because you know they are at their core a while loop with good instructions. Start by building a simple agent from scratch to understand the mechanism, then move to ready frameworks knowing what they hide beneath — whoever understands the raw version uses ready tools with deeper awareness.
Was this article helpful?
Newsletter
Enjoyed this?
Subscribe and get every new article and news post straight to your inbox.