Skip to content

Loops

A Ralph loop keeps one agent working until you stop it, starting fresh from the task and the repository every turn. Reach for it when you want a task worked through with nothing carrying over from one turn to the next.

What a Ralph loop is

python
while True:
    agent(task, suppress=True)

That is the whole of it. agent(...) opens a session (a conversation the agent holds) and drops it, so nothing of the last turn carries over.

The opposite is stateful_ralph, which holds one session for the whole run:

python
session = agent.new()
while True:
    session(task, suppress=True)

The agent is the same; the behaviour is opposite. The flow decides, not the agent — the most important choice a weaver makes. See Concepts › Session.

Write a task the loop can finish

A Ralph loop wants a task with a finish line it can check for itself.

sh
cat > TASK.md <<'EOF'
# Task

Make `calc.py` a real calculator:

- [ ] add, subtract, multiply, divide
- [ ] divide by zero raises ValueError
- [ ] a test file `test_calc.py` covering all four
- [ ] `python -m pytest -q` passes

Tick each box in this file as you finish it. Stop when all four are ticked.
EOF
git add -A && git commit -qm "the task"

Choose the flow

In hmz:

/flow

The flows appear one place at a time, one list each. and step between the places, s narrows by name, and enter takes ralph_loop. Or say it outright:

/flow ralph_loop

There are no flows to choose from while a flow is running: /flow opens inside the agents of the one that is going, and /flow ralph_loop is refused outright with hmz: a flow is running; no choosing a flow. Looking and leaving without choosing changes nothing.

What these three flows are
FlowAgents
chat1 + youone session; every line you type is a turn of it. What the interface opens on.
ralph_loop1a fresh session every turn
stateful_ralph1one session, re-sent the task every turn

Both loops say they can be picked up. They keep which round they are on, so starting one again in this directory says round 41 rather than round 1.

Start the loop

Say what you want done:

Work through TASK.md.

It keeps going until you stop it.

Watch the run

/monitor

It shows three things: who is working, every handover between agents with how often it happened, and what each model has cost. On a one-agent flow the graph is dull. On two agents taking turns it is the shape of the run.

Above the editor, continuously:

        assistant · claude/claude-opus-4-8:high · ● 1
   input 1.2k · output 980 · cache_read 46.0k · cache_write 9.1k
                          $1.34 · 91 out/s

is an agent with a turn open, and 1 is how many conversations it has open right now. A Ralph loop holds one at a time — the turn's own — and lets it go when the turn ends, so the number does not climb with the turns; between turns it holds none and the line says nothing about conversations at all. All of them run down this agent's one transcript either way, and nothing is redrawn when the next one opens. tab steps between the agents that are working, which matters on a flow that drives several.

The cost line is per model, over a recent window, so a flow that has stopped reads as stopped. See Cost and rate.

Steer the loop without restarting

A Ralph loop re-reads the repository every turn, so the fastest way to steer it is to edit the task file. In another terminal:

sh
echo '- [ ] and a --help flag' >> TASK.md

The next turn starts from a file that says so. Nothing had to be told.

You can also type at it; that goes into the turn that is running. See Talking to a running turn.

Stop the loop

ctrl+c, twice.

The loop never ends by itself; it is a while True. A stop raises Stopped inside the flow's code. suppress=True deliberately does not catch that — otherwise the loop would carry on past a stop and never end. See Stopping.

It also stops without you. Every run has an allowance — hours, millions of output tokens, dollars — and a turn taken once it is spent raises that same Stopped, which is what lets a loop like this one be written with no way out at all. ralph_loop ships declaring ten million output tokens; the budget row of /flow, or a budget: in the file -c names, is where you say otherwise.

Stopping is not losing your place. ralph_loop can be picked up: start it here again and it goes on from the round it reached. That run is a run of its own, with its own sessions and its own record. /epics is where both of them are.

Try this

Hold the conversation instead of dropping it. /flow stateful_ralph, same task. Compare how often it re-reads files it has already read.

Move the effort. Open the flow in /flow, choose the agent, find the effort row, and press ←/→ or space. A Ralph loop of low turns is a different animal from one of max turns. See Efforts.

Make it read-only. What an agent is allowed to do is the flow's to say, declared beside the agent it drives — so this one is a fork rather than something you type. Press f on ralph_loop in /flow, which copies the whole flow into .humanize/flows/ralph_loop/, and write what its one place is allowed beside the type:

python
# .humanize/flows/ralph_loop/__init__.py — the annotation on run's agents
agents: tuple[Annotated[Agent, AgentDefaults(permission="read-only")]]

local/ralph_loop now looks at the repository and changes nothing, whichever CLI fills the place, which is how you use a loop to review rather than to build. See Permissions.

See also

Released under the Apache-2.0 licence.