Part 2 — Complete LLM Systems

Agent harnesses and context engineering

Extending the model·Core·7 min read

An agent is more than a model in a loop. Around it sits a harness — the machinery that chooses tools, manages a context window that fills up, decomposes work across sub-agents, and enforces guardrails. This chapter is about that harness, and why building capable agents is mostly context engineering, not prompt cleverness.

The previous chapter introduced agents as a model looping over tools. That framing hides where the real engineering is. A capable agent is wrapped in a harness: the surrounding system that decides which tools exist and how they're described, manages the context as it fills across many steps, splits work across sub-agents, and enforces safety at the edges. The model is the reasoning engine; the harness is everything that turns that engine into something that can actually do useful, multi-step work without falling over. Building agents is largely building harnesses — and the core discipline within it is context engineering.

What you will understand by the end

  • What a harness is, and why the model is only its centre.
  • Why context engineering — managing a filling context window — is the defining agent problem.
  • Compaction strategies and sub-agent decomposition, and when each is needed.
  • The harness as the superset of decisions that make an agent reliable.

The model is the engine; the harness is the system

Give a raw model a hard, multi-step task — say, migrating a codebase or researching a question across many sources — and on its own it flounders: it can't read files, run commands, or search, and it has no way to keep track across steps. Wrap it in a harness — a set of tools it can call, a loop that feeds results back, memory of what's happened, and rules at the boundaries — and the same model becomes capable. The intelligence is the model's; the capability is the harness's.

Key idea

An agent's power comes as much from its harness as from its model. Two systems on the identical model can perform completely differently depending on how well the harness selects tools, manages context, and decomposes work. When you "improve an agent," you are usually improving the harness, not swapping the model.

Tool design is prompt design

An agent chooses what to do by reading tool descriptions. So the descriptions — names, arguments, when-to-use guidance — are not documentation; they're the interface the model reasons over, and vague or overlapping tools cause bad choices the same way an ambiguous taxonomy causes bad labels. Designing the toolset (which tools exist, how each is described, how they don't overlap) is a core harness decision, and it's really prompt engineering aimed at tool selection.

Context engineering: the defining problem

Here is the problem that dominates agent building. Every step of the decide → act → observe loop appends to the context — the model's instruction, each tool call, each (often large) result. Over a long task the context grows without bound and eventually exceeds the window, even a very large one. And it's not just about fitting: a bloated context of stale, irrelevant history degrades reasoning. Managing that growing context — deciding what to keep, summarise, or drop — is context engineering, and it's the difference between an agent that stays coherent over 50 steps and one that derails at step 10.

   step 1: [instruction]                                         small
   step 2: [instruction][call₁][result₁]
   step 3: [instruction][call₁][result₁][call₂][result₂]
   ...                                                            ▲ grows every step
   step N: ...............................................  ▶ exceeds the window / dilutes reasoning
                    context engineering decides what survives each step
Watch out

A bigger context window doesn't dissolve this — it just delays it, and it makes the quality problem worse, because more room means more stale history diluting the model's attention. Long-running agents need an active context strategy regardless of window size; "we have a million tokens" is not a context-management plan.

Compaction and sub-agents

Two harness techniques manage the growing context:

  • Compaction. When the context nears its limit (or on a schedule), compress the history — keep the most recent and most relevant tool results, summarise or drop the rest — so the agent continues with a smaller, higher-signal context. The quality of the compaction matters directly: a summary that drops a crucial earlier detail causes a later failure, so compaction is itself something to design and evaluate, not a mechanical truncation.
  • Sub-agent decomposition. Instead of one agent accumulating everything, split the work across sub-agents with focused contexts — e.g. one explores, one implements, one verifies — each starting fresh and returning only its result. This keeps any single context small and on-task, at the cost of coordinating the sub-agents and deciding what to parallelise.
Key idea

Both techniques fight the same enemy — context bloat — from opposite directions: compaction shrinks one agent's history; sub-agents partition the work so no single history grows large. Which you reach for depends on whether the task is one long thread (compact it) or separable phases (split it).

The harness is the superset

Pulling it together, the harness is the full set of decisions that turn a model into a reliable agent: which model, the tool set and descriptions, the context strategy (compaction, sub-agents), lifecycle hooks (things that run before/after steps — logging, checks), and guardrails at the boundaries (next chapter). It is, squarely, a complete system in the sense this part uses the word — a versioned configuration whose score belongs to the whole, not the model alone — and evaluating it means the step-level traces an agent demands.

Mental model

The model is the reasoning engine; the harness is the system around it — tools and their descriptions, the context strategy, sub-agent decomposition, hooks, and guardrails. The defining problem is context engineering: the decide-act-observe loop grows the context every step, so you compact it or partition it across sub-agents. Building capable agents is mostly building good harnesses.

Common mistakes

  • Blaming the model for an agent's failure. It's usually the harness — poor tool descriptions, no context strategy, bad compaction.
  • Ignoring context growth until it breaks. The loop fills the window; without a strategy the agent derails on long tasks.
  • Trusting a big window instead of managing context. More room delays the limit and worsens the dilution problem; it's not a plan.
  • Lossy compaction with no evaluation. A summary that drops a key detail causes a later failure; compaction quality must be designed and tested.

Practical guidance

  • Treat tool descriptions as prompt design — clear, non-overlapping, with explicit when-to-use guidance, since they're what the model chooses from.
  • Give long-running agents an explicit context strategy from the start: what to keep, when to compact, and what to summarise vs drop.
  • Use sub-agents to keep individual contexts small and focused when a task has separable phases; decide deliberately what to parallelise.
  • Version the whole harness as one configuration and evaluate it with step-level traces, not just a final score.

Summary

  • An agent is a model plus a harness — tools, context strategy, sub-agents, hooks, guardrails — and the harness carries much of the capability.
  • Tool descriptions are prompt design; the model chooses actions by reading them.
  • Context engineering is the defining problem: the loop grows the context every step, managed by compaction (shrink one history) or sub-agents (partition the work).
  • The harness is a complete system — versioned, evaluated with step-level traces — not a thin wrapper around the model.

Knowledge check

An agent handles short tasks well but consistently derails on long, multi-step ones — losing track and repeating itself around step 15. The model is strong. What's the likely cause and the fix?

The likely cause is a context problem, not the model: the decide-act-observe loop appends to the context every step, so by step 15 it's bloated with stale tool results that both crowd the window and dilute the model's attention, causing it to lose track and repeat itself. The fix is context engineering — an active strategy to compact the history (keep recent/relevant results, summarise or drop the rest) and/or decompose the task across sub-agents with focused contexts so no single history grows large. A bigger window would only delay the derailment, not prevent it.

Why is compaction something to evaluate rather than a mechanical "just truncate old messages"?

Because compaction is lossy, and what it drops determines whether the agent later succeeds: naive truncation can discard an early detail (a constraint, a decision, a discovered fact) that a later step depends on, causing a failure that looks like a model mistake but is really a compaction mistake. So the compaction strategy — what to keep, what to summarise, what to drop — is a design decision with real quality consequences, and it should be tested (e.g. does the agent still complete tasks after compaction?) like any other component, not treated as a mechanical size cap.

Related chapters