Articles
Designing Autonomous Agent Loops: Architecture Beyond Prompts
Automatically translated from the Japanese original.
Note: This article is a written adaptation (restructured in manuscript form) of an internal slide-style deck. Its subject is the design of a resilient multi-agent "Generator-Evaluator" architecture that keeps writing, reviewing, and merging code even while you sleep.
The End of the "Human Clock"
Traditional AI usage ran on the "human clock." The agent waits for input, a human presses Enter, tokens are generated, and it stops. Repeat. In June 2026, a turning point arrived. Peter Steinberger (OpenClaw), Boris Cherny (Claude Code), and Addy Osmani (Chrome) each independently converged on the same realization within the same week: the tools had crossed a threshold.
The essence of the shift is this: stop being the person who prompts the agent, and become the person who designs the system that does it for you. An autonomous loop engine has three properties: (1) it fires on a timer (waking up on a schedule), (2) it spawns parallel sub-agents (helpers), and (3) it feeds itself (yesterday's output becomes today's input).
The Four-Layer AI Protocol Stack
AI usage can be organized into four layers; the higher the layer, the larger the blast radius when something fails.
| Layer | Core concern | Boundary unit | Blast radius of failure | Where the human stands |
|---|---|---|---|---|
| Layer 1: Prompt | What you tell the model | A single exchange | An immediately obvious wrong answer | Typist |
| Layer 2: Context | What you put in the window | A single session | Confident but wrong reasoning | Editor |
| Layer 3: Harness | Arming a single run (tools/actions) | A single task | A bad diff caught before shipping | Reviewer |
| Layer 4: Loop | Scheduling the harness | Unattended iteration | Structural rot that advances over days | Architect |
Anatomy of a Loop That Keeps Running
An autonomous loop consists of five nodes.
Discovery — backed by Skills (SKILL.md). The project's permanent knowledge, paying down "intent debt."
Handoff — backed by Worktrees. Independent git directories for parallel execution.
Verification — backed by sub-agents. The separation of Generator and Evaluator: "something that can say no."
Persistence — backed by connectors (MCP) and memory. State lives in files on disk (such as ./state/triage.md). The agent forgets, but the repository does not.
Scheduling — backed by automation infrastructure (local cron, GitHub Actions, cloud routines). It closes the cycle.
Worktree Parallelization
The problem: two agents editing the same working directory is like two engineers committing to the same line. Collisions break unattended pipelines. The primitive: isolate independent working directories, as in claude --worktree fix/auth-test 'draft the fix'. The effect: parallelization goes from "works but messy" to "works and clean." Multiple independent working directories within a single repository make high-throughput issue triage possible.
The Self-Persuasion Bubble — Separating Generator from Evaluator
The anti-pattern is a Generator grading its own homework. The Generator isn't looking at its code; it's looking at its own chain of self-persuasion. The GAN split, by contrast, separates the Generator from the Evaluator and casts the Evaluator as an adversarial code reviewer: "Assume this code is broken until proven otherwise. Don't praise it. Find where it fails."
The core insight: tuning an independent Evaluator into a rigorous skeptic is far more achievable — both mathematically and in practice — than getting a Generator to be critical of its own output.
Verdicts Through External Execution
The flaw: if the Evaluator only reads the code, its verdict is "does this look correct?" rather than "does this actually work?" The shift: connect the Evaluator to an external execution environment (e.g., Playwright MCP). The new standard: the Evaluator clicks buttons, forces screen transitions, captures DOM state, and runs tests. The verdict moves from "intent" to "behavior." The flow becomes: Evaluator agent → Playwright MCP connector → DOM inspection / screenshots / test runner → pass/fail verdict.
Maker-Checker Stopping Conditions
When should a loop end? The /goal primitive expresses "keep going until the condition is met" (for example: /goal all tests in test/auth pass and lint is clean). The Generator (a heavy model) writes the code, the Evaluator (a heavy model) runs the tests via MCP, and the Gatekeeper (a fast, fresh model) evaluates the /goal. If it is satisfied, the loop exits; if it fails, the reasons for rejection are sent back to the Generator.
The principle: the decision that work is complete must be made by a fresh model carrying none of the context baggage of the model that did the work. And there is a line worth remembering: the floor of the loop is the Evaluator. The Generator sets the ceiling on what gets produced; the Evaluator sets the floor on what doesn't.
Five Ways a Loop Fails
| Missing element | Anti-pattern | Symptom | Required fix |
|---|---|---|---|
| No verification | The nodding loop | 100 turns of approving its own garbage | Implement Generator-Evaluator separation |
| No persistence | The amnesiac loop | Rediscovers exactly the same work every morning | Force state files to be written to disk |
| No scheduling | The manual loop | Hasn't run once since the day it was demoed | Wire up cron/event triggers |
| No discovery | The blind loop | Still spending 30 minutes pasting in "fix this bug" every single time | Bake the heuristics into SKILL.md |
| No handoff | The tangled loop | Five parallel agents wreck a single git directory | Enforce isolation with --worktree |
Deterministic Interleaving at Enterprise Scale
Stripe's "Minions" pipeline — trigger (Slack) → context orchestrator (Sourcegraph/Jira) → code generation (LLM) → mandatory linter gate → lint fixes (LLM) → git commit → human review (1,300 PRs per week) — merges 1,300 machine-generated PRs a week (powered by the open-source framework Goose).
The secret is letting deterministic systems do the deterministic work. Context gathering and linting are strictly hard-coded, and the LLM is confined entirely within guardrails bounded by hard rules. Environments are treated as "cattle, not pets": Devboxes on EC2 are swapped out and destroyed immediately to avoid state rot.
Execution Topology — Where Does the Loop Live?
| Topology | Machine state | Session | Minimum interval | Local FS access |
|---|---|---|---|---|
| Cloud (Cloud Routines / GitHub Actions) | Works even with the machine off | Not required | 1 hour | None (clean clone) → best for overnight triage |
| Desktop (macOS cron) | Machine on | Not required | 1 minute | Yes → best for periodic repository maintenance |
| Local (/loop command) | Machine on | Required | 1 minute | Yes → best for high-frequency checks during development |
Calling a local re-run "running while you sleep" is an exaggeration. Local scheduling buys you frequency; cloud scheduling buys you true autonomy. No single scheduler gives you both.
The Vicious Cycle of the Unwatched Loop
An unattended loop carries four risks: verification debt (merging code that passes tests but hides subtle logic flaws) → comprehension rot (your mental map of the codebase drifts away from reality) → cognitive surrender ("I don't know how this works, but let's accept the PR") → token waste (an unwatched agent spawns helpers all night, endlessly retrying futile bug fixes). These are not four separate risks; they are a single, compounding failure mode. A loop without a rigorous Evaluator has handed the authority over its spending to its own bugs.
The Economics of Zero-Cost Generation
What becomes abundant: generation. The cost of code, plans, fixes, and pull requests trends toward effectively zero, and mechanical labor collapses. What stays scarce: judgment. A loop can generate 100 candidate implementations, but it chooses among them based on "looks right," not "is actually right." The loop as amplifier: a loop is a faithful multiplication sign. Bring understanding and it amplifies understanding; bring laziness and it amplifies disaster.
Operational Circuit Breakers
Always read a sample (defense against comprehension rot): every day, pick a machine-generated PR at random and check whether you can explain it in your own words. If you can't, your mental map is already stale.
Set caps before shipping (defense against token waste): per-run budget limits and maximum retry counts are not about saving money; they are circuit breakers that convert open-ended risk into bounded risk.
Leave one door open (defense against cognitive surrender): build at least one checkpoint that pauses for a human — not so that you intervene every time, but to guarantee that you can.
Deploying the Minimal Resilient Loop
The minimal configuration looks like this: fire on a schedule (cron: cloud automation), run a skill (morning-triage: discovery), and write the results to ./state/triage.md (persistence). Carry out any fixes discovered in a worktree (fix/$finding: handoff), and judge them against a /goal of "tests pass and lint is clean" (verification). Output folders are split into ./inbox/ (everything unverified), ./state/, and ./src/, and the rule is: never auto-merge. Everything unverified lands in ./inbox/.
Finally, let's close with these words.
"Build the loop. But build it as someone who intends to remain an engineer, not as someone who merely presses a button."
The end
Read next ↓