Handbooks  /  Harness Engineering
Handbook~15 min readAgentsworked math + runnable code
The Harness Engineering Handbook

The loop that
makes an agent.

A model that only talks is a chatbot. Put it in a loop — let it act, see the result, and decide again — and it becomes an agent that gets things done. That loop is the harness, and most of what separates a reliable agent from a runaway one lives there, not in the model. The single most important line of code you'll write isn't the clever prompt; it's the stop condition. Without a hard bound, a stuck agent doesn't fail — it loops forever, quietly spending money. This handbook is about building the loop, and building the brakes.

01

Talk becomes action

An LLM by itself produces text. To make it do things — search, run code, edit files, call APIs — you wrap it in a program that reads its output, executes the action it asked for, and feeds the result back so it can decide what to do next. That wrapper is the agent harness, and the repeated cycle it runs is what turns a language model into an autonomous system.

The important shift in mindset is that the harness, not the model, is the system you're engineering. The model is one component inside a loop you control — you own the prompt assembly, the tool dispatch, the result parsing, the error handling, and the termination logic. A brilliant model in a sloppy harness is an unreliable agent; a modest model in a well-built harness can be a dependable one. And the part of the harness that matters most for safety and cost is the one people skip: the stop condition.

The one-sentence version

An agent is a model in a plan-act-observe loop; the harness owns that loop, and its most important job is a hard bound — max steps and a cost budget — so a stuck agent can never run forever.

02

Plan, act, observe

The core of every agent is one cycle, popularized by ReAct: plan → act → observe. The model reasons about the goal and picks an action (usually a tool call). The harness executes it — runs the tool, calls the API, edits the file. The result is fed back into the model's context. Then the loop repeats, the model choosing its next action from what it just observed, until it signals the task is complete.

One turn of the agent loop
PlanModel reasons and emits an action (a tool call).
ActHarness dispatches the tool and runs it.
ObserveResult is fed back into the model's context.
RepeatUntil the model says done — or a bound stops the loop.

What makes this powerful is the observe step: the model's next plan is grounded in the real result of its last action, not in speculation. That feedback is what lets an agent recover from a failed tool call, adjust to unexpected output, and chain steps toward a goal. But it's also where the danger hides — because the loop only ends when the model chooses to end it, and a model can fail to choose. That's the problem the harness must solve.

03

The hard stop

Here's the failure that catches every agent builder once: the model never decides it's finished. It retries a failing tool over and over, oscillates between two actions, or chases a goal it can't reach — and because the loop only exits when the model says "done," it doesn't. It just keeps going, step after step, spending tokens and money with nothing to show. An unbounded agent loop isn't a bug that crashes; it's a bug that runs your bill up.

The fix is non-negotiable: the harness enforces hard bounds that don't depend on the model's judgment. A maximum step count caps how many loop iterations can run. A cost (or token) budget caps how much can be spent. Whichever is hit first, the loop halts — regardless of what the model wants. These bounds guarantee termination: no matter how confused the agent gets, the loop is a finite process. This is the agent-runtime version of a timeout, and it's the first thing a production harness must have, not the last.

04

The bounds math

Model each loop step as having some probability p of completing the task. Then finishing is a geometric process — the chance of being done within k steps, and the expected number of steps, are:

P(done ≤ k)  =  1 − (1 − p)k     E[steps]  =  1 / p

Success probability rises fast with more steps allowed, and the average run finishes in about 1/p steps — so most legitimate tasks complete well before a generous cap.

But if p = 0 (the task is impossible or the agent is stuck), no number of steps ever finishes — the geometric never terminates. That's why the loop needs a bound independent of p: stop at max_steps or when spend exceeds budget, whichever comes first:

halt when   step = max_steps  OR  spent + cost > budget   ⟹   loop is guaranteed finite

The bound converts a possibly-infinite process into a finite, budgeted one — set max_steps from E[steps] plus headroom, and back it with a hard cost budget. The runnable version below runs a bounded loop that halts on completion, max steps, or budget.

RUN IT YOURSELF

A bounded agent loop

The agent loop is a for-loop with brakes. If each step finishes the task with probability p, the chance of finishing within k steps is 1 − (1 − p)^k (rising fast) and the expected run is 1/p steps. But a stuck task (p = 0) never finishes, so the harness enforces bounds: it halts at max_steps, or when spend would exceed the budget, or when the task completes — whichever comes first. That guarantees the loop is finite no matter what the model does. Change the step function, the max steps, or the budget and watch how the loop terminates.

CPython · WebAssembly
05

What the harness owns

Beyond the loop and its bounds, a production harness carries a lot of the reliability:

ResponsibilityWhat it does
Bounds & terminationMax steps + cost/token budget + a done-signal — guarantees the loop halts.
Tool dispatchParse the model's tool call, validate arguments, run the tool, capture the result and errors.
Context assemblyBuild each turn's prompt: system, goal, tool schemas, and the running history (with memory management).
Error handlingRetries with backoff, feeding failures back so the model can recover instead of crashing.
ObservabilityLog every step — action, result, tokens, cost — so you can trace and debug the run.
GuardrailsValidate tool arguments and results at the boundary (see guardrails).

Two are worth calling out. Loop detection — if the agent repeats the same action with the same result, it's stuck; catch that and break early rather than waiting for the step cap. And a graceful halt handler — when a bound trips, return partial progress and a clear reason, not a crash. The deeper craft of designing this loop well — when to reflect, when to branch, how to keep the agent on track — is the subject of loop engineering; this handbook is about the runtime skeleton that makes any of it safe to run.

06

Pitfalls

The cardinal sin is shipping without bounds — a `while not done` loop with no cap. It works in the demo, then in production an edge case makes the agent loop and you discover it via the bill. Always bound both steps and cost: a step cap alone won't save you from an agent making a few very expensive calls, and a cost cap alone won't catch a fast infinite loop of cheap ones. Belt and braces.

Two more. Silent context growth: each step appends to the history, so a long run can blow the context window or quietly balloon cost per step — pair the harness with memory management. And trusting tool output blindly: a tool result flows straight back into the model's context, so a malicious or malformed result can hijack the loop — validate at the boundary. Build the harness bounds-first: get a loop that always terminates, then add the tools, then make it smart. An agent you can't stop isn't an agent — it's a liability with a prompt.

Worth knowing

Bound both dimensions. A max-step cap won't stop an agent that makes a handful of very expensive calls; a cost budget won't stop a fast loop of cheap ones. Enforce max_steps AND a cost/token budget, halt on whichever trips first, and always handle the halt gracefully.

Frequently asked

Quick answers

What is an agent harness?

The code that wraps a model in a plan-act-observe loop — owning tool dispatch, context assembly, error handling, and the bounds that stop the loop.

What is the plan-act-observe loop?

The agent cycle: the model plans an action, the harness runs it, the result is observed back, and it repeats until done — the ReAct pattern.

Why a hard stop?

A model can fail to ever finish, so an unbounded loop runs forever burning money; max steps + a cost budget guarantee termination.

How many steps to allow?

Set from expected steps (~1/p) plus headroom, and pair with a cost budget so both a slow loop and an expensive one are bounded.

Finished this one? 0 / 99 Handbooks done

Explore the topic

See this alongside everything else on the same subject — handbooks, system designs, challenges and tools, in one place.