Harness Engineering Explained: Why an AI Agent Is Model + Harness
Agent = Model + Harness. If you are not the model, you are the harness.
If you have used an AI coding tool or an “AI agent” recently and wondered what the difference is between that and just chatting with a model, this post is for you. The answer has a name now: the harness. And the practice of building a good one is called harness engineering.
No prior background needed. We will build the idea up from scratch.
What is a harness? The one-sentence version
A harness is all the engineering wrapped around an AI model that turns a raw text generator into something that can reliably get real work done.
Here is the whole idea in one picture:
flowchart LR
A["Raw model"] -->|"text in, text out"| B["Just words"]
C["Model + Harness"] -->|"tools, memory, checks, limits"| D["A finished task"]
style A fill:#d0bfff,stroke:#8b5cf6
style C fill:#d0bfff,stroke:#8b5cf6
style B fill:#ffd8a8,stroke:#d97706
style D fill:#b2f2bb,stroke:#15803dA useful analogy: the model is an engine, and the harness is the rest of the car. A powerful engine sitting on the garage floor does nothing. The transmission, steering, brakes, fuel system, and dashboard are what turn raw horsepower into “I arrived where I wanted to go, safely.” The harness is all of that, for an AI model.
Why a raw AI model is not enough on its own
A large language model on its own is impressive but oddly helpless. Think of it as a brilliant expert with four specific handicaps:
- It forgets everything. Every new conversation starts from a blank slate. It does not remember what you told it yesterday, or even what happened earlier in a long task, unless something feeds that back in.
- It cannot actually do anything. It produces text. It cannot run code, open a file, search the web, or send an email by itself. It can only describe what it would do.
- It cannot reliably check its own work. Ask it for an answer and it will give you one with confidence, whether or not it is correct.
- It cannot stop itself. Left alone in a loop, it can happily retry the same broken thing forever, or quietly expand a small task into a huge one.
A raw model is like a world-class chef locked in a room with no ingredients, no stove, no memory of the order, and no way to taste the dish. Enormous skill, zero output. The harness hands them the kitchen.
The heart of a harness: the agent loop
Everything in a harness exists to support one central thing: a loop.
A person doing a real task naturally works in a cycle. Look at the situation, decide the next step, do it, check whether it worked, then repeat until done. An agent works the same way. This is the engine room of every harness:
flowchart LR
O["1. Observe<br/>look at the current state"] --> P["2. Plan<br/>decide the next step"]
P --> A["3. Act<br/>run a tool, edit a file"]
A --> V["4. Verify<br/>did it work?"]
V -->|"not done yet"| O
V -->|"done"| Done["Return the result"]
style O fill:#a5d8ff,stroke:#2563eb
style P fill:#fff3bf,stroke:#d97706
style A fill:#ffd8a8,stroke:#d97706
style V fill:#b2f2bb,stroke:#15803d
style Done fill:#c3fae8,stroke:#0e7490The model is the part that does the planning. The harness drives the loop around it: it gathers what the model should observe, executes the action the model chose, runs the check, and decides whether to go around again.
Two things this loop must get right, because they are where most real-world agents break:
- Stop when appropriate. No retrying forever. No quietly turning “fix this typo” into “rewrite the whole app.”
- Be able to verify or admit defeat. A good agent checks its work or says “I could not do this,” instead of confidently handing back something wrong.
The layers of a harness, around the loop
The loop is the heart. Wrapped around it are a handful of supporting layers, each solving one of the model’s handicaps. Here is how they stack up:
flowchart TB
M["THE MODEL<br/>(the only part that is not the harness)"]
M --> Loop["THE LOOP<br/>Observe to Plan to Act to Verify"]
Loop --> L1["Context: what the model is allowed to see this step"]
Loop --> L2["Tools: how the model acts on the real world"]
Loop --> L3["Memory: what carries over between sessions"]
Loop --> L4["Sandbox: a safe place where actions actually run"]
Loop --> L5["Permissions: what the agent is allowed to do"]
Loop --> L6["Observability: a record of what happened"]
style M fill:#d0bfff,stroke:#8b5cf6
style Loop fill:#e5dbff,stroke:#8b5cf6
style L1 fill:#a5d8ff,stroke:#2563eb
style L2 fill:#ffd8a8,stroke:#d97706
style L3 fill:#c3fae8,stroke:#0e7490
style L4 fill:#fff3bf,stroke:#d97706
style L5 fill:#ffc9c9,stroke:#dc2626
style L6 fill:#eebefa,stroke:#a21cafHere is each layer in plain language, and the simple test of whether you need it: what breaks if it is missing?
| Layer | What it does | What breaks without it |
|---|---|---|
| Context | Decides what information to put in front of the model each step | The model is either starved of facts it needs, or buried in irrelevant noise |
| Tools | Lets the model run code, search, call an API, edit a file | The model can only talk about doing things, never do them |
| Memory | Saves state so the next session is not blind | Every session starts from zero and repeats work |
| Sandbox | An isolated space where actions run safely | A mistake can damage real systems or leak data |
| Permissions | Defines and enforces what the agent may and may not do | The agent can take actions it should never have been allowed to |
| Observability | Records traces, costs, and failures | When something breaks, nobody can tell what happened or why |
A nice mental shortcut: context is what goes in, tools are how it acts out, memory is what stays, and sandbox, permissions, and observability are the safety rails that make the whole thing trustworthy.
Context and memory are the layers most teams underinvest in. If you want to go deeper on the “what goes in” side, see Get Organized for AI, which is really a story about context and memory at human scale.
A worked example: “the checkout test is failing, fix it”
Abstract layers are easy to forget. Let us watch them all work together on a real task. Imagine you tell a coding agent:
“The checkout test is failing. Please fix it.”
Here is what happens behind the scenes, layer by layer:
sequenceDiagram
participant You
participant Harness
participant Model
participant Sandbox as Sandbox + Tools
You->>Harness: The checkout test is failing, fix it
Note over Harness: Context layer picks the<br/>relevant files to show
Harness->>Model: Here is the task plus the test code
Model->>Harness: Plan, first run the test to see the error
Harness->>Sandbox: Run the test (permission, allowed)
Sandbox->>Harness: Error, null value on line 42
Note over Harness: Observation fed back in
Harness->>Model: Here is the error
Model->>Harness: Edit line 42 to handle the null, then re-run
Harness->>Sandbox: Apply edit and run test
Sandbox->>Harness: All tests pass
Harness->>Model: Verify, is it green?
Model->>Harness: Yes, done
Harness->>You: Fixed. Here is exactly what changed.
Note over Harness: Observability logged every stepNotice that the model never touched your computer directly. It only ever decided what to do next. Every real action (running the test, reading the error, editing the file) went through the harness:
- Context chose which files were worth showing the model, so it was not drowning in your whole codebase.
- Tools gave it the ability to run the test and edit a file.
- The sandbox ran that code in an isolated space, so a bad edit could not break anything important.
- Permissions allowed “run the test suite” but would have blocked something like “delete the production database.”
- Verify in the loop is what caught success: the agent confirmed the test was green before declaring victory.
- Observability quietly logged every step, so if it had gone wrong, you could see exactly where.
Swap the coding agent for a research assistant or a customer-support agent and the shape is identical. Only the tools change.
Why harness engineering matters more than people expect
Here is the part that surprises most people. The gap between what an AI model can do and what you actually see it do is, more often than not, a harness problem, not a model problem.
A widely-cited experiment from the team at LangChain made this concrete. They took the same model and only changed the harness around it. That single change moved a coding agent from roughly rank 30 to rank 5 on a public benchmark. Same brain, very different results, purely because of the machinery around it.
Treat any single benchmark with a pinch of salt, but the direction holds across the field:
A decent model with a great harness beats a great model with a bad one.
This is why “harness engineering” became a job worth naming. As models get more interchangeable, the durable craft is increasingly in the harness. It is the same reason we build agent-native products rather than bolting a chat box onto an existing app.
The catch: the layers are not really separate boxes
One honest warning, so you do not walk away with a too-tidy picture.
The clean diagram above is a teaching tool, not an architecture you can build one box at a time. In real systems, these layers leak into each other constantly:
- Context and memory blur together: what you remember is part of what you show the model.
- Verification only works if observability is already capturing the right information.
- Permissions are meaningless without a real sandbox to enforce them.
So treat the layers as a checklist of concerns you must handle, not as finished components you can tick off. The moment a team says “we have a memory layer, that is done,” is usually the moment things start getting brittle.
TL;DR
- A model on its own just produces text. It forgets, cannot act, cannot check itself, and cannot stop itself.
- A harness is everything wrapped around the model that fixes those gaps. Agent = Model + Harness.
- At its heart is a loop: observe, plan, act, verify, repeat until done.
- Around the loop sit a few layers: context, tools, memory, sandbox, permissions, observability.
- The harness often matters more than the model. A great harness with an okay model beats the reverse.
- The layers are concerns to handle, not clean boxes. In real systems they overlap, and pretending they do not is where things break.
If you remember one line, make it this one: the model is the engine, and the harness is the rest of the car.