Brahim Bousnguar

Notes · Article

The Ralph loop: how a bash one-liner moved into the model

By · · 9 min read

Listen · 12:12 · read by an AI voice

Listen to this article0:00 / 12:12

Read by an AI voice · MP3

"Earlier models didn't understand the idea of what done meant," said Raj, from OpenAI's applied AI team, at DevDay 2026. They made good progress, then ended their turn early. The fix moved three times: first a bash loop around the agent, called the Ralph loop, then a goal command inside the tool, and now persistence trained into the model.

If you run coding agents, it's worth knowing which of the three layers does the job today. Otherwise you build a loop that your model or your tool already runs for you, and you pay for it twice.

The talk is What Comes After Loops?, 24 minutes, by Raj and Eric from OpenAI. It's OpenAI telling the story of its own product, Codex, so I checked the other side too: how Anthropic's Claude Code handles the same problem.

The first fix was typing "continue"

Before the tools had an answer, the answer was you. The agent stopped, you typed "continue", and it went on for a while.

Raj showed a post by Peter Steinberger, who created OpenClaw. To keep his agent working, he queued a stack of "continue" messages, one after the other. Everyone was doing a version of it.

In the talk's words, this is an "outer loop": something outside the agent that keeps nudging it until it finishes. The model doesn't know when to stop, so a person, or a script, decides for it.

Long tasks, before the tools helped

The agent stopped early, so you typed continue

  1. WorkThe agent makes good progress on the task.
  2. StopIt ends its turn before the work is done.
  3. NudgeYou type "continue", or queue a stack of them.

Then back to step 1, until the work is really done

The outer loop as the talk describes it. The drawing is mine.

A bash loop that never gives up

The Ralph loop is the same nudge, written as a script. Geoffrey Huntley made it popular in July 2025, in a post called Ralph Wiggum as a "software engineer". Ralph Wiggum is the child in The Simpsons who never gets it right and never stops trying.

In its purest form, it's one line of bash:

while :; do cat PROMPT.md | claude-code ; done

The loop reads a prompt file and gives it to a coding agent. The agent works until it stops. Then the loop starts it again, with the same prompt, forever. There's no exit condition in that line.

Four ideas make it work, and they're more interesting than the loop itself:

  • Fresh memory every run. Each run starts with an empty context window, the text the model can see at once. No long chat history fills it up or pushes the goal out.
  • The files remember. Progress lives on disk: the code, a folder of specifications, one per file, and a plan file Huntley calls fix_plan.md. Each run reads them to find out where things stand.
  • One thing per loop. Huntley's rule: "ask Ralph to do one thing per loop. Only one thing."
  • Tests push back. After each change, the agent runs the tests for that part of the code. A failing test rejects a bad change before the next run builds on it. Huntley calls this backpressure.

He's honest about what it is. He calls the technique "deterministically bad in an undeterministic world": it fails in ways you can predict, so you can fix them in the prompt. It also needs "a great deal of faith", because the code converges slowly, run after run.

One run of a Ralph loop

Each run starts empty, the files remember

  1. ReadThe prompt, the plan and the specifications. The context is empty.
  2. Do one thingA single task from the plan.
  3. TestA failing test rejects a bad change before the next run builds on it.
  4. Write it downCommit the code, update the plan file.

Then the loop starts the agent again, with empty memory

From Geoffrey Huntley's post of July 2025. The four steps are my summary of his prompt.

The goal moved into the tool

The next step was to build the loop into the tool. OpenAI added a /goal command to Codex, which shipped in Codex CLI 0.128 at the end of April. Raj called it "loop engineering" brought into the product.

To see why it helps, you need one more word: compaction. When the context window fills up, the tool asks the model to condense the history into a short summary, and the work goes on from there. That keeps a long task alive, but every summary can drop a detail. After three or four compactions, the original instructions may be gone.

A goal avoids that. You give Codex an objective, and the tool stores it outside the conversation, where compaction can't touch it. The tool tracks its status and checks after each turn whether the agent is done. If not, it nudges the agent to keep going.

The agent can also say it's stuck. When it hits a real blocker, it reports it and stops, instead of looping on a problem it can't solve. The bash loop has no way to do that.

The bash loop against a goal command

A goal keeps the objective where compaction can't reach

The bash loopA goal in the tool

MemoryEmpty every runOne session, compacted as it grows

The goalA prompt file, read each runStored by the tool, outside the context

Done whenYou stop itA check after every turn says so

When stuckIt keeps loopingIt reports the blocker and stops

Codex's goal as described in the talk, against Huntley's one-line loop.

Then persistence moved into the model

The last step, OpenAI says, removed the need for the loop. With GPT-5.6, it trained persistence into the model itself. The model checks its own work and keeps going until the job is done, with no goal and no "continue".

Raj quoted two users. Tobi Lütke, who runs Shopify, called it the first model that no longer needed /goal. Ethan Mollick, a Wharton professor, let Codex use his computer and play the game Slay the Spire 2 for about five hours straight. These are OpenAI's examples, on OpenAI's stage.

The pattern behind it is the interesting part. OpenAI watches what people bolt onto the harness, the code around the model that runs its tools and manages its context. Then it trains that behaviour into the next model. Compaction went the same way: first a call the tool makes, then a skill the model learned, so it knows how to resume from its own summary.

Anthropic tells a similar story from its side. When it launched Claude Sonnet 4.5 in September 2025, it said it had seen the model keep its focus for more than 30 hours on complex tasks. In November 2025, its engineers wrote up how they keep Claude working across many context windows. They name the same failure: "Claude declares victory on the entire project too early."

Their fix looks a lot like Ralph. A first agent writes a list of over 200 features, all marked as failing, plus a progress file. Each session after that works on one feature, commits, and writes a summary for the next one. The agents may only change a feature's status, never delete it, so nobody can declare a missing feature done.

Where "keep going" lives

The loop moved inward, from your script to the model

  1. Your scriptA bash loop restarts the agent on the same prompt. The Ralph loop, July 2025.
  2. The toolA goal command stores the objective and checks after each turn. Codex and Claude Code.
  3. The modelPersistence trained in: it checks its own work and keeps going. OpenAI's claim for GPT-5.6.

Each layer took over the job of the one outside it.

My summary of the talk's story. The GPT-5.6 claim is OpenAI's, not an independent test.

How Claude Code and Codex handle it today

Both tools now have all three layers, and they built the middle one in different ways.

Start with the bash loop. Anthropic publishes an official Ralph Loop plugin for Claude Code. You run /ralph-loop "your prompt" --max-iterations 10 --completion-promise "DONE". A stop hook, a small script that runs each time Claude tries to end, catches the exit and feeds the same prompt back. It stops when Claude writes the word you chose, or after the iteration cap.

There's one real difference from the original. The plugin keeps the same session going, while Huntley's loop starts each run with empty memory. Huntley himself links a video on his page called "why the claude code plugin isn't it". With Codex, people still write the loop by hand, with codex exec, its non-interactive mode, inside the while.

Then the goal. Both tools now ship a /goal command, and they check it differently:

  • Codex. The goal is state the tool keeps for the chat. The app shows its progress above the input box, with buttons to pause, resume, edit or clear it. The model itself reports when it's blocked.
  • Claude Code. You write a condition, up to 4,000 characters. After each turn, a separate model reads the conversation and answers: not met, met, or impossible. The docs say this checker "doesn't run commands or read files" on its own.

That last detail changes how you write a goal for Claude Code. The checker only sees what the conversation shows. "The tests pass" is weak. "npm test passes and its output is shown" is a condition it can actually check. The docs also suggest a way out, written into the condition itself: "or stop after 20 turns".

Claude Code adds one thing Codex doesn't have under that name: /loop. It runs a prompt again on a schedule, every five minutes for example, or at a pace Claude picks, between one minute and one hour. That's for watching something, like a deploy, not for finishing a task.

Claude Code and Codex, November 2026

Same layers, different checks

Claude CodeCodex

The bash loopOfficial Ralph Loop plugin: a stop hook feeds the prompt backWrite it yourself: codex exec in a while loop

A goalA condition a separate model checks after every turnAn objective the tool keeps: pause, resume, edit, clear

On a schedule/loop: every few minutes, or self-pacedNot covered here

HelpersSubagents report back. Agent teams message each other, still experimentalSubagents, on by default, and /subagents to switch

From the Claude Code and Codex docs, read on November 11. Codex also has scheduled tasks, which I didn't look at.

Add agents only when the work asks

Once one agent keeps going on its own, the next question is speed: why not ten agents? Eric's answer, in the second half of the talk, was to wait. Start with one agent, give it a clear task and a way to check its work. For many tasks, that's enough.

Add more only when the work splits on its own. Reviewing five pull requests is easy to split: one helper agent per pull request, each with its own context. A tricky race condition is less obvious, but a couple of helpers can look in different places at once.

The cost is real. Every agent you add can raise the token bill a lot, without making the work faster or better. Both vendors say it in their docs: Codex subagents "consume more tokens", and Claude Code's agent teams use "significantly more tokens than a single session".

Eric also named a trap he calls the middle management tax. Every rule you add about how agents should work together, they start to wait for approval through hierarchies that don't exist. So keep the setup simple. If you can't say why an agent is there, take it out.

At the far end of the scale, Raj said OpenAI ran 10,000 agents on a famous open problem in mathematics, the Navier-Stokes equations. He gave 2.7 million messages and about 130 billion output tokens. That's OpenAI's report of its own internal model, and nobody outside has checked it yet. For a team at work, the useful lesson is the one before it: one agent first.

How many agents for a task

Start with one agent and a way to check

One agentA task and a checkA clear task and a way to verify the work. Most tasks stop here.
HelpersPieces that splitOne helper per pull request to review, each reporting back.
A teamPieces that talkAgents message each other while they work. The most tokens.
Eric's advice from the talk, with the two kinds of helpers both tools offer.

A short work log keeps the goal

Eric's last tip is the one I'd try first, because it works with any tool. As you watch an agent work, you keep adding small instructions you forgot in the first prompt. After a few compactions, the agent may drift from that first prompt, and it held most of the context about the goal.

His fix: ask the agent to keep a short work log. It holds three things. The overall goal. The work in progress. And how your latest instruction fits with both.

Keep it short on purpose. A log that records every failed test becomes a diary nobody reads, and it fills the context again. It's the same idea as Ralph's plan file, kept by the agent inside one long session.

He closed with a warning that fits this whole note: best practices have a shelf life, so don't get attached to your workflow. The bash loop was the best practice a year ago.

A work log, in three parts

Write it down, so the goal survives compaction

  1. The overall goalWhat the whole task is for.
  2. The running workWhat is in progress now.
  3. Your last steerHow your latest instruction fits with both.

Short on purpose: not a diary of every failed test.

From the talk. The three parts are Eric's.

Try it

The Ralph loop comes up at about 7:10 in the video, /goal just after, and Eric's advice on agents from about 11:00.

Before you write your own loop, check what your tool and model already do. Give one task a goal with a condition the checker can see, like a test command and its output. Then tell me where it stopped, and why.

Plain text: ralph-loop-moved-into-the-model.md · Atom feed · All notes

Contact

Say hello.

b.bousnguar@gmail.com

SAP Commerce Cloud, MuleSoft and Salesforce integration · Nantes · EN / FR