
A chatbot with an LLM answers; an agent acts. That's the difference between a flashy demo and a tool that solves tasks: the agent decides what to do, uses tools, and checks if the result works. And that's programmed.
Anatomy: four pieces and a loop
- Reasoning loop: the model chooses the next step; you don't hardwire it.
- Tools: functions it can invoke (query an API, do a calculation, read a file).
- Memory: the history of messages and the results of each action.
- Execution: someone runs the tool and returns the output to the model. That someone is your code.
From chatbot to agent, in Python
- Narrow down the task. "How many working days are left until the end of the month" works; "manage my company" doesn't.
- Write the tools as normal functions:
def working_days(until: str) -> int. - Send the model the request and the tool catalog, and ask for JSON output:
{"action": ..., "args": ...}. - Execute the action, add the result as a new message, and repeat.
- Cut off at 8 iterations. Infinite loops cost money and are tedious.
while steps < 8:
r = llm(messages, tools=tools)
if r.type == "final":
return r.text
messages.append(execute(r.action, r.args))
steps += 1
What it really costs
Memory and error handling. An agent that doesn't verify the output of its tool hallucinates very confidently. Frameworks like Claude Code, OpenCode, or Hermes already bring that scaffolding, but understanding the loop prevents treating the agent as a black box and helps you know why it gets stuck.
Start with a small task, two tools, and a willingness to watch the console. If you prefer a guided setup, at Clasesdeprogramacion we build it step by step in Python with Stanislav Vakaruk, PhD in AI: bring a real task and we'll leave with a working agent.