Module 1 · Foundations of Agentic AI · scripted

The Agent Loop

30 minoutcomes: agent-architectures

The simplest part of the whole story

Now we arrive at the thing you hear about the most: the agent loop. And here is the truth: the agent loop is the simplest concept in this entire course. Everything conversational we have built — trajectories, tools, protocols, shadows, framing — is where the real design and innovation live. The code for an agent is remarkably simple, and can generally be thought of as a single loop.

The agent loop

Starting the play

Something starts the loop — an event. It could be a user typing a request. Or something happening in the external world: an email arriving, a new help ticket showing up, a camera capturing a photo that needs analysis.

That event is turned into the initial conversation — the start of the play the agent is going to act in:

The initial conversation

system message:the agent's role in the play, and its rules
tool definitions:what it may ask the computer to do
first user msg:the task — from a person, or from an event translated as if a user reported it: "An email has arrived. Contents: … Draft a reply."

Then the prompt goes to the LLM, it chooses a first tool through function calling, we detect which tool it chose, cause that action to happen on the computer, translate the result into text, and append it as a user message. That is one iteration. Not done yet? Loop back around: the LLM now sees a conversation whose last message is the tool result — a user message sitting at the bottom, prompting (no pun intended) its next decision.

Watch it run

Example 1 · The help-desk ticket
user

Event — new ticket #4412 from Kari L.:

"The lab printer on floor 3 says ERROR E-341 and won't print my consent forms."

You have the following tools available for use:


  1. kb_search( query ) — search the support knowledge base
  2. printer_status( id ) — current status and error history
  3. reply( ticket, text ) — answer the requester
  4. escalate( ticket, team, note ) — hand off to another team
  5. end( summary ) — finish, reporting what was done

Task: resolve or route the ticket.

assistant
⟨tool_use⟩
kb_search(query = "printer ERROR E-341")
user
⟨tool_result⟩
1 match: "E-341 = fuser overheat. Power off 10 min. If recurring,
needs part FK-3170 — facilities handles replacement."
assistant
⟨tool_use⟩
printer_status(id = "PRT-3F")
user
⟨tool_result⟩
Status: ERROR E-341. Error count this month: 4.
NoteLook at the bottom of the conversation after each result: a user message, prompting the next decision. Four errors this month changed that decision — this isn't a power-cycle case anymore.
assistant
⟨tool_use⟩
reply(
  ticket = 4412,
  text   = "Known issue: the fuser is overheating. Short term: power
            the printer off for 10 minutes. Because this is the 4th
            occurrence this month, I've escalated for a part
            replacement. Nearest working printer: floor 2 south."
)
assistant
⟨tool_use⟩
escalate(
  ticket = 4412,
  team   = "facilities",
  note   = "PRT-3F recurring E-341, 4x this month — needs FK-3170
            fuser kit per KB."
)
assistant
⟨tool_use⟩
end(summary = "Ticket 4412 answered with workaround and escalated to
facilities for recurring fuser fault.")
Example 2 · The camera event
user

Event — loading-dock camera motion alert at 23:41.

You have the following tools available for use:


  1. describe_image( id ) — describe what a camera frame shows
  2. check_schedule( date ) — bookings for the loading bays
  3. log( entry ) — append to the site log
  4. alert( oncall, text ) — wake the on-call staff member
  5. end( summary ) — finish, reporting what was done

Task: assess and log; alert a human only if warranted.

assistant
⟨tool_use⟩
describe_image(id = "dock-2341")
user
⟨tool_result⟩
A box truck reversed to bay 2, hazard lights on. One person at the
tailgate moving pallets. Bay door open. High-visibility vest.
assistant
⟨tool_use⟩
check_schedule(date = "2026-08-24")
user
⟨tool_result⟩
Bay 2 booked 23:30–00:30: night delivery, Vestland Foods, truck
NF-71212.
NoteTwo tool calls, and the trajectory has already bent twice: the image description made it "a delivery, probably" and the schedule made it "a booked delivery, certainly." No alert needed — the conversation now knows it.
assistant
⟨tool_use⟩
log(entry = "23:41 bay 2 motion = scheduled Vestland Foods delivery,
matches booking. No action.")
assistant
⟨tool_use⟩
end(summary = "Motion alert resolved as scheduled delivery; logged,
no human alerted.")

And notice: the email agent from The Conversation with the Computer was exactly this loop too — you have now seen it three times in three domains. Same machine, different play.

When does the loop end?

Termination is a design decision, and there are several strategies — usually used in combination:

Termination strategies

An explicit end toolthe LLM calls end(summary=…) when it believes it's done — with a message describing what it did
Text means done"choose a function, or answer in plain text — if you write text, we stop"
Max iterationsa hard cap: at most N times around the loop, then stop and report failure — the LLM could otherwise run forever
Budgetscount input/output tokens, or their cost, and stop at a ceiling
Errorsa tool throws, something breaks — stop, or repair; but never ignore

The soft strategies (1–2) let the agent decide. The hard constraints (3–5) protect you when it decides badly. Production agents carry both.

The trajectory, revisited

Look at what the loop is, in the terms of this course: the prompt grows as tools are called and results come back — the self-evolving conversation, live. When we construct that initial conversation, we are constructing the trajectory of the agent through the loop. Each iteration is one move along it, with the LLM providing the move.

The conversation grows around the loop

The code is a footnote

Here is the entire mechanism, boiled down as far as it will go:

The whole idea

conversation = system + tools + task

repeat:
    action = LLM(conversation)          # function calling
    if action is "end": stop
    result = run(action)                # the computer acts
    conversation += action + result     # append; never rewrite

In Python, with the details honest:

Python

def agent(system, tools, task, max_steps=8):
    conversation = init(system, tools, task)   # the initial play
    for step in range(max_steps):              # hard cap: strategy 3
        action = llm(conversation, tools)      # function calling
        if action.name == "end":               # soft stop: strategy 1
            return action.args["summary"]
        result = execute(action)               # the computer acts
        conversation.append(action)            # its move…
        conversation.append(user(result))      # …and the world's reply
    return "stopped: step limit reached"       # failed, but safely

JavaScript

async function agent(system, tools, task, maxSteps = 8) {
  const conversation = init(system, tools, task); // the initial play
  for (let step = 0; step < maxSteps; step++) {   // hard cap
    const action = await llm(conversation, tools); // function calling
    if (action.name === "end") return action.args.summary;
    const result = await execute(action);          // the computer acts
    conversation.push(action, userMessage(result)); // append, never rewrite
  }
  return "stopped: step limit reached";
}

That's it. That is the process. Everything difficult about agents lives in what we've spent the whole day on: what goes into that conversation, and how it evolves.

You will never write this loop by hand

One more thing, and it changes how you should spend your effort: LLMs — and agents — are extraordinarily good at writing agent-loop code. So in this course we focus solely on the conversation. When we actually need a loop of our own, we ask the LLM to build it. And in the spirit of the course, the prompt that gets it built is a flipped interaction:

Prompt 1 · The loop builder

I want you to build an agent loop for me. Interview me first: ask me one question at a time until you have what you need, covering at least — what the agent's purpose and goal is; what tools it needs, with their parameters and what they return; what language I want it in and whether I want any frameworks or none; how it should decide it is done; and what hard limits (steps, tokens, cost) it must respect. Then generate the complete, runnable, commented code, and nothing else.

Prompt 2 · The walkthrough

Here is the agent code you generated. Now walk me through running it the way a guide walks a beginner through a recipe: one step at a time. Tell me exactly one thing to do, wait for me to report what happened, and use my report to decide the next step — including fixing anything that goes wrong along the way.

Prompt 2 is the cooking agent, pointed at your own code: you are the hands, eyes, and ears; the LLM steers.

Your turn

Run both prompts. Let the interview design an agent for a task from your research, generate the loop in the language of your choice, and have the LLM walk you through executing it — one step at a time. Bring the transcript: where did the interview ask something you hadn't considered?