An AI agent is a language model put in a loop. That is the whole idea, and it is worth taking literally, because almost every hard problem in production agents comes from the loop and not from the model.
The model looks at a goal and the history so far, and it decides one action. An orchestrator, ordinary code you write, runs that action as a tool, takes the result, and hands it back to the model. The model looks again and decides the next action. This repeats until the model declares the goal met, or until a budget stops it. The model never runs anything itself. It only proposes; the orchestrator executes and owns the loop, the budget, and the stop condition.

That division is the most important thing to see before anything else. Because the orchestrator owns execution, an agent is not a black box you can only hope behaves. It is an engineering artifact with seams you can reach into: you decide how many steps it may take, which tools it may call, what happens when a tool errors, and whether a proposed action is even allowed to run. Every reliability lever in this lesson lives at one of those seams.
Notice too that the model is stochastic. Ask it the same thing twice and you may get two different actions. That is fine for a chatbot, where a human reads the answer and moves on. It is a much bigger deal in a loop, where the output of one step becomes the input to the next, and a single wrong action can send the whole run somewhere useless. The first hard problem is the one that surprises almost everyone the first time they ship an agent: a system that was magical in the demo becomes unusable on real work, for a reason that has nothing to do with how smart the model is.
The number of steps a task takes is the strongest predictor of whether an agent finishes it correctly, and it is the one thing a demo quietly controls for you.
Count the steps in a typical demo: two, maybe three, on a clean chosen example. Count the steps in real work: ten, twenty, fifty, against messy inputs and tools that sometimes fail. Same agent, same model, same prompt. The only thing that changed is how many actions had to go right in a row.

The demo is not dishonest on purpose. The presenter picks a task they already know works, feeds it clean input, and the tools happen to respond on the first try. That is a three-step happy path, and three steps of a good model almost always succeed. The pilot then hands the same agent a real ticket, with an ambiguous request, a missing field, a stale record, and a tool that rate-limits under load. Now it is twenty steps, and twenty steps is a different universe.
You cannot prompt your way out of this, because it is not a wording problem. Rewriting the system prompt does not change the number of actions the task requires, and the number of actions is what is killing you. That single variable, length, is doing almost all the work in whether the agent succeeds, and almost nobody instruments it. The next slide is the arithmetic that makes length so brutal.
Because the steps are a chain, and a chain multiplies.
Think about what it takes for a whole task to succeed: every step in it has to succeed. If the steps are roughly independent, the probability that all of them succeed is the product of their individual success rates, not the average. Multiplication punishes length in a way intuition does not expect, because we are used to reasoning about averages, and averages hide the collapse.

Put numbers on it. Suppose each step succeeds 95 percent of the time, which sounds excellent. A five step task succeeds about 77 percent of the time. A twenty step task succeeds about 36 percent of the time. A fifty step task succeeds under 8 percent of the time. The per-step number never changed. Only the length did, and the curve falls off a cliff.
The same table also shows the other exit. Getting each step from 95 percent to 99 percent lifts the twenty step task from 36 percent to 82 percent, and getting to 99.9 percent lifts it to 98 percent. So there are exactly two ways down the curve: fewer steps, or a higher per-step rate. Hold that, because it is the whole strategy of the lesson.

Read the heatmap as a control panel. Where you land is decided far more by the column you sit in, the length, than most teams believe. A near-perfect 99.9 percent step over 50 steps still beats a merely-great 95 percent step over just 10 steps. Run the arithmetic yourself and watch the collapse.
The lesson in that table is blunt. A per-step reliability that feels great is not good enough once a task is long, and the fastest way to a reliable agent is usually to make the task shorter, not the model smarter.
Before you can raise per-step reliability, you have to know what "a step failed" even means, because the 95 percent is an average over a pile of very different failures, and they do not all get fixed the same way.

Sort them by root cause. A transient tool error, a 429 or a 503 or a socket timeout, is not the model's fault at all; the world simply blinked, and the same call would have worked a moment later. That failure belongs to retries. The other four are the model: it emitted invalid JSON, or it picked the wrong tool, or it invented an order number that never existed, or it forgot a constraint stated fifteen steps ago because the transcript outgrew what it can track. Those belong to validation, tighter tool schemas, verification, and shortening the task, in that rough order.
This sorting matters because the wrong fix is worse than no fix. Retrying a permanent error, a 400 or a schema violation, wastes budget and can double a side effect, and it will never succeed no matter how many times you try. Adding a verification pass to a step that only ever fails transiently spends tokens catching a failure that a cheap retry would have erased. Notice what is not on the list: "use a smarter model." A bigger model nudges the four model failure modes down a little, but it is the most expensive lever you have, and it rarely touches the transient failures at all. Match the fix to the root, and most of your per-step reliability comes from cheap, boring engineering.
Zoom all the way into a single turn of the loop, because a step is not one call. It is a little pipeline, and inside it there are two specific places you can intervene to push that step toward the 99.9 percent that survives a long chain.

The first intervention is validation. When the model proposes an action, the orchestrator checks it against the tool's schema before anything runs. If the arguments are malformed or a required field is missing, the action is rejected right there and handed back to the model to try again. A caught malformed action never becomes a corrupted database row or a bad API write; it is a non-event. This is the cheapest reliability you will ever buy, because you already have the schema.
The second intervention is recovery. When the tool returns a transient 503, the orchestrator does not surface it to the model and it does not abort the run. It retries, after a short backoff, under the same key, and the second attempt succeeds. From the task's point of view the blink never happened. It never entered the success math at all.
The point of tracing one step this closely is that "raise per-step reliability" stops being a vague instruction and becomes two concrete pieces of orchestrator code: a validation gate on the way in, and a bounded retry on the way out. Neither one is model work. Both are the ordinary plumbing of a reliable system, and both live at seams the orchestrator already owns.
Retries are the lever for transient failures, but a naive retry is itself a bug in two ways, and you have to close both before a retry is safe.
The first way is retrying the wrong thing. Put a classifier between the failure and the response, so a transient error goes down the retry branch and a permanent error goes down the fail-fast branch. Retrying a 429 or a timeout is a free save; retrying a 400 or a 404 burns budget on something that can never succeed. And there must always be a third branch, the hard stop, so a step that keeps failing does not loop forever: cap the retries, cap the total wall-clock, and when the cap is hit, halt, checkpoint the state, and raise for a human or a fallback.

The second way a retry becomes a bug is more subtle, and it is the reason retries and are always taught together. A retry replays a side effect. If the first attempt actually succeeded and only the response was lost on the way back, a naive retry runs the effect a second time. For a read, that is harmless. For a charge, an email, or a row insert, you just did the thing twice.

The fix is a contract. Derive one stable key per logical action, an order id or a hash of the arguments, send it on every attempt, and let the tool or a dedup store collapse repeats so the effect runs at most once. Stripe, SQS, and most payment and queue APIs expose exactly this header for exactly this reason. Reads are naturally idempotent, so retry them freely; it is the writes where a key is the difference between a save and a double-charge. See how a bounded retry over an idempotent step changes the arithmetic.
There is no single fix. There is a stack of four levers, and a real system uses all of them. The first two change the arithmetic itself; the last two catch what the arithmetic still lets through.
The highest-leverage move is to shorten the task, because the step count is the exponent. Decompose one long goal into smaller bounded ones with a verified checkpoint between them, and a failure is caught and retried at the boundary instead of sinking the whole run.

That figure is the crux of decomposition, and it is worth being precise about why it works, because "0.95 to the tenth twice" is literally the same number as "0.95 to the twentieth once." The win is not the split by itself. The win is the verified, recoverable boundary you insert at the seam: the checkpoint confirms stage one is correct before stage two starts, and a failed stage retries in isolation instead of propagating a quiet error into the next ten steps. That is what turns 36 percent into roughly 70 percent without touching the model at all.

Read the stack top to bottom, because that is the spending order. Shortening the task and hardening each step change the math for free. Verification and recovery cost tokens and , so aim them at the steps that are risky or irreversible rather than firing them on every step. And a bigger model sits below all four, because it is the priciest lever and the one that moves the number least per dollar. Reach for it last, once the cheap arithmetic is exhausted, not first.
Underneath all four levers is a single change in how you think about the thing you are building, and once it clicks, the levers stop feeling like a checklist and start feeling obvious.
The mindset that fails treats an agent like a function that returns the right answer. You call it, you trust the output, you move on. The mindset that ships treats it like an unreliable distributed system, because that is exactly what it is: a sequence of calls over a network to a component that is stochastic and sometimes wrong.

You already know how to build reliable systems out of unreliable parts, because that is most of backend engineering. You use retries, verification, bounded scope, idempotency, and recovery. An agent needs exactly the same discipline, and each lesson that follows in this chapter takes one of those tools and shows how it applies to the loop: the contract that makes schemas hard to misuse, the durable-execution runtime that makes long runs recoverable, the evaluation harness that measures per-step reliability so you can improve it.
It is also why, later, you will see the advice to constrain an agent rather than maximize its autonomy. A shorter, narrower agent is not a weaker product. It is a more reliable one, and on a long task, reliability is what makes it shippable at all. The team that ships is not the one with the smartest model. It is the one that treated the loop like the distributed system it is.
5 questions - Score 80% to pass
Each step of an agent succeeds 95 percent of the time. Roughly how often does a 20-step task succeed end to end?
Why does a short demo make an agent look far more reliable than it is?
Which lever most directly attacks the compounding problem?
Why must a retried step be idempotent before you retry it?
What is the mindset the lesson recommends for building agents?