A loop with no stop condition is a bill with no ceiling.
Every article stops at "an agent is a loop, add a circuit breaker". That is tier one. This goes three tiers deep, and the interesting part is not the definition, it is the judgment: which number, whose approval, what happens on a crash.
Tier 1
Basics
The loop and its two deaths
Tier 2
Intermediate
The guards, and the judgment they need
Tier 3
Advanced
Utilize the full potential
?New to this? 30-second primer▾
- Agent
- A model in a loop that can take actions, look at the result, and decide what to do next, instead of answering in one shot.
- Tool call
- The model asking your code to do something real (search, refund, transfer) and getting the result back to reason over.
- Iteration
- One turn of the loop: one think, one action, one observation. Agents run many before they finish.
Want all ten words first? Read the beginner primer →
The loop, and the two ways it dies
An agent is not magic. It is a four-step wheel: think what to do, act by calling a tool, observe the result, decide whether to stop. It dies in exactly two ways, and you can see both below. Toggle reflection off to watch it spin, on to watch it adapt.
Reflection is OFF. Press start and step the loop. Watch it repeat the failure.
Death 1: it never stops
No stop condition, or a goal it can never satisfy. The loop turns until a rate limit or an invoice stops it for you.
Death 2: it never progresses
It retries the identical failing action because nothing made it reflect. Busy, not progressing.
That is the article-level understanding, and it is where almost every other explanation ends. Here is where it stops being enough.
"Add a circuit breaker" is the easy part. At what value?
Everyone tells you to cap the loop. Nobody tells you the number, because there is no safe one. Set a single global ceiling for four real tasks below and watch it fail: loose enough to let a legitimate 22-step reconciliation finish is loose enough to let every runaway burn right up to that ceiling.
One global ceiling, four real tasks. Find a number that is safe for all of them.
Your ceiling murdered Reconcile a statement. That is real work: a 22-step reconciliation is not a bug. To make the runaway cheap, you strangled the legitimate deep task. This is the trap of one global number.
The senior move (what the dial cannot do)
Stop looking for one number. Give each task class its own budget (a balance check gets 5 steps, a reconciliation gets 40), and add a progress check that kills on no new information regardless of count. That catches the runaway in 2 idle steps without ever touching legitimate deep work. A ceiling guards cost; a progress check guards sense.
The progress check does what the ceiling cannot
A ceiling counts. A progress check asks "did this turn add anything?" and halts a runaway in two idle steps without touching a legitimate long task. You need both: one guards cost, the other guards sense.
Reflection theater
Adding a "reflect" step is not enough if the reflection does not change the next action. A loop that thinks "that failed, let me try again" and then tries the identical thing has reflected on paper and learned nothing.
Utilize the full potential
This is the tier the articles skip. A production loop in a bank is not a while-loop, it is a durable, interruptible, auditable process that sometimes pauses for a human and sometimes runs its children in parallel. Operate one below: it pauses for approval before it moves money, and a crash proves why durability is not optional.
A loop that touches money must pause for a human. Start the request and step to the approval gate.
Sub-agent loops, joined
A supervisor loop spawns worker loops (one per document, per account, per region) and waits on them. The hard part is not the fan-out, it is the join: partial failure. Three of five workers finish, one errors, one hangs.
In a bank → A bank reconciling 12 accounts in parallel needs a defined answer for "one account timed out": return the eleven, flag the twelfth, never block the whole request on the slowest worker.
Confidence-aware early stopping
A hard step ceiling is blunt. The sharper rule stops when the marginal information from another turn is worth less than the tokens it costs. The loop ends because it is done learning, not because it hit a wall.
In a bank → A fraud-review agent should stop the moment its confidence crosses the decision threshold, not burn ten more tool calls gathering evidence that cannot change the outcome.
Resumable, auditable runs
Long agents crash, get deployed over, and outlive a single request. Checkpointing each step means a crash resumes mid-run instead of restarting and re-paying, and the checkpoint trail is itself the audit record of what the agent did and when.
In a bank → A regulator asks "why did the agent decline this in March". A durable run has every step, tool call, and input preserved. A non-durable one has a log line and a shrug.
The loop as a trace
Every iteration is a span: the thought, the tool call, the observation, the cost. Without it, a loop that quietly took 40 turns instead of 4 looks identical to a healthy one on a latency chart.
In a bank → This is where loop engineering meets the observability lesson: you cannot tune a loop you cannot see, and you cannot bill a tenant for an agent whose turns you never counted.
The advanced patterns in LangGraph, and by hand
Your stack runs agents on LangGraph. Interrupts, checkpoints, and idempotency are the concepts; the graph is where you spell them.
The concept
Loop until done or a limit trips, and on each turn check for progress. The two guards, a ceiling and a progress check, do different jobs: one guards cost, the other guards sense.
steps = 0
while not done and steps < MAX_STEPS: # guards cost
thought = model.think(state)
result = run_tool(thought.action)
state = observe(state, result)
if no_new_information(state): # guards sense
state = reflect(state, result) # change the plan, or halt
done = goal_met(state)
steps += 1The point: the stop condition, the progress check, the interrupt, and the idempotency key are the concept. LangGraph, Temporal, or a hand-written loop are just where you put them.
The same question, three depths of answer
"How do you keep an agent loop safe in production?" The depth of your answer is the level they hire you at.
Add a maximum number of steps so it cannot run forever.
A step-and-cost ceiling per task class, plus a progress check that halts on no new information, plus reflection that actually changes the next action. One global number is unsafe because a runaway and a deep task look identical by count.
All of that, made durable and interruptible: checkpoint every step so a crash resumes instead of re-paying, interrupt before high-stakes actions for human approval, make side effects idempotent so a resume cannot double-send, and emit each turn as a span so the loop is observable and billable. Safety is a property of the harness around the loop, not a number inside it.
On your real stack this week
Add interrupt_before to one money-moving node, and a checkpointer behind it.
Pick the most autonomous LangGraph agent you run, add a human interrupt before its highest-stakes tool, and a checkpointer so the pause survives a restart. Then kill the process mid-run and confirm it resumes instead of restarting. It is the cheapest incident you will ever prevent.