← back to writing
#AI Engineering · #Agentic AI · #Loop Engineering · #AI Safety · #Evaluation

Loop Engineering: Maker, Checker, Breaker

A safe agent loop separates three jobs: making the work, checking the evidence, and stopping the run. Let one model own all three and confidence quietly becomes control.

The draft was wrong, the review was glowing, and both came from the same agent.

That failure is easy to create. Ask an agent to produce an answer, then ask it whether the answer is good. The second prompt feels like verification, but the same model is still looking through the same eyes. It remembers the intent behind every weak choice. It is unusually sympathetic to its own shortcuts.

I have seen this pattern in code, architecture notes, and research. The maker says, “Done.” The reviewer says, “Comprehensive and well-structured.” A test, a missing source, or a human with fresh eyes finds the hole in minutes.

The problem is not that models cannot review. They can. The problem is role collapse: one actor is doing the work, defining success, interpreting the evidence, and deciding whether it gets another attempt.

Loop engineering separates those powers.

Three jobs, not one clever agent

The smallest useful control structure has three roles:

A human sits outside the cycle for decisions the loop is not allowed to make.

A bounded autonomy loop. The maker creates a candidate, deterministic checks and an independent checker test it, and the breaker routes the result to repeat, stop, or human handoff. The maker cannot approve itself, and every path writes a receipt.

These roles can be different programs, different agents, or different layers of one system. What matters is that their authority is separate.

The maker should not rewrite the rubric after seeing its score. The checker should not quietly repair the artifact it is judging. The breaker should not accept “one more try” just because the maker sounds close.

The maker owns the attempt

The maker’s job is creative and local: take the current goal, state, tools, and constraints, then produce the next candidate.

Good maker instructions are specific about the output but do not reveal every detail of the held-out check. If the maker knows the exact scoring tricks, it can optimise for the appearance of success instead of the outcome.

Give the maker:

Do not give it the right to declare the entire loop complete. “I finished” is a claim submitted to the checker.

The checker owns the verdict

The checker asks a colder question: what evidence would make this candidate safe to accept?

The best checker rail is layered.

Start with deterministic gates

Run the checks that do not care how persuasive the candidate sounds:

If a candidate cannot pass the objective floor, do not spend a model call debating its style. Reject it cheaply and return useful evidence to the maker.

Then apply the rubric

Some work cannot be reduced to a boolean test. A design may need to be coherent, a research note may need balanced coverage, and a blog may need a strong argument rather than merely valid Markdown.

Use a rubric with observable dimensions. “High quality” is not a dimension. “Every material claim has a source, the opening creates a concrete tension, and each section advances the argument” is.

Keep the scoring criteria stable during the run. A moving rubric turns iteration into negotiation.

Use a second model where judgment is genuinely needed

An independent checker can catch omissions and contradictions the maker misses. Diversity helps: a different model, persona, context, or temperature is more likely to make a different error.

But independence is not magic. A second model is still weaker evidence than a passing executable check. Put machine judgment after deterministic evidence, not instead of it.

The checker ladder orders evidence from cheapest and most objective to most expensive and judgment-heavy. Schema, build, tests, policy, and provenance run first; a stable rubric scores survivors; an independent model handles genuine judgment; and a human decides only reserved consequences or unresolved ties.

The breaker owns permission to continue

The checker says whether the latest candidate passed. The breaker decides what happens next.

That distinction matters because failure does not automatically justify another attempt.

candidate = maker.run(state)
verdict = checker.evaluate(candidate)

if verdict.passed:
    return complete(candidate, verdict)

if verdict.denied:
    return terminate(candidate, verdict)

if budget.exhausted() or verdict.requires_human:
    return handoff(candidate, verdict)

state = record_failure_and_prepare_next_attempt(candidate, verdict)

A breaker should understand at least four stop conditions:

Budget exhausted

Maximum attempts, tokens, money, or wall-clock time. A loop without a cost ceiling can turn a small problem into an expensive ritual.

No measurable improvement

If the score has plateaued, another mutation is not automatically progress. For hill-climbing loops, keep a candidate only on strict improvement. “Different” is not “better.”

Repeated failure class

Three attempts failing for the same missing permission or unavailable dependency are not three creative failures. They are one blocked condition repeated. Stop and surface the blocker.

Consequence requires a human

Production changes, external communication, destructive actions, money movement, or policy exceptions should suspend at a precise gate.

The loop is not failed while a person is deciding. It is waiting.

That state deserves its own name because it changes how the system behaves. A failed run may be terminal. A waiting run should preserve its exact candidate and approval request, then resume after the decision. It should not regenerate a slightly different artifact and assume the old approval still applies.

Approval belongs to the exact thing a human saw.

A checker is not a critic

This was an important correction in my own thinking. I used to picture the checker as a senior reviewer writing comments. That is only part of the job.

A useful checker returns a machine-actionable verdict:

It should also return the failing criteria and the evidence used. That gives the next iteration something firmer than “make it better.”

For example:

{
  "verdict": "revise",
  "failed": ["source_coverage", "acceptance_test"],
  "evidence": {
    "uncited_claims": 2,
    "test": "test_resume_after_approval",
    "exit_code": 1
  }
}

The maker can act on that. The record can preserve it. The breaker can count it. A dashboard can explain it.

“Needs improvement” does none of those things.

A checker verdict routing map. Pass completes with evidence. Revise returns specific failed criteria to the maker if budget remains. Deny terminates and records the reason. Awaiting human suspends the exact artifact until a decision, then resumes or rejects without regenerating approval scope.

One practical pattern: gate, score, escalate

For consequential work, I use this order:

  1. Gate: remove candidates that fail objective checks.
  2. Score: compare survivors against a stable rubric.
  3. Escalate: ask a stronger model or a human only when evidence cannot settle the decision.

This keeps the expensive judgment focused on the small set of cases that deserve it. It also makes failure legible. The candidate did not lose because another model “felt better.” It failed the build, missed a source, scored below the threshold, or reached a decision reserved for a person.

Design your first bounded loop

Take one task you already repeat and write four lines:

  1. Maker: who produces what artifact?
  2. Checker: what independent evidence must pass?
  3. Breaker: what exact limits end iteration?
  4. Human: what decision can the loop never make alone?

If one actor currently owns all four lines, split the authority before you add more autonomy.

The goal is not to make agents distrust themselves. It is to stop confidence from becoming permission. A capable maker and a skeptical checker help, but the breaker is the component that lets you leave the room because it knows when the next attempt is no longer deserved.


Next in the series: State, Recovery, and the Right to Continue - how a loop survives restarts without repeating side effects or learning from the wrong signal.