Welcome back to the Harness Engineering series — a 10-part journey from raw language model to production-ready agentic system. Made by builders. For builders.
In Part 2, I named the six components that make up a harness. Time to dig into the first one — and it's not an accident that it's first. The Loop is the outermost machinery of a harness. It's the piece everything else plugs into. Without it, none of the other components have anything to do.
Every agent you've ever seen — whether it's Claude Code fixing a bug, a research agent skimming papers, or a customer support bot pulling up account data — has a Loop at its core. Sometimes it's obvious. Sometimes it's tucked away inside a framework. But it's always there, and how it's designed shapes what the agent is capable of.
What's ahead:
- Part 1: The Raw Model Problem
- Part 2: Defining the Harness — The Six Components
- The Control Loop ← You are here
- Part 4: The Tool Layer
- Part 5: Context Engineering
- Part 6: The Filesystem & Environment
- Part 7: The Memory Layer
- Part 8: Observability
- Part 9: The Harness Architecture
- Part 10: Decomposing Claude Code
By the end of this article, you'll know what the Loop is, why every agent needs one, what separates a robust loop from a fragile one, and the common shapes you'll see loops take in the wild.
Let's get started.
📚 Want to go deeper than the articles?
While you follow along with this series, I've put together two hands-on resources that go further than any single article can:
- Build a Harness from Scratch — Udemy Course — A self-paced course where I walk you through building a production-grade agentic harness from the ground up, in code.
- Harness Engineering for AI Agents — Live Maven Workshop — A live, cohort-based workshop for builders who want direct feedback, Q&A, and to work through the material with peers.
Both are optional — the series stands on its own. But if you want the full studio-quality version, that's where it lives.
What The Loop Is
The Loop is the control flow that wraps the model. It's the piece of code that turns a one-shot API call into something that can take multiple steps, react to intermediate results, and eventually stop when the job is done.
At its minimum, a loop does three things, in a cycle:
- Call the model with the current context.
- Parse the response.
- If the model asked for a tool, run the tool and call the model again with the results attached. Otherwise, stop.
In pseudocode, that looks like:
while True:
response = model.call(context)
context.append(response)
if response.has_tool_call:
result = run_tool(response.tool_call)
context.append(result)
else:
break # model is done
That's it. Three steps, running in a cycle. Every fancy orchestration pattern you've heard of — multi-agents, sub-agents, planning phases, self-reflection — is a variation of this shape. Sometimes with extra bells, sometimes with recursion, sometimes with parallelism. But underneath, the same core cycle.
Another way to say it: the Loop is where the model does its work, and where the harness decides what to do with that work. Without the Loop, the model produces one message and the process ends. With the Loop, the model gets to iterate — respond to tool results, revise its plan, keep going until something is done.
Why The Loop Exists
We established in Part 1 that a raw language model can't act. But the Loop solves a subtler problem: a single model call produces text and then exits.
Even if you gave the model tools, without a loop all it could do is say "I'd call this tool now." The moment it finishes generating that message, control returns to your program. If your program isn't set up to look for tool requests, run them, and re-call the model, no tool actually runs. The model's request just sits there in the response object.
Everything that resembles agency — taking multiple steps, reacting to results, deciding to keep going or stop — has to come from a loop around the model. Not from the model itself. The model doesn't know it's in a loop. Every time it's called, it just responds to whatever context it's given.
The model proposes; the Loop decides whether to keep going.
That sentence is worth writing on a Post-it. Every design decision about the Loop follows from it.
What a Good Loop Design Looks Like
If you're evaluating a harness — or someone else's — three things separate a good Loop from a bad one.
Clear Termination Conditions
A Loop that doesn't know when to stop is not an agent. It's a bill from your model provider. Good loops have explicit, multiple termination conditions:
-
The model signals it's done — a stop phrase in the response, a specific
stop_reasonfrom the API, or adonetool call the model can invoke on itself - A step budget runs out — a max-iterations counter that prevents runaway loops
- An error threshold is hit — too many consecutive tool failures, too many parse errors, too many empty responses in a row
You want all of these, not one. Relying on the model alone to say "I'm done" is how you end up with agents that run for 200 iterations because the model keeps thinking of one more thing to check.
Sensible Error Handling
When a tool call fails — invalid parameters, network timeout, the file doesn't exist — the Loop should not crash. It should catch the error and feed it back to the model as an observation.
This turns errors into information. The model reads "the file you tried to open doesn't exist," realizes it hallucinated the filename, and tries a different one. That's the whole game. A Loop that crashes on the first tool failure has no way to recover. A Loop that treats errors as inputs to the next model call learns to steer around them.
A Loop Has a Shape
The two points above are about the quality of a Loop. But loops also come in different shapes — architectures, patterns, whatever you want to call them. And the shape determines what kinds of tasks the loop can handle.
Some of the common shapes you'll run into:
- ReAct — the model alternates between "reasoning" (thinking out loud) and "acting" (calling tools), with tool observations feeding back into the next reasoning step. The default shape for most modern agents.
- Plan-then-Act — the model produces a plan up front, then the Loop executes the plan step by step. Good for tasks with a knowable structure; brittle when the world doesn't cooperate.
- Multi-Agent — multiple agents (each with their own Loop) coordinate on a task, often passing messages between one another. Useful when different sub-tasks call for different tools, models, or personas.
- Deep Recursion — the Loop is intentionally allowed to spawn sub-loops that dig into a task. The Ralph Loop and Orchestrator/Worker patterns are two variants. Powerful for tasks that decompose naturally into sub-tasks.
None of these shapes is objectively "best." The right shape depends on the task, the reliability requirements, and how much you're willing to spend per invocation. Getting the shape wrong is one of the most common ways an otherwise well-built harness fails to do the thing it was designed to do.
Example: Claude Code
If you've used Claude Code, you've already watched the Loop at work.
When you ask Claude Code to fix a bug, it doesn't make one model call. It makes many. It reads a file. It edits the file. It runs the tests. It reads the failure output. It edits the file again. It re-runs the tests. It reads the diff. It might read a different file to check an import. It keeps going, iteration after iteration.
The Loop is what makes that possible.
And critically, the Loop is also what decides when to stop — when the tests pass, or when Claude Code is confident the task is done. Without termination conditions, the same Loop that fixes bugs would keep going forever, "improving" code long after the user's actual request was satisfied.
So when you see Claude Code do something impressive across ten or twenty steps, remember: the model doesn't know it's doing ten or twenty steps. Every time it's called, it just sees the current state and produces the next response. The sense of coherent, multi-step problem-solving — the thing that makes it feel like an agent — comes entirely from the Loop wrapping it.
Where This Leaves Us
The Loop is the first component of the harness because nothing else works without it. Tools have nowhere to be invoked from. Context has nothing driving its accumulation. Memory has no cycle to write into. Observability has no execution path to trace. Every other component plugs into the Loop.
That's why we started here. From Part 4 onward, every component we look at slots into the Loop somewhere — and understanding the Loop is what lets you see where.
Remember that this article is part of a longer 10-part series that walks you through every component of an agentic harness.
Here's the roadmap:
- Part 1: The Raw Model Problem
- Part 2: Defining the Harness — The Six Components
- The Control Loop ← You just finished this one.
- Part 4: The Tool Layer ← Move to this one.
- Part 5: Context Engineering
- Part 6: The Filesystem & Environment
- Part 7: The Memory Layer
- Part 8: Observability
- Part 9: The Harness Architecture
- Part 10: Decomposing Claude Code
See you in the next one.
Happy coding :)

Top comments (0)