U-10 · pruebas · July 2026
Harness, loop and graph engineering: three ways to build an agent
There’s a pattern that repeats in every conversation about agents in 2026: three people use three different words —loop, graph, harness— convinced they are debating the same decision, and they are not. One is talking about who decides the next step. Another about how the path is drawn. The third about the ground you stand on.
These aren’t three options on a menu. They are three layers, and confusing them leads to arguments nobody can win. This post separates them, says what breaks in each, and brings the evidence —which exists, and is more forceful than I expected— for which one actually moves the needle.
It all starts as a loop
Before the three words there was ReAct (Yao et al., ICLR 2023), and its idea is still the skeleton of nearly everything built today: interleave reasoning and action in the same flow, so thought serves to plan the next action and the action’s result serves to correct the thought. At the time that earned them a 34-point absolute success-rate improvement over imitation and reinforcement learning on ALFWorld, prompted with one or two examples.
Reduced to code, an agent is this and not much more:
def agent(goal, tools, max_steps=20):
context = [{"role": "user", "content": goal}]
for _ in range(max_steps):
response = model(context, tools=tools)
if not response.tool_calls:
return response.text # the model believes it's done
for call in response.tool_calls:
result = execute(call) # ← the harness lives here
context.append(result)
raise StepLimit() # ← this is a design decision too
Four lines of substance. What’s interesting is that almost every architectural decision that matters sits outside the model call: who decides when to stop, what’s in tools, what happens to context when it grows too large, what execute returns when something fails. The three disciplines come out of that.
Loop engineering: let the model decide
The first option is to leave that loop as it is and work on it: the model picks the next action each turn, and you invest your effort in the prompt, the tool catalogue and the stopping conditions.
This is what Anthropic simply calls an agent, in contrast with a workflow, and their definition is the cleanest I know: agents are “systems where LLMs dynamically direct their own processes and tool usage, maintaining control over how they accomplish tasks” (Building Effective Agents, 2024).
When it wins. When you cannot predict how many steps will be needed or in what order. Anthropic’s guide puts it bluntly: agents are for “open-ended problems where it’s difficult or impossible to predict the required number of steps, and where you can’t hardcode a fixed path”. Debugging, exploring a repository, researching a question: tasks where step five depends on what you find at step four.
How it fails. In three ways, all expensive:
- Drift. The model wanders off the goal little by little, without any single turn looking wrong. It’s the most treacherous failure because it raises no exceptions.
- Loops. It repeats the same failing action expecting a different outcome, burning tokens each turn.
- Compounding errors. This is Anthropic’s explicit warning: “their autonomous nature means higher costs, and the potential for compounding errors”. A 95% per-step success rate is 60% after ten steps.
None of the three is fixed by a better prompt. They are fixed by structure — which is where the second discipline comes in.
Graph engineering: let the designer decide
The second option is to take control away from the model and put it in an explicit topology: nodes that do things, edges saying what can follow what, conditions that pick a branch. This is what LangGraph does, and what Anthropic calls a workflow: “systems where LLMs and tools are orchestrated through predefined code paths”.
Their guide catalogues five patterns covering most real cases: prompt chaining, routing, parallelization, orchestrator-workers and evaluator-optimizer — the last of which is exactly the critique-and-rewrite loop discussed in loop prompting (Spanish).
When it wins. When you can draw the whole flow before writing it. If the requirement is “if step B fails, go back to A, but at most three times”, in a free loop that’s a plea in the prompt and in a graph it’s an edge. Explicit topology gives you for free what a loop makes you bleed for: bounded retries, human approval gates, resumption after a crash, and a diagram someone can review without reading the prompt.
How it fails. Also in three ways:
- It gets boxed in. If a condition arises with no matching edge, the agent doesn’t improvise: it has nowhere to go. The rigidity that buys you guarantees is the same rigidity that strips it of options when something unforeseen happens.
- Edge explosion. Every new edge case is another node and a few more edges. At some point the graph is harder to reason about than the loop it replaced.
- False determinism. The graph is deterministic; the nodes are not. Having the diagram drawn is more reassuring than it should be when every box is still an LLM call.
The most useful rule of thumb I’ve read is also the simplest: if you can’t draw the whole flow up front, the graph isn’t your tool. And its converse: if you can draw it, you probably didn’t need an agent.
Harness engineering: the ground
And here is the layer almost nobody names at the start, because it doesn’t look like an architectural decision — it looks like plumbing.
The harness is the deterministic infrastructure surrounding the model: the sandbox where actions run, the tools and how they’re described, context management, traces, verifiers, permissions. The model proposes; the harness validates, authorises, executes, records. In the code above, it is everything inside execute() and everything that decides what goes into context.
The Agent Harness Engineering: A Survey (Li et al., 2026 — a joint effort from CMU, Yale, Stanford, Tulane, Amazon and others, mapping more than 170 open-source projects) organises it into seven layers under the acronym ETCLOVG:
| Layer | What it covers |
|---|---|
| Execution | Sandbox, isolation, reset semantics |
| Tooling | Protocols (MCP, A2A), tool description and discovery |
| Context | Active window, session memory, persistent memory |
| Lifecycle | State, orchestration, inner loop, multi-agent patterns |
| Observability | Traces, monitoring, cost attribution |
| Verification | Evaluation, verifiers, failure detection |
| Governance | Identity, permissions, audit, human approval |
What stands out is where loop and graph land in that table: inside a single layer, Lifecycle. The entire loop-versus-graph debate is a debate about one seventh of the problem.
The evidence
This is where I expected to find opinion and found numbers. Holding the model frozen and changing only the harness:
And it isn’t an isolated case: the same survey collects work that modified the edit-tool format and its surrounding harness across 15 different models, reporting coding-benchmark gains of up to 10× on one of them.
Now the honest part, which the survey writes itself and is worth not skipping: “the strongest controlled evidence currently comes from coding-agent benchmarks, and these results do not establish that the harness matters more than the model in every setting”. The defensible conclusion isn’t “the harness matters more than the model”. It’s that an agent’s performance cannot be cleanly attributed to the model without specifying the controller around it — which, among other things, makes any model comparison that doesn’t state its harness rather suspect.
Try it: same task, three architectures
Pick a scenario and watch what each architecture does step by step. The first three are everyday; the fourth is the one that separates the first two from the third:
The fourth scenario is the whole post in miniature. Faced with hostile content, “loop or graph?” has no useful answer: neither topology defends against anything. What defends is having no credentials in the sandbox and requiring approval for consequential actions. That’s harness, and it appears on no flow diagram.
So where does control live?
That’s the question that actually separates the three disciplines:
| Who picks the next step | Where a failure gets fixed | What breaks first | |
|---|---|---|---|
| Loop | The model, every turn | In the prompt and the tools | Coherence after N steps |
| Graph | The designer, up front | By adding nodes and edges | Whatever wasn’t foreseen |
| Harness | Neither: it bounds both | In the infrastructure | Nothing visible… until everything |
The most practical synthesis I know is the eighth of Dex Horthy’s 12-Factor Agents, “own your control flow”: the model may choose the next action, but your application owns the loop, the stopping conditions, the retries, the approval gates and the budget ceilings. That sentence dissolves the false dilemma. It isn’t “loop or graph”: it’s that the loop should be yours and not an emergent property of the prompt.
The fourth temptation: multiplying agents
When one agent isn’t enough, the reflex is to add several. Here the consensus breaks, and it’s worth knowing both positions before deciding.
Cognition published the sharpest one, Don’t Build Multi-Agents: with several agents in parallel, decisions get dispersed and context isn’t shared thoroughly enough, so the system turns brittle. Their recommendation is a single thread of execution, with a separate LLM dedicated to compressing context. LangChain, from the other side, qualifies the when more than the whether.
Where both agree, and where the field seems to have landed, is this: one main agent owns the continuous context and spawns ephemeral, read-only subagents that return a compressed summary. No peer-to-peer channel, no shared mutable state. Swarms of agents writing at once remain brittle for the same old reason: context fragments and decisions contradict each other.
Notice that this debate is, again, about the Lifecycle layer. And that the consensus solution —compress context, isolate, return summaries— is pure harness.
Three tolls you can’t dodge
The survey closes with three tensions that aren’t resolved by choosing well, only managed. They strike me as the most useful part of the whole work:
Cost, quality and speed. More faithful sandboxes, richer memory, deeper evaluation and finer observability improve quality and worsen the other two. No configuration wins on all three: you have to decide which checks are synchronous, which run offline, and which failures justify an expensive recovery.
Capability versus control. Every increase in authority widens the control problem. A larger tool catalogue covers more tasks while increasing selection error and prompt-injection surface. Persistent memory helps long-running tasks and creates provenance, staleness and privacy risks. A permissive sandbox makes autonomous execution useful and enlarges the blast radius.
Coupling. The layers interact in ways that make local optimisation fragile. Tool descriptions consume context budget and shape model behaviour; the execution environment changes evaluation results; evaluation design feeds back into orchestration by rewarding some recovery loops and penalising others. The operational conclusion is uncomfortable but clear: a harness change must be tested as a system change, not a local one. A tool, a verifier or a memory policy can look good in isolation and degrade the whole rollout once combined with the rest.
What I would do
Ordered by return per unit of effort:
- Start with the simplest loop that works. Anthropic’s own guide recommends finding the simplest possible solution and adding complexity only when needed — “which might mean not building agentic systems at all”.
- Invest in the harness before the topology. That’s where the quantitative evidence is: same model, +13.7 points. Well-described tools, errors that return to the context with useful information, traces from day one, and a budget ceiling.
- Move to a graph only when you can draw it. If the flow has branches you can enumerate, guarantees to meet, or human approvals to insert, explicit topology pays for itself. If you can’t draw it, don’t force it.
- Multiply agents last, and one at a time. One orchestrator owning the context, ephemeral subagents returning summaries. No swarms writing in parallel.
- Measure the system, not the model. If you change the harness and the score rises, you’ve learned something. If you change the model without fixing the harness, you’ve learned nothing.
And the whole thing in one sentence: loop and graph engineering decide who draws the path; harness engineering decides whether the ground holds. Almost everyone, myself included, starts by arguing about the first.
Sources
- Yao, Zhao, Yu, Du, Shafran, Narasimhan and Cao — ReAct: Synergizing Reasoning and Acting in Language Models (ICLR 2023). The loop all the others descend from.
- Anthropic — Building Effective Agents (2024). The workflow/agent distinction and the five orchestration patterns.
- Anthropic — Effective context engineering for AI agents. Compaction, context rot and context as a finite resource.
- Li, Xiao, Zhang, Liu et al. — Agent Harness Engineering: A Survey (2026). The ETCLOVG taxonomy, the mapping of 170+ projects, and the three closing tensions. The main source for this post.
- Zhang, Wang, Ge, Xu, Hamm and Reddy — Stop Comparing LLM Agents Without Disclosing the Harness (2026). The uncomfortable corollary: comparing models without stating the harness doesn’t mean much.
- Trivedy (2026), collected in the survey above: LangChain’s DeepAgents, from 52.8% to 66.5% on Terminal-Bench 2.0 with the model frozen.
- Zhang et al. — The Interplay of Harness Design and Post-Training in LLM Agents (2026). What happens when you train an agent on a poor harness: it breaks when the tools change.
- Cognition — Don’t Build Multi-Agents (2025). The strong position against parallelism between agents.
- LangChain — How and when to build multi-agent systems. The counterpoint.
- Horthy — 12-Factor Agents. In particular “own your control flow” and “compact errors into the context window”.
- Anthropic — Model Context Protocol. The protocol behind ETCLOVG’s T layer; taken apart in how an agent talks to an MCP server (Spanish).