Appearance
What Makes an Agent
Ask ten people what an "AI agent" is and you'll get ten answers, and at least half of them will just be describing a chatbot with better branding. That confusion isn't harmless, if you don't know what actually makes something an agent, you'll spend real engineering effort building a fancier chat interface when what you needed was a system that could act on its own. This page draws the line precisely, because everything else in this course sits on the far side of it.

What you'll learn
- The one mechanical feature that separates an agent from a chatbot: the loop
- Why "agent" isn't a spectrum from chatbots to something fancier, it's a different shape of system
- The smallest possible agent you can build, in about twenty lines of code
The problem: everyone calls everything an agent
A chatbot takes your message, generates a response, and stops. It doesn't check whether its answer was right. It can't go look something up unless you paste the information in yourself. It doesn't retry. When ChatGPT tells you the capital of a country or drafts an email for you, that's the entire transaction, one input, one output, done. This is genuinely useful, and it's also the entire reason so much AI marketing calls things "agents" that are really just chat with a system prompt.
An agent is different in one specific, mechanical way: it runs a loop. It takes an action, observes what happened, decides what to do next based on that observation, and keeps going until the task is actually finished, not until it's produced a response, but until the goal is met. That loop is the whole idea. Everything else in this course, tools, memory, multi-agent coordination, deployment, is infrastructure in service of making that loop reliable enough to trust.
Chatbot, workflow, or agent, and why the distinction matters
It helps to place "agent" between two things people often confuse it with:
| Kind of system | What decides what happens next | Good for | Bad for |
|---|---|---|---|
| Chatbot | You do, every single turn | Answering questions, drafting text, one-shot help | Anything that needs more than one step to complete |
| Fixed workflow (e.g. a no-code automation) | A human designed the steps in advance | Predictable, repetitive processes | Tasks where the right next step depends on what just happened |
| Agent | The model decides, based on what it just observed | Tasks with an uncertain number of steps, or steps that depend on results you can't predict in advance | Anything where you need a guarantee of exactly what will happen, every time |
A workflow tool that sends an email when a form is submitted isn't an agent, the sequence was fixed by whoever built it. An agent that reads a support ticket, decides whether it needs to check a database, checks it if so, and only then decides how to respond, is one, because the model, not a human designer, chose which branch to take. This is also why "agent" isn't automatically the right tool for every job: if you can draw the flowchart in advance and it never changes, a fixed workflow is simpler, cheaper, and more predictable than an agent. Reach for an agent when the number and order of steps genuinely can't be known ahead of time.
Build it: the smallest real agent loop
Strip away every framework and this is what an agent actually is, a while loop, a model call, and a way to take action based on what the model decides:
python
from anthropic import Anthropic
client = Anthropic()
def run_agent(task: str, max_steps: int = 10) -> str:
messages = [{"role": "user", "content": task}]
for step in range(max_steps):
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
tools=[READ_FILE_TOOL, RUN_COMMAND_TOOL], # what it's allowed to do
messages=messages,
)
if response.stop_reason != "tool_use":
# The model decided it's done, this is the loop's exit condition
return response.content[0].text
# The model wants to act. Do it, then feed the result back in.
messages.append({"role": "assistant", "content": response.content})
tool_result = execute_tool_call(response.content)
messages.append({"role": "user", "content": tool_result})
return "Stopped: reached max_steps without finishing."Compare that to a chatbot call, which is just the first iteration of this loop with nowhere to go afterward:
python
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
messages=[{"role": "user", "content": task}],
)
return response.content[0].text # done, no matter what the answer wasSame model, same API. The difference is entirely in whether there's a loop that lets the model observe its own results and decide to keep going. That's the whole trick, and it's also why an agent inherits every reliability problem a chatbot has, plus a new one: it can now confidently take the wrong action multiple times in a row before you notice, instead of just giving a single wrong answer. Day 4 of this course is built entirely around that risk.
What goes wrong
| Mistake | How you notice it | The fix |
|---|---|---|
No exit condition beyond max_steps | Agent runs to the step limit on every task, even simple ones, burning tokens for no reason | Give the model a clear way to signal "done" (a specific tool call, or a stop condition it checks for) rather than relying only on a step ceiling |
| Treating a single API call with a system prompt as "an agent" | The system never takes more than one action, no matter what marketing calls it | If there's no loop and no ability to observe-and-decide again, it's a chatbot with a job title |
| Using an agent where a fixed workflow would do | Unpredictable behavior on a task that actually has a fixed, known sequence of steps | If you can draw the flowchart in advance and it never changes, build the flowchart, not an agent |
| No limit on the loop at all | A confused agent loops indefinitely, burning API cost | Always cap max_steps, and log every iteration so you can see where it got stuck |
Confirm it worked
Give the minimal loop above a task that genuinely requires more than one step, something a single chatbot response couldn't complete, and watch it actually take more than one turn:
python
result = run_agent("Check whether the file config.yaml exists, and if it does, tell me its size.")If the model calls a tool to check for the file, receives the result, and then responds with the size (rather than guessing), you've watched the loop do the one thing that makes it an agent instead of a chatbot: act, observe, decide, and only then answer.
Next: Vibe Coding with AI CLIs , the tool you'll actually use to build agents like this one, day to day.