The Agent Loop, From Scratch
0/7 lessons completed
Overview

Chapter 1: How the loop works · Lesson 1 of 7 · 6 min read

The loop in 30 lines

An agent is a while-loop around a model call. Here is the whole thing, with nothing hidden.

Every AI agent, no matter which framework it uses, runs the same loop:

  1. Send the conversation so far to the model.
  2. If the model asks to use a tool, run it and add the result to the conversation.
  3. If it doesn't, it has answered. Stop.

That's it. Everything else (planning, memory, sub-agents, guardrails) is something bolted onto this loop.

The agent loop: the model decides whether it wants a tool. If yes, your code runs it and adds the result to messages, and the model is called again. If no, that's the answer and the loop ends.
The loop every agent runs. The messages list in the middle is all the model knows.

The whole thing

Here it is in plain Python. call_model stands for whichever model API you use; it takes a list of messages and returns the model's reply.

def run_agent(task, tools, call_model):
    messages = [{"role": "user", "content": task}]

    while True:
        reply = call_model(messages, tools=tools)
        messages.append(reply)

        if not reply.tool_calls:          # no tool requested: this is the answer
            return reply.content

        for call in reply.tool_calls:     # the model asked for one or more tools
            result = tools[call.name](**call.arguments)
            messages.append({
                "role": "tool",
                "tool_call_id": call.id,
                "content": str(result),
            })

Read it twice. Notice three things:

  • The model is stateless. It remembers nothing between calls. The messages list is its memory, and you resend all of it every time.
  • The model decides when to stop, by simply not asking for a tool. You are trusting it to know when it's done.
  • There is no brake. while True will happily run forever if the model keeps asking for tools.
The same loop with three warnings: messages grows forever, the model decides when it's done, and while True has no brake.
Three bugs hiding in 20 lines. The rest of the course fixes them one by one.

The last two are where real agents go wrong, and lessons 3 and 4 are about fixing them.

Walking through one run

Say the task is "What's 17% of the price of order #4411?" and the agent has one tool, get_order.

Step Who What gets added to messages
1 you user: the task
2 model assistant: "call get_order(id=4411)"
3 you tool: {"price": 250}
4 model assistant: "17% of $250 is $42.50." (no tool call, loop ends)

Two model calls, one tool call. The model never touched your database. It asked, and your code did the work.

Mental model: the model is a very smart colleague on the phone. They can't see your screen. They can only tell you what to do, and they only know what you read back to them.

The model asks for get_order(id=4411) over the phone. Your code, which has the database, reads back {"price": 250}.

Why frameworks feel magic

Open the source of any agent framework and you'll find this loop, wrapped in classes, retries, streaming and logging. Once you can see it, the framework stops being a black box: "max iterations" is a brake on while True, "memory" is something that edits messages, and "tool schema" describes tools to the model.

In the next lesson we look at the contract between the model and your tools, because that's where most beginner bugs live.