Skip to content

All lessons

Area 03 // AI AgentsLesson 55 / 14017 min read

Harness engineering: everything around the model

An agent is a model plus a harness, the system around it (instructions, tools, context management, permissions, hooks, verification and memory), and harness engineering is designing that system so the agent works reliably; in 2026 it became the main place teams invest after prompt and context engineering.

Think of it like this

Analogy

A brilliant new surgeon still needs an operating theatre: a checklist read aloud before every operation, instruments laid out in order, monitors that beep when something's wrong, a nurse who counts the swabs before closing, and rules about who may do what. The surgeon is the model. The theatre, checklists, monitors and rules are the harness. Put the same surgeon in a badly run theatre and outcomes get worse; improve the theatre and every surgeon gets better.

The problem it solves

Teams often try to fix an unreliable agent by swapping models or polishing the prompt. But many failures aren't about intelligence: the agent didn't know the project's test command, forgot a rule halfway through, edited a file it shouldn't touch, declared victory with failing tests, or lost track after its context filled up. Those are failures of the system around the model.

In 2026 this system got a name, the harness, and designing it well, harness engineering, became one of the main skills of AI engineers building agents.

How it works: harness engineering

Harness engineering is designing every part of an agent harness deliberately. The usual parts:

  1. Instructions: the system prompt and project instruction files (next section).
  2. Tools and skills: the actions available (tool calling, MCP) and the procedures it can load (skills).
  3. Context management: what the model sees each step, compaction, sub-agents (context engineering).
  4. Permissions and sandbox: what the agent may read, write and run, where (least privilege).
  5. Hooks and mechanical enforcement: code that runs at fixed points to block or fix things (section below).
  6. Verification: tests, linters, type checks, evals that decide whether "done" is really done.
  7. State and memory: plans, notes and checkpoints that survive long tasks and restarts (memory, checkpoints).
  8. Observability: traces of every step, cost and outcomes, so you can see why it failed (tracing).
  9. Feedback: turning observed failures into harness changes (a new rule, a new hook, a better tool), then measuring.

From prompt engineering to loop engineering

The field's vocabulary grew in layers, each wrapping the previous one:

LayerQuestion it answersTypical work
Prompt engineeringHow do I phrase the instructions?System prompts, examples, formats (lesson 20)
Context engineeringWhat should the model see right now?Retrieval, memory, compaction, tool results (lesson 52)
Harness engineeringWhat system makes the agent reliable?Tools, permissions, hooks, verification, state, tracing (this lesson)
Loop engineeringHow do agents run repeatedly without me?Triggers, maker-checker loops, budgets, schedules (lesson 61)

None replaces the others: a good loop runs a well-harnessed agent, whose harness manages good context, which contains good prompts.

How it works: instruction files

  1. An instruction file lives in the repository, commonly AGENTS.md (a cross-tool convention) or tool-specific names such as CLAUDE.md. Coding agents read it at the start of each session.
  2. Put in it what a new teammate would need: how to install, build, test and lint; project structure; conventions; things never to touch; how to verify work.
  3. Keep it short and specific: commands and rules, not essays. Every line costs context on every session.
  4. Nest them where tools support it: a root file for the repo, smaller files in sub-folders for local rules.
  5. Version and review it like code; update it when the agent repeatedly gets something wrong.

How it works: hooks and mechanical enforcement

  1. A hook is code the harness runs automatically at a fixed point: before a tool call, after a file edit, when the agent says it's done, when a session starts or ends.
  2. Block: a pre-tool hook refuses dangerous commands (rm -rf, force-push, editing protected paths), whatever the model intended.
  3. Fix: a post-edit hook runs the formatter, so style never depends on the model remembering.
  4. Verify: a "before done" hook runs tests and rejects completion if they fail.
  5. Record: hooks log actions for audit.
  6. Back it up with CI: linters, structural tests and eval gates enforce the same rules on every change, agent-made or human-made.
  7. The principle: instructions guide; hooks, tests and CI enforce. Anything that must always hold should be enforced mechanically.
The harness wraps the model: every action passes through rules, tools and checks the harness controls.

See it in code

Needs
Nothing: plain Python 3.

Two harness pieces: an instruction file the model reads, and a pre-tool hook plus a verification gate that the harness enforces in code.

harness_hooks.py
import re
 
# Part of a harness: rules the MODEL reads (instructions) and rules the HARNESS enforces (hooks).
AGENTS_MD = """# Project rules for coding agents
- Run `pytest -q` before saying a task is done.
- Never edit files in migrations/.
- Use the repo's formatter: `ruff format`."""
 
BLOCKED = [r"\brm\s+-rf\b", r"git\s+push\s+--force", r"\bDROP\s+TABLE\b"]
 
def pre_tool_hook(tool: str, args: dict) -> tuple[bool, str]:
    """Runs before EVERY tool call. Code, not a prompt, so the model can't talk its way past it."""
    if tool == "bash" and any(re.search(p, args["command"], re.I) for p in BLOCKED):
        return False, "blocked by policy: destructive command"
    if tool == "edit_file" and args["path"].startswith("migrations/"):
        return False, "blocked by policy: migrations are read-only"
    return True, "allowed"
 
def verify_done(test_exit_code: int) -> str:
    """A verification step the harness runs before accepting 'done'."""
    return "accept" if test_exit_code == 0 else "reject: tests fail, keep working"
 
for tool, args in [("bash", {"command": "pytest -q"}),
                   ("bash", {"command": "rm -rf /"}),
                   ("edit_file", {"path": "migrations/0007.sql"}),
                   ("edit_file", {"path": "app/routes.py"})]:
    print(f"{tool:9} {list(args.values())[0]:22} -> {pre_tool_hook(tool, args)[1]}")
print("model says done, tests exit 1 ->", verify_done(1))
Output
bash      pytest -q              -> allowed
bash      rm -rf /               -> blocked by policy: destructive command
edit_file migrations/0007.sql    -> blocked by policy: migrations are read-only
edit_file app/routes.py          -> allowed
model says done, tests exit 1 -> reject: tests fail, keep working

Real coding agents expose the same idea as configuration: hook scripts that run on events such as "before tool use" or "on stop", and permission rules that allow or deny commands and paths.

A real example

Example

Same model, twice the success rate

A team ran a coding agent on their monorepo. Out of the box, about 40% of its pull requests passed CI. They didn't change the model; they changed the harness:

  • An AGENTS.md with the exact build, test and lint commands per package, and the three folders never to touch.
  • Hooks: format after every edit, block edits to generated code, run the affected package's tests before accepting "done".
  • A narrower tool set (no raw database access) and a sandbox with no network except the package registry.
  • Context: test output trimmed to failures; a PLAN.md the agent updates; compaction at 70%.
  • Tracing, so every failed PR could be traced to the step that went wrong; each recurring failure became a new rule or hook.

Within a month, about 80% of PRs passed CI on the first try.

The easy way

Start here

Start with two things: an AGENTS.md (or CLAUDE.md) listing how to install, run, test and lint your project plus its no-go areas; and one verification rule: the agent must run the tests before saying it's done. Then, every time the agent makes the same mistake twice, turn that lesson into a rule, a hook or a test.

When you grow: the production setup

Mature teams treat the harness as a product: versioned instruction files and skills, hook libraries, sandboxed runtimes with least privilege, structured state and checkpoints, full tracing with cost per task, eval suites for agent tasks (trajectory evals), and a feedback process that turns production failures into harness improvements, then into loops that run agents on schedules and events.

Trade-offs

What you gain

  • Big reliability gains without changing (or paying more for) the model.
  • Rules enforced by code hold every time, for agents and humans alike.
  • Observability makes agent failures fixable instead of mysterious.

What it costs you

  • Real engineering effort: hooks, sandboxes, verification and tracing to build and maintain.
  • Overly strict harnesses can block legitimate work.
  • Instruction files and hooks drift as the project changes.

When not to use it

  • One-off, low-stakes chats don't need a heavy harness; a good prompt is enough.

Common mistakes

  • Blaming the model for failures the harness should prevent.
  • Instruction files that are long essays instead of short, specific commands and rules.
  • Relying on instructions alone for rules that must never be broken.
  • Accepting "done" without running tests or checks.
  • No tracing, so nobody knows which step failed.

Interview questions

Try answering out loud first, then open the model answer.

What is harness engineering?

Model answer

Designing the system around a model that makes it an effective agent: instructions and project instruction files, tool and skill design, context management, permissions and sandboxing, hooks that enforce rules at fixed points, verification before accepting completion, state and memory, and observability, plus a feedback loop that turns failures into harness changes. It's often described as agent = model + harness, and harness improvements frequently beat model upgrades.

What would you put in an AGENTS.md file?

Model answer

Concise, actionable project knowledge: setup, build, run, test and lint commands (per package if needed), repository layout, coding conventions, how to verify a change, areas not to modify, and pointers to deeper docs. It should be short because it's loaded every session, kept current, and backed by mechanical checks for rules that matter.

Why prefer hooks and CI over instructions for important rules?

Model answer

Instructions are probabilistic guidance that models may ignore, misinterpret or forget as context grows; hooks and CI are deterministic and run every time, regardless of what the model intended or was manipulated into. Use instructions to explain and guide, and mechanical enforcement (pre-tool blocks, post-edit formatting, tests, linters, eval gates) to guarantee.

Quiz

Pick an answer to see whether it’s right and why.

  1. 01What is an agent harness?
  2. 02Two teams use the same model. One's coding agent is far more reliable. What most likely differs?
  3. 03What is an instruction file like AGENTS.md or CLAUDE.md?
  4. 04Why enforce "never edit migrations/" with a hook instead of only writing it in AGENTS.md?
  5. 05How do prompt, context, harness and loop engineering relate?
  6. 06What is a verification step in a harness?

0 of 6 answered

Key terms

Harness engineering
Designing the system around a model that makes it a reliable agent, including instructions, tools, context, permissions, hooks, verification, state and tracing.
Agent harness
Everything around the model in an agent, such as instruction files, tools, context management, permissions, hooks, verification and memory.
Instruction file (AGENTS.md)
A file in a repository, such as AGENTS.md or CLAUDE.md, with project rules and commands that coding agents read every session.
Hook
Code a harness runs automatically at a fixed point (before a tool call, after an edit, before finishing) to block, fix, verify or log.
Context engineering
Deciding exactly what goes into the model's context at each step (instructions, tools, knowledge, memory, history, results) within a budget.
Loop engineering
Designing automated loops around agents (triggers, verifiers, stop conditions, budgets, human gates) so they do repeated work without step-by-step prompting.

Before and after

Progress is saved in this browser only.