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.

HARNESS sandbox · tools · context · traces · verification · permissions what the model can see and touch — it sits underneath both options above LOOP the model decides think act done? GRAPH the designer decides fixed edges
Loop and graph are alternatives to each other. The harness is not: it sits beneath both, and it's the layer almost nobody names when starting out.

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:

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:

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:

LayerWhat it covers
ExecutionSandbox, isolation, reset semantics
ToolingProtocols (MCP, A2A), tool description and discovery
ContextActive window, session memory, persistent memory
LifecycleState, orchestration, inner loop, multi-agent patterns
ObservabilityTraces, monitoring, cost attribution
VerificationEvaluation, verifiers, failure detection
GovernanceIdentity, 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:

TERMINAL-BENCH 2.0 · SAME MODEL (GPT-5.2-CODEX) · ONLY THE HARNESS CHANGES baseline harness 52.8% redesigned harness 66.5% +13.7 pts Restructuring the system prompt, injecting context via middleware and adding self-verification hooks. Zero changes to the model.
Data from Trivedy (2026) on LangChain's DeepAgents, collected in the harness engineering survey.

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:

LOOP
    GRAPH
      HARNESS

        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 stepWhere a failure gets fixedWhat breaks first
        LoopThe model, every turnIn the prompt and the toolsCoherence after N steps
        GraphThe designer, up frontBy adding nodes and edgesWhatever wasn’t foreseen
        HarnessNeither: it bounds bothIn the infrastructureNothing 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:

        1. 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”.
        2. 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.
        3. 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.
        4. Multiply agents last, and one at a time. One orchestrator owning the context, ephemeral subagents returning summaries. No swarms writing in parallel.
        5. 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

        ← back to the rack