Back to BlogAI Frameworks

Loop Engineering: Designing Agent Loops That Actually Work

Orioverse Team·
🔁

Loop Engineering: Designing Agent Loops That Actually Work

Anthropic published two posts in 2026 that together form the most detailed guidance available on agent loop design: a deep dive on building effective agents with the Claude Agent SDK, and a full case study on harness design for long-running application development.

This post covers what we learned from these about designing agent loops that converge reliably.

The Standard Agent Loop

Strip away the branding and every agent system is the same skeleton: perceive, decide, act, observe, repeat. Anthropic's guidance on building effective agents defines agents as models using tools based on environmental feedback in a loop. OpenAI says the same thing: a loop of model calls and tool executions that runs until an exit condition fires.

Everything interesting about loop engineering lives in three details: the exit condition, the budget, and what one pass through the body contains.

Context Anxiety and Context Resets

Anthropic's harness design post identified two failure modes that emerge in long-running agents. First, models lose coherence on lengthy tasks as the context window fills. Second, some models exhibit context anxiety - they begin wrapping up work prematurely as they approach what they believe is their context limit.

Their solution for Claude Sonnet 4.5 was context resets: clearing the context window entirely and starting a fresh agent with a structured handoff carrying the previous state and next steps. This differs from compaction (summarizing earlier parts of the conversation in place). Compaction preserves continuity but does not give the agent a clean slate, so context anxiety can persist.

For Opus 4.5, the context anxiety was strong enough that compaction alone was not sufficient. Context resets became essential to the harness design. For Opus 4.6, the improved model largely removed that behavior on its own, so they dropped context resets entirely and relied on the Agent SDK's automatic compaction.

context-reset.tstypescript
type HandoffNote = {
  state: Record<string, unknown>;
  nextSteps: string[];
};

function writeHandoff(note: HandoffNote): string {
  return JSON.stringify(note);
}

async function continueFrom(note: HandoffNote, goal: string) {
  const agent = new Agent({ fresh: true }); // empty context, no history
  return agent.run({
    goal,
    checkpoint: note.state,
    nextSteps: note.nextSteps,
  });
}

// When a run approaches its context limit, serialize and reset:
const note: HandoffNote = {
  state: currentAgent.memory(),
  nextSteps: ["refactor module B", "re-run eval suite"],
};
await save(writeHandoff(note));
return continueFrom(note, "finish module B");

The Generator-Evaluator Pattern

The most interesting pattern in Anthropic's harness is the generator-evaluator loop. It maps onto the software development lifecycle where code review and QA serve the same structural role as a design evaluator.

The harness uses three agent personas:

  • Planner: expands a simple prompt into a full product spec
  • Generator: works in sprints, implementing one feature at a time
  • Evaluator: uses Playwright MCP to click through the running application testing UI features, API endpoints, and database states

Before each sprint, the generator and evaluator negotiate a sprint contract - agreeing on what done looks like before any code is written. The generator proposes what it will build and how success will be verified. The evaluator reviews that proposal. They iterate until they agree.

Communication between agents is handled via files: one agent writes a file, another reads it and responds. This keeps the work faithful to the spec without over-specifying implementation.

generator-evaluator.tstypescript
type SprintContract = {
  spec: string;
  done: string[]; // verifiable acceptance criteria
};

async function generatorEvaluateLoop(
  propose: (spec: string) => SprintContract,
  build: (contract: SprintContract) => unknown,
  verify: (contract: SprintContract, output: unknown) => boolean,
  maxAttempts = 5,
) {
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
    const contract = propose("feature: retro game maker");
    const output = build(contract);
    if (verify(contract, output)) {
      return { contract, output, attempt };
    }
  }
  throw new Error("max attempts exceeded - inspect logs");
}

// verification is code, not opinion:
const result = await generatorEvaluateLoop(
  (spec) => ({ spec, done: ["level editor renders", "entities respond to input"] }),
  buildSprint, // generator implements one feature
  async (contract, output) => {
    // evaluator clicks through the running app with Playwright
    const page = await openApp(output.url);
    for (const criterion of contract.done) {
      if (!(await pageCovers(page, criterion))) return false;
    }
    return true;
  },
);

Verification Is Code, Not Opinion

Anthropic found that out of the box, Claude is a poor QA agent. It identifies legitimate issues, then talks itself into deciding they are not a big deal and approves the work anyway. It also tests superficially rather than probing edge cases.

The tuning loop was the same pattern that works for every agent system: read the logs, find examples where judgment diverged from yours, and update the prompt to solve for those issues. It took several rounds before the evaluator was grading in a way the team found reasonable.

The lesson: verification must be grounded in real tool results, not the model's opinion. A code interpreter that runs the code, a search that checks the claim, a Playwright test that clicks through the UI - these correct reliably where introspection does not.

The Model Upgrade Effect

When Anthropic upgraded from Opus 4.5 to 4.6, the boundary of what the generator could handle solo moved outward. Tasks that used to need the evaluator's check were now within what the generator handled alone. For those tasks, the evaluator became unnecessary overhead. For tasks still at the edge of the generator's capabilities, the evaluator continued to provide real lift.

The practical implication: the evaluator is not a fixed yes-or-no decision. It is worth the cost when the task sits beyond what the current model does reliably solo. When a new model lands, re-examine the harness and strip away pieces that are no longer load-bearing.

Budget Boundaries

Every agent loop needs hard ceilings on iterations, cost, and wall-clock time. Not one of them - all three, because they fail differently. An agent can burn its dollar budget in four iterations of huge context, or run 200 cheap iterations for six hours, or hang on a single tool call overnight.

The important design decision is what happens at the boundary. A loop that hits its budget should not just die - it should land. Commit work-in-progress, write a handoff note, and exit cleanly. Budget exhaustion is a planned exit path, the same as convergence, just with a different report.

Read the full Context Engineering series: orioverse.com/blog/what-is-context-engineering

A Note for Vibe Coders and Non-Technical Users

Everything above assumes you can write TypeScript. If you mostly prompt an AI assistant like Claude, you can still get loop engineering working - you just ask for it in plain English instead of code. Here are the prompts. Paste one in, let it run, and it will loop the same way a well-engineered agent does.

title
I have a long task that will run for a while. As we go, do not just keep going forever. When you are about to run out of room, first write a short handoff note covering: what is complete, what is left, and the next three steps. Paste the note back at the top whenever we start a fresh conversation so we continue without losing progress.

What it does: asks the AI to checkpoint its own state and hand it off into a fresh conversation - the context reset pattern.

title
Before you answer, act as two people: first a Planner, then an Evaluator.
First, write a short plan for what you will do to answer. Then do it. Then check what you delivered against the plan one line at a time, fix anything missed, and only then show me the result.

What it does: makes the AI generate and self-verify - the generator-evaluator loop, in one prompt.

title
If you run out of room or hit a limit while working on this, do not stop silently and do not cut your answer short. List what is done and what is left. Then tell me whether I should start a fresh pass to finish.

What it does: forces a clean exit boundary - the loop reports and lands cleanly instead of dying.

References

  1. https://www.anthropic.com/engineering/harness-design-long-running-apps
  2. https://www.anthropic.com/engineering/building-effective-agents
  3. https://www.anthropic.com/engineering/building-agents-with-the-claude-agent-sdk