AI Engineering Playbook
Agents

Harness vs Orchestration

Two layers that both claim the phrase "agent runtime" — where the boundary really is, and where it's just vocabulary.

Prerequisites

The intuition

Ask two experienced engineers what runs an agent and you get two confident, incompatible answers.

The one who lives in LangGraph says: orchestration is the runtime — nodes, edges, typed state, checkpoints. The loop is just a cycle in my graph. The one who lives in Claude Code says: the harness is the runtime — the loop, the tools, the sandbox, the permission gates. Orchestration is what you reach for when one agent isn't enough.

Both are describing something real, and neither is describing the whole thing. The useful mental model is two axes rather than two camps. The harness is vertical: everything between the model and the world on a single turn — what it sees, what it can touch, what it's allowed to do. The orchestrator is horizontal: everything between one unit of work and the next — what runs after this, what state survives, who approves, what happens when the process dies at step seven.

Key insight

The harness contains non-determinism turn by turn; the orchestrator constrains it step by step. A harness makes one model turn safe and well-informed. An orchestrator makes a sequence of turns survivable, resumable, and composable. Neither substitutes for the other, and most production failures come from investing in one when the problem was in the other.

Why it exists

This looks like a vocabulary argument. It costs real money, in both directions.

  1. Orchestration bought for a harness problem. A team ships a supervisor graph with four specialist agents for "code quality." Each agent has an unnamespaced tool catalogue, no result truncation, no sandbox, and an instruction file nobody has read in two months. The graph is beautiful. The agents flail. Topology multiplied a per-turn failure by four and added a merge problem on top.
  2. Harness bought for an orchestration problem. A team hand-rolls an excellent loop — good tools, tight compaction, real permission tiers — and points it at a five-hour invoice-approval process with a human sign-off in the middle. There is no durable identity for "step 7 of this approval," so a deploy mid-run loses the work, and a retry re-sends the payment.
  3. The words hide the boundary. Vendors market their whole stack under whichever word they own. LangGraph calls itself "an agent runtime and low-level orchestration framework" — both layers, one product. Anthropic's engineering writing calls a planner/generator/evaluator arrangement harness design, which is orchestration-shaped work under the other word. Neither is wrong; both make the boundary invisible if you only read one.

The reason to hold the distinction is not taxonomy. It's that the two layers fail differently, are tested differently, and are fixed by different people. Knowing which layer you're in tells you where to look.

The core idea

A harness is the runtime for one control loop's relationship with the model and the world: instruction and context assembly, tool schemas and dispatch, result shaping, the context budget, the sandbox, permission tiers, and the stop condition. Orchestration is the composition of multiple units of work over time: what runs next, what durable state carries between units, how branches fan out and merge, how a step retries or compensates, where a human interrupts, and how a run resumes after a crash. The unit of concern is the difference — a harness reasons about a turn, an orchestrator reasons about a sequence.

The sharpest test: if it changes what the model can see or do this turn, it's harness; if it changes what happens after this unit of work finishes, it's orchestration. That test is good enough to argue from and honest enough to admit its own failures, which is more than most taxonomies manage.

Now the part most write-ups skip. The split is partly real engineering and partly dialect. The coding-agent community built its vocabulary around one long-lived loop, so harness grew to mean everything: LangChain's widely-cited framing is "Agent = Model + Harness," and it lists "orchestration logic (subagent spawning, handoffs, model routing)" as a harness component. The framework community built its vocabulary around composing steps, so orchestration grew to mean everything, including the per-turn tool loop that sits inside every node. Hugging Face's agent glossary exists because practitioners at ICLR could not converge on definitions, and says so explicitly. Martin Fowler's write-up calls the broad definition "a very wide definition, and therefore worth narrowing down." A candidate who says "these are two clean, universally agreed categories" is overselling; a candidate who says "these are two concerns, and here's which layer owns which, and here's where real systems blur them" is describing the field as it actually is.

So use the words for concerns, not for product categories. Ask "is this component doing harness work or orchestration work?" — that question always has an answer, even when "is this product a harness or an orchestrator?" doesn't.

How it actually works

Who owns which concern

The interesting column is the third one. Several concerns legitimately exist at both layers with different semantics, and conflating them is exactly how teams end up with two half-implementations.

ConcernPrimary layerAlso at the other layer?
System prompt assemblyHarness — built fresh every turnOrchestrator picks which role/brief a unit runs with
Tool schemasHarness — the interface the model seesOrchestrator decides which tool set a given unit gets
Tool executionHarness — alwaysNo
Retry on tool errorHarness — return the error as an observation, let the model adaptOrchestrator retries the whole unit when the unit itself failed
Context compactionHarness — the window is a per-loop resourceOrchestrator can force a fresh unit with a handoff artefact instead
CheckpointingBoth, differentlyHarness persists a session so it can resume; orchestrator checkpoints between units so it can replay
Human approvalBoth, differentlyHarness gates a specific tool call before execution; orchestrator interrupts between units
BranchingOrchestrator — an inspectable, testable edgeHarness has micro-branches (which tool to offer) but they aren't control flow
Fan-out / map-reduceOrchestrator — parallel units with merge semanticsHarness does parallel tool calls in one turn, which is not the same thing
Multi-agent handoffOrchestrator — control transfer between unitsHarness spawns sub-agents as a context-isolation trick
IdempotencyOrchestrator's requirement, harness's implementationKeys live on the tool; the need arises from replay
Observability spansBoth — and they must nestTurn and tool spans inside unit spans inside a run

The awkward cases

Any boundary test is only as good as the cases that embarrass it. These are the ones worth having an answer for.

A LangGraph prebuilt ReAct agent. Tool schemas, a tool node, a state object, a cycle back to the model. That is a harness, expressed in an orchestration framework's vocabulary. The while loop is the graph. It is doing harness work with orchestration primitives, which is why LangGraph honestly describes itself as both a runtime and an orchestration framework.

Claude Code's sub-agents. Spawning a child with its own window and collecting a distilled result looks like orchestration. Mechanically it's a harness feature: a context-management technique implemented as a tool. The tell is that the parent doesn't checkpoint between children and can't resume a half-finished fan-out — there's no durable step identity, which is the thing orchestration actually provides.

OpenAI Agents SDK handoffs. The SDK defines orchestration as "the flow of agents in your app — which agents run, in what order, and how do they decide what happens next," and splits it into LLM-decided (handoffs, agents-as-tools) and code-decided flow. Handoffs are horizontal control transfer, so: orchestration. But the runner that executes each agent's turns is a harness, and it ships in the same package.

A Temporal-durable agent loop. Unambiguously orchestration: event-sourced history, deterministic replay, activities as the non-deterministic boundary, durable timers for human waits. What Temporal does not give you is prompt assembly, tool ergonomics, or a context policy — those you still build. This is the cleanest case in the list precisely because the layers don't overlap.

An MCP client. Neither. MCP is the tool-and-context interface — plumbing into the harness's tool catalogue. Deciding which server a given unit of work gets is a configuration decision that can be made at either layer.

The flows

FlowShapeWhen it's rightWhat breaks it
Bare loopwhile + tools, in-processSingle request, seconds to a minute, reversible actionsAnything that must survive a deploy or wait on a human
Harness, no orchestratorRich single loop: compaction, sandbox, permission tiers, session resumeInteractive coding/assistant work; one long conversationMulti-hour processes with irreversible steps and no durable step identity
Orchestrator, thin harnessDurable workflow whose steps are simple LLM callsEnumerable pipelines where the LLM fills in stagesOpen-ended work — you'll fight the graph to express "the model decides"
BothDurable workflow whose units each run a full harnessLong-horizon agentic work with approvals and real side effectsCost and complexity — earn it with failure modes, don't assume it

A worked example

The same requirement, sitting on the boundary. On the governed enterprise platform, finance wants: "every month-end, reconcile supplier invoices against POs, flag mismatches over £1k, and post corrections after a controller signs off."

Three things about this shape decide the architecture: it runs for hours, a human sign-off sits in the middle, and the last step moves money.

RequirementLayerWhy
Read 4,000 invoices without flooding the windowHarnessResult caps, pagination, offload-and-reference. A graph node with an unbounded tool result fails identically.
Model decides how to investigate each mismatchHarnessThis is the agent loop. The path per invoice isn't enumerable.
"Reconcile invoice X" as a retryable unit of workOrchestrationNeeds a durable identity so failure at invoice 2,847 doesn't restart at 1.
Controller signs off, possibly next morningOrchestrationA durable interrupt. Holding a process open for 14 hours is not an architecture.
post_correction never double-postsBothOrchestration creates the replay risk; the harness implements the idempotency key on the tool.
Deploy a prompt fix while 400 runs are in flightOrchestrationVersioning in-flight runs. No harness feature addresses this.

The failure mode of getting this wrong is specific in each direction. Build it as one heroic loop and the first mid-run deploy loses six hours of reconciliation and, worse, a retry re-posts corrections that already landed. Build it as a pure orchestration graph without harness investment and every node blows its context window on invoice line items, the model picks the wrong lookup tool because three of them overlap, and you conclude — incorrectly — that the graph was the problem.

Common misconception

"We added LangGraph, so context and tools are handled." A graph gives you durable state, branching, and interrupts. It does not give you tool schemas the model can use, truncation that doesn't lose the answer, a compaction policy, or a sandbox. Every node still contains a loop that needs all of those. Frameworks move harness decisions into configuration; they never remove them.

Common drill-downs

Give me the one-line distinction. The harness is the runtime for one control loop's relationship with the model and the world; orchestration is the composition of multiple units of work with durable state between them. Harness contains non-determinism turn by turn, orchestration constrains it step by step. Then add the honest caveat: the terms are used inconsistently across communities, so in practice you reason about concerns rather than categories.

Where does human-in-the-loop live? Both, with different semantics, and you usually need both. The harness gates a specific tool call before it executes — the granular, synchronous check. The orchestrator interrupts between units and durably parks the run — the one that survives a three-hour wait without holding compute. A team that only has the first can't handle long approvals; a team that only has the second can't stop a dangerous call inside a turn.

Where does checkpointing live? Both. The harness persists a session transcript so a conversation can resume where it left off. The orchestrator checkpoints between units so a crashed run replays from the last completed step without re-executing side effects. They're different granularities solving different problems, and LangGraph's checkpointer happens to serve both, which is why people conflate them.

Is a sub-agent orchestration? Usually not — it's a harness feature. Spawning a child with a fresh window and getting back a summary is context management implemented as a tool call. It becomes orchestration when the units get durable identity: independently retryable, independently checkpointed, resumable after the parent dies. Ask "can I resume a half-finished fan-out?" If no, it's a harness trick.

What earns an orchestration framework? Concrete forcing functions, at least two: runs that outlive a request, human waits measured in hours, side effects that must not replay, branching complex enough that a readable loop can't express it, or fleets of runs you must version and trace. Absent those, Anthropic's advice stands — start with direct API calls and simple composable patterns, because frameworks "create extra layers of abstraction that can obscure the underlying prompts and responses."

What earns harness investment instead? Symptoms that repeat within a turn: the model picking the wrong tool from an overlapping catalogue, results that blow the window, quality decaying over a long session, unactionable tool errors, or actions you can't safely allow. These don't improve with a better graph, because the graph never sees them. The tell is that your failures cluster inside single steps rather than between them.

Why is durable execution suddenly an agent topic? Because agents made the old workflow-engine problems acute. Temporal defines durable execution as "crash-proof execution": work resumes transparently in a new process with state intact. That's decades-old workflow-engine thinking. Agents stress it harder because the non-deterministic step now costs real money, branches unpredictably, and takes minutes instead of milliseconds — so replaying a decision rather than re-making it is both cheaper and more correct.

A team says their multi-agent system is slower and worse than the single agent it replaced. Where do you look? Usually not the topology. Check whether the sub-agents share enough context to avoid making conflicting implicit decisions, whether the extra tokens bought parallel reads (which works) or parallel writes (which doesn't merge), and whether each agent's own harness — tools, truncation, compaction — was ever tuned. Adding agents multiplies per-turn weaknesses. See multi-agent systems.

Production concerns

  • Instrument both layers or you'll misdiagnose every incident. Spans must nest: run → unit → turn → tool call. With only orchestration spans, "the model didn't find the obvious answer" is indistinguishable from a truncated tool result. With only harness spans, you can't see that unit 12 replayed twice. Anthropic's stated bar is that without full production tracing, user reports of an agent missing obvious information are simply undiagnosable. See observability.
  • Cost attribution needs the same nesting. Token spend accrues in the harness; the decision to spend it is usually made by the orchestrator, when it fans out or retries a unit. A dashboard that shows tokens by model but not by unit tells you what you spent, not why. See cost.
  • Idempotency is where the layers must agree. Orchestration creates the replay risk; the harness owns the tool that must tolerate it. This coordination is routinely missed because each team assumes the other handled it — the classic symptom is a duplicate write after a resume that everyone believed was safe.
  • Deploys are an orchestration concern that breaks harnesses. Change a tool schema or a prompt while runs are in flight and mid-run agents see a world that doesn't match their transcript. Anthropic runs staged deployments for exactly this reason. Version the harness, and let in-flight runs finish on the version they started with.
  • Neither layer is a security boundary on its own. The harness enforces per-tool permissions; the orchestrator enforces which unit gets which capability. An agent with private data access, untrusted input, and an outbound channel is exploitable regardless of how well either layer is built. See security.
  • Watch the framework-boundary trap. Adopting a framework for orchestration and inheriting its harness defaults — its tool wrappers, its truncation, its prompt assembly — is how teams end up unable to explain their own agent's behaviour. Anthropic's guidance applies at both layers: if you use a framework, understand the code underneath it.

Test yourself

Your agent is failing because it keeps calling the wrong one of three similar lookup tools. Your teammate proposes a supervisor agent that routes to specialists. What do you say?

A run crashed at step 7 of 10 and resumed correctly — but the customer got two refund emails. Which layer failed?

You need an agent that reads a 900-page contract, extracts obligations, and waits for legal to approve each high-risk one. Split the requirements across the two layers.

Someone argues 'a harness IS orchestration — my LangGraph ReAct agent has nodes, edges, and state, and that's all a harness is.' Steelman it, then answer it.

Under a hard latency budget, you must cut one: durable checkpointing between steps, or context compaction. Which goes, and what did you just accept?

Go deeper

Where this connects

  • The agent harness — the vertical layer in full: components, how to build one, and how to tell whether a change helped.
  • Orchestration & memory — the horizontal layer as LangGraph implements it: state, checkpoints, interrupts, and the two kinds of memory.
  • Multi-agent systems — what orchestration looks like when the units of work are themselves agents, and the token bill for it.
  • Agents vs workflows — the prior decision: whether the model should own control flow at all.
  • Reliability — idempotency, replay, and staged deploys, which are where the two layers have to agree.
Multi-Agent Systems

On this page