← Blog

Context, Harness, Loop

July 15, 2026 AIAgentsEngineering

Two teams ship an agent on the same model. One is dependable enough to run untrusted work in production. The other loops, forgets, and quietly does the wrong thing. The weights are identical. The difference is everything wrapped around them.

That wrapper is not one thing. It is three, and they fail for different reasons and get fixed in different places. Calling all of it “prompt engineering” is why so many agents feel like they are held together with tape.

Loop: how steps become a task Harness: what it can do Context: what it sees this step Model

Context is the input to a single step. Harness is the set of actions available and how the world answers. Loop is the control flow that turns one step into a finished task. The model sits in the middle of all three and changes nothing about itself.

Context: what the model sees this step

The context window is not storage. It is attention. Every token you add competes with every other token for the model’s focus, and past a point, more context makes the output worse, not better. A window stuffed with forty files the model does not need is not thorough. It is noisy.

So context engineering is a budgeting problem. The system prompt, the tool schemas, retrieved docs, memory, the running conversation, and every tool result all draw from the same account. The job is signal per token, not tokens.

The techniques all reduce to getting the right thing in front of the model at the right moment:

  • Retrieve, do not stuff. Pull the three relevant functions, not the whole repo.
  • Compact. Summarize the resolved parts of a long run so the window holds conclusions, not transcripts.
  • Isolate with subagents. A sub-agent can read forty files and hand back two hundred tokens. The parent gets the answer without paying for the haystack.
  • Load tool schemas just in time. A harness with two hundred tools does not need all two hundred definitions resident on every step.

If a smart human with the same information on screen would get the task right, and the model does not, you usually have a context problem. It is not seeing what it needs to, or it is drowning in what it does not.

Harness: what the model can do

The harness is the body. It decides which actions exist, how results come back, and what the agent is allowed to touch. A model with a bad harness is a brain with no hands.

Tool design is where most of the leverage sits, and the mistake is almost always the same: tools that return raw dumps instead of conclusions. A search tool that returns five hundred lines of matches has pushed the real work back onto the model and burned the context budget doing it. A search tool that returns the answer has done its job. Return the conclusion, not the pile you found it in.

The environment also has to answer in a way the model can act on. An error that says exit code 1 teaches nothing. An error that says which file, which line, and what was expected turns a dead end into the next step. Hooks that inject feedback after a tool runs are part of the harness too: they are how the world talks back.

And some things should never be the model’s job. Deduplication, filtering, sorting, enforcing a hard budget: these are functions. If a plain function can do it reliably, do not spend a model call and a prayer on it. Push determinism into the harness and save the model for the parts that actually need judgment.

This is also where safety lives. At Aster the whole point of the harness is that untrusted code runs in a container with no network and a memory cap, and nothing it touches outlives the request. The model never gets the choice to phone home because the harness never gave it the option. Capability is a design decision, not a hope.

If the model clearly knows what to do but literally cannot do it, or the result comes back in a form it cannot use, that is a harness problem. No prompt fixes a missing tool.

Loop: how steps become a task

A single model call is one step. A task is many steps with a condition that says when to stop. The loop is that structure, and it is the layer people skip.

The naive version is a while loop: call the model, run the tool it asked for, feed the result back, repeat. It works right up until the agent does not know it is done, or spins on the same failing action, or produces something wrong and confidently moves on because nothing ever checked.

The stopping condition is the hard part, and the underrated one. “Keep going until done” is not a condition a model reliably evaluates about its own work. Better loops make the structure carry it:

verify-loop.ts
// don't trust a single pass. produce, then adversarially check.
let bugs = await find(diff);
const verified = [];
for (const bug of bugs) {
  const votes = await Promise.all(
    reviewers.map((r) => r.refute(bug)) // each tries to prove it wrong
  );
  if (votes.filter((v) => !v.refuted).length >= 2) verified.push(bug);
}

The shapes worth knowing:

  • Verify, do not assume. Generate, then run an independent check whose job is to refute. A finding that survives skeptics is worth more than three that never faced one.
  • Loop until dry. For open-ended discovery, keep going until N rounds in a row surface nothing new. A fixed count of tries stops before the tail.
  • Fan out and pipeline. Independent work runs in parallel; a barrier only where a stage genuinely needs every prior result at once.
  • Bound the loop. Cap it on a budget or a round count so a bad run degrades instead of running forever.

Multi-agent orchestration is just this layer taken seriously: an outer loop running inner loops, each with its own context and harness. If the model gets individual steps right but the task as a whole comes out wrong, the bug is in the loop, not the prompt.

Same failure, three fixes

Take one symptom: an agent reviewing code keeps missing real bugs. The instinct is to rewrite the prompt. But the fix depends entirely on the layer:

not seeing the file output truncated single pass, no check Misses real bugs Which layer? Context: retrieve related code Harness: return full, structured results Loop: add an adversarial verify round

If it never sees the caller of the function it is judging, that is context. If its search tool truncates at fifty lines and the bug is on line sixty, that is harness. If it reads everything correctly but does one pass and never double-checks, that is loop. Three different repairs, and only one of them is the prompt. Guess wrong and you tune the prompt for the tenth time while the truncated tool quietly keeps hiding the bug.

The diagnostic is worth internalizing. Would a capable human get it right with the same thing on screen? Context. Can the agent even take the action, and can it use what comes back? Harness. Do the steps work but the task does not? Loop.

Where the lines blur

The taxonomy is a lens, not a law. Compaction is context work that only makes sense because of the loop. A subagent is all three at once: its own context, its own tools, a step in the parent’s loop. The boundaries move depending on where you stand.

That is fine. The point of naming the three layers is not to file every technique into exactly one box. It is to stop reaching for the prompt every time an agent misbehaves. Most unreliable agents are not running a bad model. They are running a good one that cannot see what it needs, cannot do what it should, or has no structure telling it when it is finished. Fix the layer that is actually broken.