← All guides

How to Keep an Agent Loop From Running Away

You hand an agent a goal and walk away. That is the entire point — you stop watching. The danger is that the agent doesn't stop either. It chases an unsatisfiable check for six hours, edits the module you didn't mean, or retries the same broken fix until the token bill shows up.

Keeping a loop safe is not a framework or a tool. It is a few specific lines in the prompt that tell the agent when to quit, what to check, and what to leave alone. Most loops skip them. We check every loop in this directory for those lines, so we can put a number on it: only 1 in 5 states when to stop. Here is what to write, starting with the line that matters most.

Start here: the two lines that bound the loop

Take an ordinary goal loop:

Fix the failing tests.

There is no stopping point, so the agent keeps going as long as anything is red — including when a test is broken in a way it cannot fix. Add two sentences:

Fix the failing tests until npm test exits 0. Stop after 10 attempts and report what is still red. Only touch application code — never edit the tests to make them pass.

Now it has an exit condition (npm test exits 0), an iteration budget (10 attempts), and a scope limit (leave the tests alone). That one edit is the difference between a loop that stops on its own and one that runs until you notice. Everything below is a variation on it.

The lines that bound a loop

Six things make a prompt safe to run unattended. Put the ones that apply into yours:

Put this in the promptExampleWhy
An exit condition"until the audit is clean", "until pytest passes"Without a finish line, the loop never stops on its own
An iteration budget"stop after 10 turns"The backstop for when the exit condition turns out to be unreachable
A check to run each passtests, lint, build, a scriptSelf-reported "done" is not done — make it prove it
A scope limit"never touch the tests", "minimal diffs", "report-only"Stops the agent reward-hacking the check or wandering off-task
A human gate"open a PR, never auto-merge"Keeps a person on anything that actually ships
No dangerous commands(see the last section)The one line that is not a judgment call

The first two do most of the work, and they are the two people leave out most.

Why the exit condition and the budget matter most

Across the vetted loops in this directory, a stated exit condition and an iteration cap are consistently the two rarest lines. They are also the two that most directly stop a runaway.

They are also what separates a loop that runs cleanly unattended from one that doesn't. The loops here that get it right are worth copying: Ship a PR until green bounds itself on CI status, and Make tests pass, gate frozen adds a scope limit so the agent can't cheat the check by rewriting it. If you add only two lines to your prompt, add these.

Picking `/goal` over Ralph will not save you

It is tempting to think one loop command is safer than another. It is not. Average safety barely moves by type — /goal, /loop, /schedule, and the fire-and-forget Ralph pattern all land in the same middle band. A /goal loop with no exit condition is more dangerous than a Ralph loop that has one. The bound lives in the prompt, not in which command you typed.

The line that is never optional

Everything above is a judgment call about how tightly to bound the loop. One thing is not: no unattended loop should carry a destructive command. No rm -rf, no git push --force, no curl | sh. No loop published here contains one — not because every author was careful, but because the directory rejects them on sight. Give your own loop the same floor. A loop that can force-push can undo a safeguard faster than you can read the log.

Check your own loop

Paste your prompt into the grader and it tells you which of these lines you are missing — the same check every loop here runs through. For the harness-level version — hooks that veto bad commands before they run, hard budgets, evaluators that reject bad output — see Agent Loop Safety. Or start from a loop that is already bounded: the Builder generates a harness with the exit condition, budget, and evaluator already wired in.

Most loops that run away were not reckless. Their authors just forgot to write down when to stop. Write it down, and you have done the single most important thing.

Ready to run one? Browse the loop directory →
All EVALUATION loops

Draft a sprint plan from the backlog

Turn the open issue backlog into a proposed two-week sprint plan with estimates, a dependency ordering, and an explicit cut line, written as a document for the team to edit.

Open loop →

Fix interpreter matching test failures

Run the test suite repeatedly, fixing InterpreterMatchingServiceTests failures until all pass.

Open loop →

Receipt & statement archiver

Scan the inbox for receipts, invoices, and statements and file each under a Receipts label — read-only on everything else, deleting nothing.

Open loop →

Auto-unsubscribe agent

Find newsletters you never open and unsubscribe via the List-Unsubscribe header — bulk mailing lists only, never transactional or security senders.

Open loop →