
Every conversation about building with AI still opens with the model. Which one, how new, how large. That has quietly become the least interesting question in the room. Frontier models are close enough in capability that the difference between an agent which closes a ticket and an agent which burns an afternoon is almost never the model.
The difference is the system built around it, and that system is three disciplines answering three questions. What does the agent know at the moment it acts? What can it actually do, and what can it break? How does it keep going, and what makes it stop?
Context engineering, harness engineering, loop engineering. None of them are vendor features you can buy. All three are ordinary engineering work, and they are the part most teams skip on the way to a demo.
Three questions, three disciplines
| Discipline | The question it answers | Under-built, it looks like |
|---|---|---|
| Context engineering | What is in the working set when it acts? | Confident, well-formed work built on the wrong facts |
| Harness engineering | What can it do, and what can it break? | A correct plan with no safe way to execute it |
| Loop engineering | How does it proceed, and when does it stop? | Motion without progress, and a bill to match |
Most teams build them in that order, because each one makes the next worth doing. Context without a harness produces good advice you still have to type in yourself. A harness without a loop produces one action rather than finished work.
Context engineering: what the agent knows

Prompt engineering is the wording of one message. Context engineering is the composition of the entire working set: the system prompt, the tool definitions, project rules, retrieved files, prior tool output, conversation history, and whatever state was carried forward from the last step. The model sees exactly that and nothing else. Everything it gets wrong that it should have known is a context decision, not a model failure.
The window is a budget, not a bucket
A large context window invites you to put everything in it, on the theory that more information cannot hurt. It can. Attention is a finite resource spread across the whole window, and retrieval gets less reliable as the window fills, especially for facts buried in the middle of a long input. A window packed with everything is a window where the three files that matter compete with a repository dump.
So set a target: the smallest set of high-signal tokens that makes the next decision correct. The empty space is not waste. It is where the reasoning, the long tool output and the recovery from a mistake have to fit.
Four moves that do the work
- Select. Retrieve at the last responsible moment. A file path and a search tool almost always beat a pre-loaded codebase, because the agent fetches what this step needs instead of everything the task might touch.
- Compress. When a phase of work is finished, replace the transcript with its outcome: the decisions taken, the things ruled out, the questions still open.
- Isolate. Give a noisy sub-task its own window and let it return the answer rather than the exploration. A search that took forty tool calls should arrive as a paragraph.
- Persist. Write down what has to outlive the session, because the window will not.
What deserves to be written down
The persistent layer holds most of the leverage and is the cheapest thing here to build. Agents do not fail on your codebase because they are weak. They fail because nobody ever wrote down how this system is meant to be built.
- Conventions the code implies but never states: error handling, logging, folder structure, naming.
- Architecture decisions and the reasoning behind them, so nobody helpfully undoes one.
- API and data contracts other teams depend on.
- Runbooks: how to run the tests, seed the database, reproduce a bug locally.
- Incidents: what broke before, and what the fix actually was.
- The definition of done for a change in this repository.
If a new engineer would need to be told it in their first week, an agent needs it in the context. The difference is that the agent will not ask.
Harness engineering: what the agent can do

The harness is everything between the model and reality: the tools it can call, the schema of those tools, the permissions around them, the sandbox it runs inside, and the shape of the results that come back. The same model in a different harness is, in practical terms, a different worker.
This is the layer that turns advice into work. A model with no tools can only describe a fix. A model with a file editor can produce a diff. A model that can also run the suite produces a diff with evidence that it works. The intelligence did not change. The reach did.
Tools are an interface for a reader who never asks a follow-up question
Hand an engineer an ambiguous API and they will ask what you meant. An agent will guess, plausibly, and you will find out two steps later.
- One job per tool, with a name that says which one. Two tools with overlapping purposes turn tool selection into a coin flip.
- Parameters that cannot be read two ways. Absolute paths rather than “the file”. Enumerations rather than free text wherever the set is known.
- Output written to be read, not dumped. Truncate long results, paginate, and say what was cut and how to get the rest.
- Errors that name the fix. “No such path: src/content.ts. Did you mean src/lib/content.ts?” saves an iteration every time it fires.
- Misuse made hard rather than documented. A tool that can only do the safe thing needs no warning in the prompt.
Every one of these is also a context decision. Tool definitions sit in the window on every single turn, which makes them the most expensive text in the system. Forty tools is usually a sign that the work wanted splitting across more than one agent.
Reach sized to consequence
Permissions are not a checkbox bolted on at the end. They are the design of the blast radius, and they belong in the first version.
| Action | Sensible default | Why |
|---|---|---|
| Read and search the source | Allow | Reversible, and the alternative is guessing |
| Edit files on a scratch branch | Allow | The branch is the sandbox |
| Run the test suite | Allow | This is the feedback the loop depends on |
| Reach the network, add a dependency | Ask | Supply chain and cost, both hard to undo quietly |
| Merge, deploy, run a migration | Human | The consequence outlives the session |
The rule underneath the table: automate what is reversible, gate what is not. When you widen a permission, widen it because the loop earned it, not because the approval prompts got annoying.
Errors are the highest-leverage prompt you will write
In an agentic system an error message is not a log line for a human to read tomorrow. It is the model's next input. A stack trace ending in “connection refused” produces a retry. The same failure reported as “connection refused on localhost:5432; the database container is not running; start it with docker compose up db” produces a fix.
Every failure your harness can emit is a place to write instructions that arrive at exactly the moment they are needed. Most teams have this backwards: hours spent tuning the system prompt, none spent on the message the agent will actually read when it is stuck.
Loop engineering: how it keeps going, and when it stops

The loop is the iteration itself: gather what this step needs, take one scoped action, verify it, then decide whether to continue, stop or hand over. Loop engineering is deciding what each of those words means in your system. It is where autonomy is either earned or faked.
No verifier, no loop
The largest single difference between an agent that improves across iterations and one that drifts is whether something outside the model can say no. Without it the agent grades its own homework, and the loop optimises for looking finished rather than being finished.
- A test suite that fails for the right reasons.
- A type checker and a linter: cheap, fast and merciless.
- The application actually running, with a screenshot or a health check to prove it.
- Output compared against a known-good result.
- A human, on the decisions that carry real risk.
The verifier does not need to be sophisticated. It needs to be outside the model and hard to argue with. This is also why agentic delivery lands first in codebases with good tests: the verifier is already built and nobody has to be talked into it.
Three ways a loop should end
- Done. The verifier passed, and the change leaves the loop with the evidence attached.
- Out of budget. Attempts, wall clock or spend hit a cap. It stops and reports what it tried, which is more useful than trying harder.
- Escalated. The next step needs a decision a human owns, so it hands over with context instead of guessing.
“Keep going until it works” is not a fourth option. It is the absence of design, and it is how a loop becomes an outage with a credit card attached.
The failure message is the next input
A well-built loop repairs rather than restarts. The failing test name, the type error, the review comment that rejected the diff: that is the most useful context the system will ever have about this task, and it arrives for free. A loop that throws it away and starts the next attempt from the original prompt is discarding the only thing it learned.
The outer loop
Inside a task the loop is gather, act, verify, decide. Around the task there is a slower one: ship the change, watch it in production, compare it against the metric it was supposed to move, and write the next intent from what you find. Teams that build only the inner loop get very fast delivery of things nobody asked for.
Reading a failure back to its discipline
Almost every version of “the AI is not working” resolves cleanly to one of the three.
| Symptom | Usually | Fix it in |
|---|---|---|
| It ignored our conventions | Nobody ever wrote them down | Context |
| It rewrote code it should not have touched | The task boundary and the relevant files were never stated | Context |
| Quality collapsed late in a long session | The window filled and the early instructions got crowded out | Context |
| It produced a plausible diff that does not run | Nothing ran it | Loop |
| It burned an hour and delivered nothing | No budget, no stop condition | Loop |
| It went in circles on the same error | The failure message said nothing actionable | Harness |
| It did something it should never have been able to do | The permission was wider than the consequence | Harness |
| It asks for approval on everything | Gates were placed per tool rather than per consequence | Harness |
Where to start
In this order, because each step makes the next one worth doing.
- Write the context that does not exist yet: conventions, architecture decisions, how to run and test the thing. A day of writing that pays out on every task afterwards.
- Give the agent one verifier it cannot argue with, runnable in a single command.
- Scope the harness to one reversible workflow: a branch, a sandbox, and tools that read, edit and run.
- Put a budget and a stop condition on the loop before you widen anything.
- Instrument it: acceptance rate, human review time, cost per change.
- Then, and only then, lengthen the leash.
Most teams can work through that in weeks rather than quarters. The constraint is almost never the model.
What to measure
| Metric | What it tells you |
|---|---|
| Agent acceptance rate | How much of the autonomous output survives review untouched |
| Human review time per change | The cognitive load the system is placing on your engineers |
| Iterations to a passing verifier | Whether the loop is repairing or thrashing |
| Escalation rate | Whether the gates are in the right places |
| Cost per shipped change | The economics, retries and abandoned attempts included |
| Defect escape rate | Whether the speed is being paid for in production |
Our view
The three disciplines have one thing in common: they are ordinary engineering. Deciding what a system knows, bounding what it can do, and designing how it iterates are problems we have always had. The novelty is that the component in the middle is probabilistic and reads English.
That is the good news, too. The advantage does not come from picking the right model this quarter, because that keeps changing. It comes from the system around it, which compounds. Swap the engine and a well-built system keeps working.
If you are starting from nothing, pick one workflow that is repetitive, measurable and reversible. Write down what the agent needs to know. Give it one verifier and one budget. Then read what actually happened before you widen anything.