Harness vs context engineering: how harness engineering differs from prompt and context engineering
Prompt engineering improves the wording of a single request, context engineering decides which information reaches the model's window at each step, and harness engineering builds the whole environment of the agent: instructions, tools, the execution environment, state between sessions and feedback loops. The first two work inside a single model call, while the harness works at the level of the whole system and long tasks, where the goal is not an answer but a verified result.
In short: three levels of one task
Prompt engineering answers "how to ask", context engineering answers "what the model must know right now", and harness engineering answers "in what environment the agent works and how it learns that it made a mistake". These are not three competing approaches but nested levels: a good prompt is part of good context, and well-designed context is one of the harness subsystems.
Confusion arises because all three change the model's behavior, but their levers are different. If the agent cannot run the tests, no wording of the prompt will fix that. If the agent forgets yesterday's decisions, the problem is not the words of the request but where the state is stored. Understanding the difference between harness vs context engineering saves weeks: you stop rewriting instructions where the environment is broken.
Prompt engineering: the wording of a single request
Prompt engineering is working with the text of a request: role, task, output format, examples (few-shot), constraints, order of steps. The unit of work is one model call. The result is judged by the answer: is it correct, is it in the right format, did the model stay on topic.
Typical techniques:
- describe the output format explicitly (a JSON schema, a table, a list);
- give 2–3 examples of "input → correct output";
- ask for step-by-step reasoning before the answer;
- separate instructions and data with clear delimiters;
- list what must not be done.
Prompt engineering works well for "one input — one output" tasks: classification, data extraction, translation, text generation from a template. Its ceiling becomes visible when the model starts acting: calling tools, changing files, working through dozens of steps in a row. There, quality depends no longer on a single phrase but on everything around the model.
Context engineering: what goes into the model's window
Context engineering is managing the contents of the context window at each step. The window is limited, and during a long session the agent accumulates command output, file contents and dialogue history. The task is to have what is needed at every moment and nothing superfluous.
This includes:
- selection: which files, documents and code fragments to load for the task (search, RAG, reading on demand);
- compression: summarizing a long history, trimming command output, compacting the session;
- structure: an entry instructions file as a table of contents, with details in separate documents that the agent opens when needed;
- isolation: moving a subtask into a sub-agent with its own clean context so the main thread does not get cluttered.
The metric of context engineering is whether the agent found the right rule or fact at the right moment and did not drown in noise. A typical symptom of the problem: a rule is written in CLAUDE.md, but the agent breaks it, because the file runs to five pages and the rule got lost among the tone of voice and the favorite patterns of the team lead.
Harness engineering: everything around the model
The harness ("the gear") is the environment in which the agent works. The model is one component in it, which enters the loop once. Everything else — instructions, tools, environment, state and feedback — is designed by an engineer. Harness engineering is responsible for ensuring that the agent can not only write code but also run it, check it, learn about a mistake and continue the next session from the same place.
It is convenient to break the harness into five subsystems:
| Subsystem | What is included | Sign of breakdown |
|---|---|---|
| Instructions | AGENTS.md / CLAUDE.md, skills, docs, ADRs | The agent breaks conventions "everyone knows about" |
| Tools | shell, tests, linter, debugger, browser, MCP servers | The agent "wants to but cannot": no access to the needed command |
| Environment | dependency lock files, runtime versions, Docker/devcontainer, git worktree, sandbox | Every session starts with fixing the environment |
| State | PROGRESS.md, feature_list.json, DECISIONS.md, git history | A new session does not know where things stopped |
| Feedback | make check, E2E tests, hooks, rubrics, an independent verifier | "Done" does not match reality |
In this scheme context engineering lives inside the first two subsystems: it decides how instructions and tool output get into the window. The harness adds what cannot be put into the context: a working check command, a reproducible environment, a state file that survives a restart.
Comparison table
| Criterion | Prompt engineering | Context engineering | Harness engineering |
|---|---|---|---|
| Unit of work | One request | The model's window at each step | The whole system: agent, repository, environment, processes |
| What it changes | The text of the request | The composition and order of information in the window | Tools, environment, state storage, checks |
| Horizon | Seconds | One session | Many sessions, hours and days of work |
| What it measures | Answer quality | Whether the agent found what it needed and whether the window overflowed | Share of tasks really brought to a working state; the gap between "done" and verified |
| Typical artifacts | System prompt, examples | Docs structure, RAG, compaction, sub-agents | AGENTS.md, check scripts, hooks, Docker, feature_list.json, PROGRESS.md |
| Who checks the result | A human reads the answer | A human or a model | A machine: tests, linters, E2E, a separate verifier |
| When it hits the ceiling | When the model starts to act | When the agent lacks capabilities, not knowledge | When the task requires a human decision (product, risks) |
Why one prompt and context are not enough
A classic story: the team sees that the agent makes mistakes and spends a week writing a five-page AGENTS.md. The agent still does not run the linter before committing. The reason is not the text: the agent simply has no shell access with the right permissions, and the linter is not installed in the image. This is a problem of tools and environment, and it was being treated with instructions.
A second story: for the third session in a row the agent is fixing the same bug, because after a restart it does not remember what it already tried. Context engineering within a session will not help here: the window is cleared. What is needed is the state subsystem — a file where the agent records attempts and decisions, and a rule to read it at the start of work.
The third story is the most expensive: the agent writes "done", unit tests are green, but the feature does not work. Neither a prompt saying "check carefully" nor extra documents in the context will give the agent an independent check. Only feedback from a machine can do that: an end-to-end test, a verification script, a separate verifier with no access to the executor's reasoning.
The general conclusion: the prompt and the context influence what the model thinks. The harness influences what the model can do and what it learns after an action.
Why replacing the model does not help
A common reaction to an unstable agent is to take a more powerful model. Usually this does not cure the problem: the same model works like a confident senior in a well-organized repository, but gets lost in a repository without check commands and without a description of the stack. A stronger model will not guess your team's conventions, will not get access to a database it was not given, and will not learn about a broken migration if nobody ran it.
At the same time, the harness does not become obsolete when new models come out. Instructions, a reproducible environment and checks are needed by any model. What changes is how much manual micromanagement can be removed: a strong model needs only invariants ("data is validated at the domain boundary"), not step-by-step instructions.
How to tell which level to fix
Diagnosis by symptoms is faster than any experiment:
| Symptom | Where the problem is | What to do |
|---|---|---|
| The answer is in the wrong format, the model did not understand the task | Prompt | Clarify the format, add examples |
| The rule is written, but the agent does not apply it | Context / instructions | Shorten the entry file to a table of contents, move details to docs loaded on demand, turn the important rule into a check |
| Mid-session the agent "forgets" early decisions | Context | Compaction, sub-agents for side tasks, entries in a state file |
| The agent says "I cannot run it" | Tools | Give access to the command, MCP server, permissions |
| The session starts with installing dependencies and fixing the environment | Environment | Lock files, Docker/devcontainer, an init.sh script |
| A new session asks what was done yesterday | State | PROGRESS.md, a list of features with statuses, checkpoint commits |
| "Done", but the feature does not work | Feedback | E2E, Definition of Done, a verification script, an independent verifier |
Where to start with the harness
If you build from scratch, a practical order is: feedback → instructions → state → environment → tools. Feedback comes first, because without it you cannot measure the effect of the other changes. As long as there is no command that honestly answers "works or not", any improvement to the instructions is judged by eye.
A minimal start looks like this:
# AGENTS.md (excerpt)
## How to check
- make check # lint, types, unit tests
- make e2e # end-to-end scenarios
A feature is ready only if both commands finish with exit code 0.
## Rules
- MUST: all SQL queries are parameterized
- MUST: run make check before committing
- Payment details: docs/payments.md (read when the task involves payments)
Pay attention to the last line: this is context engineering inside the harness. The entry file is a map, not a textbook; details are loaded under a "when" condition.
How to measure the contribution of each part
The harness has a metric that a prompt does not: the share of tasks the agent declared ready that independent verification did not confirm. It is called the verification gap. Take 10 tasks in a row, and for each mark whether the agent said "done" and whether the check passed — you get a number to compare changes against.
To see which subsystem has an effect, people use ablation: fix the model and the set of tasks, then switch off one part of the harness at a time and watch the drop. Two things matter here. It is better to start not with ablation but with a failure log: labeling at which layer things broke will show the bottleneck faster. And a zero drop does not prove that a component is useless: it may simply not have been exercised by the chosen tasks.
Common mistakes
- Treating a prompt file as the harness. Instructions are one of five subsystems. A shelf of recipes is not yet a kitchen.
- Fixing missing tools with text. "Always run the tests" is useless if the tests cannot be run in the agent's environment.
- Bloating the instructions. The longer the entry file, the higher the chance that an important rule is not read. Important rules are better turned into executable checks.
- Trusting the agent's self-report. A model that evaluates its own work tends to overrate it. A script or a separate agent with a clean context must check it.
- Setting up the harness once. It goes stale, like code: rules drift from reality and commands change. It must be reviewed regularly.
Summary
Prompt engineering improves the wording, context engineering selects what goes into the model's window, and harness engineering covers the whole environment of the agent, including tools, the environment, state and checks. When an agent works for a long time and changes code itself, the harness becomes the main thing: it turns "the agent said done" into "the system verified that it works". So the choice in the harness vs context engineering debate is not either/or: context is part of the harness, and you should fix the subsystem the symptoms point to. This topic is covered in practice in the harness engineering course on an end-to-end payment backend project.
FAQ
Does harness engineering replace prompt engineering?
No, it includes it. The wording of instructions still matters, but it is just one of five subsystems alongside tools, environment, state and feedback.
Do I need a harness if I use an agent only for small edits?
A minimal one is always useful: an instructions file with the stack and the check command. The full set with a feature list and an evaluator pays off on long tasks and in teams.
How is context engineering different from RAG?
RAG is one technique of context engineering: searching and loading relevant fragments. Context engineering is broader and includes history compression, documentation structure and isolating subtasks in sub-agents.
Which part of the harness should I build first?
Feedback: a command that answers mechanically whether the result works. Without it, the effect of other improvements cannot be measured.
Does harness engineering apply to any agent, not only Claude Code?
Yes. The principles are general: many agents read AGENTS.md, and check scripts, Docker, state files and E2E tests do not depend on a specific tool.
This topic is covered in depth with practice in the course “Harness Engineering: Engineering Reliability for AI Agents”.
- What Is Harness Engineering? Why AI Coding Agents Fail Because of the Environment
- What an AI Agent Harness Is Made Of: Instructions, Tools, Environment, State, Feedback Loops