How AI Agents WorkCourse map

Chapter 1 · The core loop

The agent loop

Every agent repeats one cycle: build the context, call the model, do what it asked, record the result, and decide whether to go again.

Observe, decide, act, repeat

Robots and control systems have long been described by one cycle: observe the world, decide what to do, act, then look at the result. LLM agents run the same cycle.

Observe Decide Act Observe the result Repeat

Here is what each word means in an agent:

Only the decide step happens inside the model. Some models write out their reasoning before they decide, but that reasoning is part of the same reply. Between calls, nothing is thinking. Your code is just running.

The same loop in engineering terms

Framework docs use many names for the same five pieces. This table says what each one actually is.

The five pieces of the loop
PieceWhere it happensWhat it is
Model callThe provider's APIMessages and tool descriptions go in, and a reply comes out.
Choosing an actionThe model's replyOne or more tool requests with arguments, or a final answer
Running the toolYour codeCheck the arguments and the rules, run the function, and capture the output or the error
ObservationYour code's stateA message with the tool's result, tagged with the request's id, added to the history
StoppingYour codeThe rules that end the loop

Step through a run

The widget below lets you step through three runs, one step at a time. At each step, watch who is acting, what your code remembers, and what the model sees. Notice that the model's view goes empty between calls, because the model is not running then.

Interactive widget. Without JavaScript, here is the run in words. The user asks Patch to fix a failing auth test. Your code builds the context and calls the model. The model asks to run the tests. Your code checks the request, runs the tests, and adds the failing output to the history. On the next call your code sends everything again, and the model asks to read auth/session.py. After an edit and a passing test run, the model replies without asking for a tool. Your code stops the loop and checks that the last test run passed.

Three things in the widget come up again later in the course:

How a run ends

Say the agent edits a file and replies, "Done, the test passes now." Should the run end? Usually yes, but only after your code checks that the test really passes. A good agent has several ways to stop, and you choose them on purpose:

Here is a sketch of those rules in code:

def should_stop(state, reply):
    if state.user_cancelled:             return "stopped by the user"
    if state.step >= state.max_steps:    return "step limit reached"
    if state.cost >= state.max_cost:     return "cost limit reached"
    if state.repeated_calls(window=3):   return "stuck: repeating itself"
    if not reply.tool_calls:                  # the model says it is done
        if state.success_check():             # confirm with evidence
            return "success"
        state.add_note("Check failed: " + state.check_output)
    return None                               # keep going

Notice the order. The hard limits come first, so a model that keeps saying "done" while the check fails still cannot run forever. Then a reply without a tool request leads to a check, not straight to success. That is the split from chapter 0: the model says it is done, your code stops, and a check confirms it.

In the sketch, success_check() is a few lines of your own code that look at the result itself, not at what the model said about it. For Patch, it runs the tests and passes only if they all pass. The model may say it is done several times in one run, and the check runs each time. When the check fails, your code adds the failure to the history, and the loop goes on. The model reads the failure, keeps working, and later says it is done again. Only a passing check ends the run as a success.

When no test can check the result

Many tasks have no test. Say you ask an agent to summarize a 40-page contract for a manager. Part of "good" is a judgment call, but you still need a check. So split "done" into smaller claims, and check each one with the cheapest thing that can judge it:

The rule is the same as for Patch. The model's "done" starts the check, and evidence ends the run. Only the checker changes. Chapter 16 compares code, model, and human checkers in more detail.

A few words, defined

Docs use these words loosely. In this course they mean:

Loop vocabulary
WordMeaning
TurnOne message from the user and everything the agent does until it replies
StepOne model call plus the tools it asked for
RunOne task, from the first step to the stop
SessionA saved conversation that can span several runs
TraceThe record of a run: every context, reply, tool call, and result

Example: why long runs get expensive

Your code sends the whole history on every call, so the total cost grows faster than the number of steps. Suppose the fixed part of the context is 3,000 tokens, and each step adds 1,000 more.

call 1 sends   3,000 tokens
call 2 sends   4,000 tokens
call 3 sends   5,000 tokens
...
call 20 sends 22,000 tokens

total over 20 calls:
  20 x 3,000 + 1,000 x (0 + 1 + ... + 19)
= 60,000 + 190,000
= 250,000 tokens

So twenty steps cost a quarter of a million tokens, and doubling the steps roughly quadruples the cost. Prompt caching makes the repeated part cheaper, but the context still fills up. Chapter 4 shows what to do about that.

Other shapes of the loop

The basic loop has a few common variations. They differ in who decides the next step and in how the work is split up. This is a first look; chapter 14 covers them in depth.

Simple loop

LLM tool LLM tool LLM

This is the loop from the widget, often called a ReAct loop. The model picks every step. Start here. It handles a wide range of tasks when the tools and the stopping rules are good.

Event-driven agent

Here the loop runs once for each event, such as a new chat message, a webhook, or a scheduled time. The agent loads its saved state, runs the loop, and saves the state again.

def on_event(event):
    state = store.load(event.thread_id)    # what we knew before
    state.add(event)
    run_loop(state)                        # the same loop as before
    store.save(state)                      # keep it for the next event

This fits agents that live for days and react to the world, such as support bots, inbox assistants, and scheduled jobs.

Graph or state machine

Here you draw the process as boxes and arrows. Some boxes call the model, and some arrows depend on a check or on the model's choice. For example: research, then draft, then review, then either revise or publish.

Research Draft Review Revise or publish?

This fits when you already know the shape of the process. You get a natural place to save progress after each box, and a natural place for a person to approve.

Planner and executor

One model call writes a plan, and a loop carries out the steps. If a step fails, the planner revises the plan. This helps with long tasks where steps depend on each other, or when a person should approve the plan first. Chapter 6 covers when planning helps.

Parent agent with subagents

One of the parent's tools starts a second agent loop with a fresh context. The second loop does a focused job and returns a short result. This helps with independent research in parallel, and with keeping messy exploration out of the parent's context. Chapter 7 covers the costs.

The shapes at a glance
ShapeWho picks the next stepUse it when
Simple loopThe modelYou are starting out. Most tasks.
Event-drivenEvents start runs, and the model picks steps inside each runThe agent reacts to the world over days
GraphYour graph, with the model choosing at some pointsYou know the process and need to audit it
Planner and executorA plan that the model revisesLong tasks with dependencies, or plans that need approval
SubagentsThe parent model, which hands off partsIndependent subtasks, or exploration that would flood the context

Who decides what happens next?

Each shape gives a different answer to this question. At one end, your code decides every step and the model fills in blanks: that is a workflow. At the other end, the model decides every step within a few hard limits: that is an open agent.

Put each decision where the knowledge is. If you know the process, write it in code or as a graph. If the next step depends on what the agent discovers, as when debugging, let the model choose. Hard limits such as budgets, permissions, and approvals always stay in your code.

Running example: Patch gets a loop

In version 1, Patch replaces you with a loop. It gets one tool, run_command, so it can run the tests itself, and it stops when the model replies without a tool request or after 30 steps. Patch can now try a fix, run the tests, read the failure, and try again. It can also repeat a bad idea until the step limit stops it.

- suggestion = model([system, user(paste)])          # v0: you were the loop
+ answer = run_agent(task, tools=[run_command], max_steps=30)   # v1

What goes wrong

The loop never ends

Why it happens
The tool results do not change what the model decides, so it repeats itself. Or nothing tells it what finished looks like.
How to spot it
Count the steps, and flag the same request with the same arguments appearing again.
What to do
Set step and cost limits, detect repeats, and state clearly what success looks like. Chapter 15 goes deeper.

The loop ends too early

Why it happens
The model says it is done before the work is finished, and your code treats that as success.
How to spot it
The success check fails right after the model says it is done. Without a check, a person finds the unfinished work later.
What to do
Run the check every time the model says it is done, and accept "done" only when it passes. Send the failure back to the model so it can keep working.

Costs grow quietly

Why it happens
Every call sends the whole history again, so long runs cost far more than short ones.
How to spot it
Track tokens for the whole run, not only for single calls.
What to do
Set budgets, trim large tool outputs, and shorten old history. Chapter 4 explains how.

You decide, AI builds

Decide yourself

  • How a run ends: what counts as success, how your code checks it, and which limits apply.
  • What happens when the model says it is done but the check fails.
  • Which shape of loop fits the task.

Delegate to AI

  • The loop itself, the step counter, and the timers.
  • Detecting repeated requests.
  • Counting tokens and cost, and logging every step.

Check yourself

What is the agent loop, in one sentence? (Q2)

Answer

A loop in your code that builds the context, calls the model, runs any tools the model asks for, adds the results to the history, and repeats until a stop rule fires.

The model replies without asking for a tool. What should a careful agent do?

  1. Report success, because the model is done
  2. Check the success criteria, and send the model back to work if they fail
  3. Call the model again with the same context
Answer

The reply only means the model thinks it is done. Your code decides whether to stop, and success needs evidence.

A run starts with 2,000 tokens of context and adds 500 tokens per step. Roughly how many tokens do 10 steps send in total?

Answer

10 x 2,000 + 500 x (0 + 1 + ... + 9) = 20,000 + 22,500 = 42,500 tokens. The last call alone sends 6,500.

Takeaways

Going deeper