agent-patterns

loop-with-guard

flowchart TD
    Start([Task input]) --> Coder[Coder agent]
    Coder --> Reviewer[Reviewer agent]
    Reviewer --> Valid{Valid verdict\nJSON?}
    Valid -- no, attempts left --> Repair[Repair turn:\nsend parse error back]
    Repair --> Reviewer
    Valid -- no, attempts exhausted --> Escalate
    Valid -- yes --> Approved{verdict ==\nAPPROVED?}
    Approved -- yes --> Done([Return result])
    Approved -- no --> CapCheck{Round cap\nreached?}
    CapCheck -- no --> Coder
    CapCheck -- yes --> Escalate([Escalate to human gate\nwith last reasons])

An agent iterates in a loop — coder → reviewer → coder — with an explicit exit condition and a round cap to prevent infinite loops.

How it works

  1. The coder agent produces or improves a solution in a single fenced code block; only that block is kept as the code.
  2. The reviewer agent receives the original task and the code, wrapped in <task> / <code> tags and told to treat the code as untrusted data. It returns JSON: {"verdict": "APPROVED" | "CHANGES_REQUESTED", "reasons": string[]}.
  3. The verdict is parsed strictly; the only leniency is stripping one surrounding ` ```json ` fence. CHANGES_REQUESTED must carry at least one reason — empty feedback gives the coder nothing to act on.
  4. An invalid verdict is the reviewer’s fault, so it is repaired on the reviewer side: the parse error is sent back once, without spending a coder round. If the repair also fails, the loop fails closed and escalates — a reviewer that cannot produce a verdict is a system fault, not a code fault.
  5. If approved, the loop exits cleanly. Otherwise reasons become the coder’s feedback for the next round.
  6. If the round cap is reached without approval, the task escalates to a human gate with the last reasons, not just the rejected code.
  7. A safety-classifier refusal escalates to the human gate — another round cannot fix it. Truncated output (stop_reason: "max_tokens") or an empty answer throws: neither is reviewable code nor a verdict.
  8. The repair turn appends the reviewer’s full previous turn, thinking blocks unchanged — the history stays append-only, which models with preserved thinking require.

Where it came from

When to use

When not to use

Trade-offs

   
Pro Prevents infinite loops with a hard cap
Pro Escalates gracefully rather than silently failing
Con Round cap is a blunt instrument — too low and valid tasks escalate; too high and costs grow
Con Reviewer and coder must share enough context for the loop to converge
Con Same model as coder and reviewer shares blind spots and tends to approve its own style — use a different model or an adversarial reviewer prompt when the stakes justify the cost

Failure modes