A chatbot answers in a single pass: your words in, its words out, done. An agent is a different animal — it persists. It reads the situation, does something, looks at what happened, and goes around again until the job is finished or a limit says stop. Strip away the mystique and the architecture is almost embarrassingly small: one language model, a handful of tools, and a loop.
The 2026 way of saying it — now that "loop engineering" has become a discipline of its own — is blunt: you're not the model; you're the loop. The model is rented. The loop — what it's allowed to do, when it stops, how it recovers — is where all the engineering actually lives.
So let's build the mystique back up from parts. Our lab rat: a support agent for Peak Bean Coffee Co. (yes, the same imaginary company as essay № 1). A customer named Jamie has just written in: “My espresso machine arrived leaking. I want my money back. — order #PB-2417.”
This is the entire API request an "agent" sends. Flip between turn 1 and turn 3 and watch what changes.
§1Around the loop, one click at a time
Here is Jamie's ticket, run through the agent — every model thought, every tool call, every result, exactly as the loop sees them. Nothing is skipped: you'll watch it consult the policy index (retrieval! — inside an agent), hit a real API error, and recover without human help.
Press ⏭ step (or ▶ run) and watch both panels: the conversation the model sees, and where we are in the loop.
lookup_order search_policy issue_refund send_reply§2The loop eats its own tail
Exhibit A showed that nothing is remembered for free — history is re-sent every turn. Exhibit B quietly demonstrated the consequence: the context ticker only ever goes up. Run a long session and the loop starts drowning in its own past: old tool dumps crowd out the goal, every turn costs more than the last, and eventually you hit the window limit mid-job.
Jamie's finished ticket is loaded below. Drag the slider to pile more tickets into the same session — then click any block to compact it (summarize-and-shrink), the way production agents survive.
§3What separates a demo from production
Exhibit B's agent lived in a kind world: one error, one clean retry. Production is meaner — flaky APIs, rate limits, tools that time out at 4 a.m. The difference between an agent that ships and an agent that embarrasses you is rarely the model. It's two numbers you choose: how many times to retry, and when to stop trying.
Set the world's cruelty and the loop's guardrails, then run 30 tickets. Same knobs → same outcome (seeded), so experiment away.
The loop engineer's checklist
- a goal the loop can verify, not vibe about
- tools with crisp descriptions (the model chooses by reading them)
- structured observation of every result — errors included
- termination: step caps, token budgets, no-progress detection
- recovery that adds information, never blind repetition
§4Where loops go feral
Every production agent horror story is one of these three, and you've now met them all:
The doom loop
Retrying the same failing call with the same inputs, forever. Recovery must change something — Exhibit B's agent added the missing field; that's what made its retry legitimate.
→ uncap Exhibit D and watchContext bloat
Fifty turns in, the goal is a needle in a haystack of stale tool dumps. The model starts answering the haystack. Compaction isn't optional hygiene — it's how long sessions stay sane.
→ you fixed this in Exhibit CThe wrong tool
Vague tool descriptions make the model guess — search_policy vs lookup_order for "where's my order?" is obvious to you, not to a model reading two sloppy one-liners. Schemas are UX for machines.
§5What to keep
- An agent = model + tools + loop. The loop is the product; the model is rented.
- The API is stateless — you re-pay for every token of history, every turn. Memory is an engineering choice, not a feature.
- Errors are just observations. Good agents recover by adding information; bad ones repeat themselves.
- Termination is designed, never emergent: step caps, budgets, verifiable goals.
If you stepped through Exhibit B, you've now watched every component the frameworks wrap in acronyms: the reasoning turn, tool dispatch, observation, recovery, exit. The rest is hardening — the part I do for clients, and the part that makes the difference between 25% and 85% of tickets actually resolved.
← previously in this series: № 1 · How RAG actually finds the answer