What is a Ralph Loop?
You are watching an agent work on a feature. It edits a file, runs the tests, hits an error, patches the error, runs again, finds a second issue, tries a different approach, and then stalls. The transcript is now long. Half of it is abandoned attempts.
So you tell it to retry.
It retries in the same chat. It carries the old stack traces forward. It carries the abandoned approach forward. It carries the file contents that no longer match disk. The next attempt fails the same way, or a slightly worse way, because the model is no longer solving the clean task. It is solving the task plus the sediment of every previous attempt.
Retrying in the same chat compounds errors. Junk piles into the context.
That is the problem a Ralph Loop fixes.
The short definition
A Ralph Loop is what you do when an agent attempt stalls or fails:
- Stop the attempt.
- Write a compact note of what went wrong.
- Scrap the degraded session.
- Retry fresh, in a clean worktree, carrying only that note forward.
The attempt is time-boxed. Default is 20 minutes. If it does not finish cleanly in the box, the loop stops, writes the note, and the next iteration starts over with fresh context and that one note.
The key move is the reset. You do not continue in the polluted transcript. You throw it away and start clean, except for the failure note.
Why retrying in the same chat fails
Every step an agent takes leaves context behind. Some of it is useful. Some of it was useful five minutes ago and is now harmful.
When you retry in the same chat, the model keeps:
- old plans that were abandoned
- stack traces from errors you already fixed
- file contents that no longer match the repo
- tool output that was only relevant to one dead branch
- your corrections mixed with the model's guesses
After a while the model is not solving the task. It is doing archaeology on its own failed attempts.
A larger context window does not solve this. It gives the model more room. It does not decide what belongs in the room. Bad context pulls the model toward the wrong action even when the answer is technically somewhere in the window.
This is context rot. The working set became polluted, and the retry inherited the pollution.
The move: scrap and retry fresh
The fix is a boundary. The failed attempt does not get to bleed into the next one.
- The attempt runs in its own isolated git worktree, so it never touched your main checkout.
- It stalls or fails inside its time box.
- The loop writes one failure note: what was being done, what went wrong, what to try next.
- The worktree is discarded. The transcript is discarded.
- A fresh worktree is created. A fresh session starts. The only thing carried forward is the failure note.
The next attempt gets a clean workbench and one useful fact. It does not get the 2000-line log. It does not get the abandoned plan. It does not get the old file dump.
This is the same pattern a careful human uses. When you get stuck on a bug and start going in circles, you stop, write down the one thing you know is wrong, close the noisy terminal, and start over with just that note. You do not keep rereading the same dead-end output hoping this time is different.
What a bad retry looks like
Keep going in the same chat.
Paste the full error log back in.
Ask it to try again.
Ask it to try harder.
Paste the log again.
The model now has the original task, the failed attempt, the full log, your frustration, and the same wrong context that produced the failure. It will likely fail the same way. The retry did not get smarter. It just got longer.
What a good retry looks like
Previous attempt failed because the password-reset test
creates a user without an email address.
Fix the fixture or guard the email access before rerunning:
npm test -- password-reset
Retry in a fresh worktree. Do not inherit the previous transcript.
The next attempt gets the clean task plus one specific cause. It does not get the noise. It can actually move forward.
The failure note is the whole trick
The reset is easy. The hard part is the note.
A good failure note preserves only what changes the next action. It answers: what was being attempted, what specifically went wrong, and what to do differently.
Good compression:
The bead failed because the empty-state container replaced the
upload button, which broke keyboard focus. Keep the upload button
outside the conditional empty-state block. Rerun:
node _check_css.js
Bad compression:
Tests failed. Try again.
The bad version throws away the only useful fact. The next fresh attempt is now flying blind in a different way. It has a clean context but no idea what went wrong, so it guesses from scratch and may repeat the exact same mistake.
The failure note is what turns a reset from "start over dumb" into "start over smarter." Each iteration of the loop carries one more useful fact forward instead of one more pile of sediment.
Why it is called a loop
Because it repeats. A bead may take one iteration or five. Each iteration is a fresh attempt with a growing set of failure notes and nothing else from the past. The loop ends when an attempt finishes cleanly inside its time box and passes its validation.
Failures compound into learning. They do not compound into context rot. That is the whole point.
Sources
- Anthropic, "Effective harnesses for long-running agents": https://www.anthropic.com/engineering/effective-harnesses-for-long-running-agents
- Anthropic, "Effective context engineering for AI agents": https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents
- OpenAI Cookbook, "Context Engineering - Short-Term Memory Management with Sessions": https://developers.openai.com/cookbook/examples/agents_sdk/session_memory
How LoopTroop uses Ralph Loops
LoopTroop is a local, open-source GUI app for running coding tickets across local git repositories. It is built around the idea that long tasks fail when every step lives inside one endless chat, so it orchestrates around the agent instead of letting it run until it rots.
The pieces that matter here:
- A ticket is split into small atomic units called Beads, each with acceptance criteria and a validation command.
- Each Bead runs inside its own isolated git worktree, so concurrent work never stomps on itself.
- Each Bead is time-boxed, default 20 minutes.
- If a Bead does not finish cleanly inside its box, the Ralph Loop stops, writes a failure note, discards the worktree and the session, and starts a fresh attempt carrying only that note.
- The loop repeats until the Bead passes, or until you intervene.
The effect: every retry gets a clean workbench and one useful fact. The model never has to dig its way out of its own polluted transcript. You can watch the whole thing from one pane, see every failure note, every fresh attempt, and the final diff before anything reaches your main branch.
LoopTroop is one implementation of this pattern. It is not the only way to run a Ralph Loop, but it is a worked, observable one.
- Site: https://www.looptroop.ovh/
- GitHub: https://github.com/looptroop-ai/LoopTroop
- 16-minute demo: https://youtu.be/LYiYkooc_iY



Top comments (0)