Ralph is an autonomous AI agent loop that runs repeatedly until all PRD items are complete. Each iteration is a fresh AI instance with clean context. Memory persists via git history, progress.txt, and prd.json.
Based on Geoffrey Huntley's Ralph pattern.
Read the original article on how Ralph works
Ralph now supports multiple AI providers - no Amp CLI required!
- Anthropic Claude - Claude Sonnet 4.5, Opus, Haiku
- Z.ai - GLM-4.7 and other GLM models
- Qwen - qwen3-coder-plus and other Qwen models
- OpenAI - GPT-4, GPT-3.5, etc.
Simply configure your preferred provider in .env and Ralph uses their API directly.
- Python 3.9+
jqinstalled (brew install jqon macOS)- A git repository for your project
- API key for your chosen AI provider (Claude, Z.ai, Qwen, or OpenAI)
pip install -r requirements.txtCopy the example config:
cp .env.example .envEdit .env and add your API key. For example, to use Z.ai:
AI_PROVIDER=z.ai
Z_AI_API_KEY=your-api-key-here
Z_AI_MODEL=GLM-4.7
Z_AI_BASE_URL=https://api.z.ai/api/coding/paas/v4/Or for Claude/Anthropic:
AI_PROVIDER=anthropic
ANTHROPIC_API_KEY=sk-ant-your-key-here
ANTHROPIC_MODEL=claude-sonnet-4-5-20250929See SETUP.md for detailed configuration for all providers.
chmod +x ralph.sh agent.pyTo use Ralph in another project:
# From your project root
mkdir -p scripts/ralph
cp /path/to/ralph/{ralph.sh,agent.py,prompt.md,requirements.txt,.env.example} scripts/ralph/
cd scripts/ralph
pip install -r requirements.txt
cp .env.example .env
# Edit .env with your API key
chmod +x ralph.sh agent.pyCreate a prd.json file with your user stories. See prd.json.example for format.
Example:
{
"branchName": "ralph/new-feature",
"userStories": [
{
"id": "FEAT-1",
"title": "Add user authentication",
"description": "Implement JWT-based authentication",
"passes": false,
"priority": 1
}
]
}You can also use AI to help generate the PRD - just describe your feature and ask it to create a prd.json.
./ralph.sh [max_iterations]Default is 10 iterations.
Understanding Iterations vs API Calls:
- Iterations (controlled by
./ralph.sh N): Fresh AI contexts with clean memory. Each iteration can complete multiple stories. - API calls (shown in debug output): Individual tool executions within an iteration. A single iteration might make 20-50 API calls while completing tasks.
Ralph will:
- Create a feature branch (from PRD
branchName) - Pick the highest priority story where
passes: false - Implement that single story
- Run quality checks (typecheck, tests)
- Commit if checks pass
- Update
prd.jsonto mark story aspasses: true - Append learnings to
progress.txt - Repeat until all stories pass or max iterations reached
| File | Purpose |
|---|---|
ralph.sh |
The bash loop that spawns fresh AI agent instances |
agent.py |
Lightweight agent that calls AI APIs and executes tools |
prompt.md |
Instructions given to each AI agent instance |
.env |
Configuration for AI provider (API keys, models) |
requirements.txt |
Python dependencies (anthropic, openai, python-dotenv) |
prd.json |
User stories with passes status (the task list) |
prd.json.example |
Example PRD format for reference |
progress.txt |
Append-only learnings for future iterations |
SETUP.md |
Detailed setup instructions for all AI providers |
flowchart/ |
Interactive visualization of how Ralph works |
View Interactive Flowchart - Click through to see each step with animations.
The flowchart/ directory contains the source code. To run locally:
cd flowchart
npm install
npm run devEach iteration spawns a new AI agent with clean context. The only memory between iterations is:
- Git history (commits from previous iterations)
progress.txt(learnings and context)prd.json(which stories are done)
Each PRD item should be small enough to complete in one context window. If a task is too big, the LLM runs out of context before finishing and produces poor code.
Right-sized stories:
- Add a database column and migration
- Add a UI component to an existing page
- Update a server action with new logic
- Add a filter dropdown to a list
Too big (split these):
- "Build the entire dashboard"
- "Add authentication"
- "Refactor the API"
After each iteration, Ralph updates the relevant AGENTS.md files with learnings. This helps future iterations (and future human developers) benefit from discovered patterns, gotchas, and conventions.
Examples of what to add to AGENTS.md:
- Patterns discovered ("this codebase uses X for Y")
- Gotchas ("do not forget to update Z when changing W")
- Useful context ("the settings panel is in component X")
Ralph only works if there are feedback loops:
- Typecheck catches type errors
- Tests verify behavior
- CI must stay green (broken code compounds across iterations)
Frontend stories should include manual verification steps. After Ralph completes UI changes, verify them in the browser to ensure they work as expected.
When all stories have passes: true, Ralph outputs <promise>COMPLETE</promise> and the loop exits.
Check current state:
# See which stories are done
cat prd.json | jq '.userStories[] | {id, title, passes}'
# See learnings from previous iterations
cat progress.txt
# Check git history
git log --oneline -10Edit prompt.md to customize Ralph's behavior for your project:
- Add project-specific quality check commands
- Include codebase conventions
- Add common gotchas for your stack
Ralph automatically archives previous runs when you start a new feature (different branchName). Archives are saved to archive/YYYY-MM-DD-feature-name/.
Ralph uses a lightweight Python agent (agent.py) that:
- Reads your prompt from stdin
- Calls your configured AI provider API (Claude, Z.ai, Qwen, or OpenAI)
- The AI responds with tool calls (read_file, write_file, edit_file, run_bash, etc.)
- Agent automatically executes these tools (no confirmations needed)
- Sends results back to the AI
- Loops until the AI outputs
<promise>COMPLETE</promise>
This replaces the need for Amp CLI and makes Ralph provider-agnostic.
Just edit your .env file:
# Use Z.ai
AI_PROVIDER=z.ai
# Or use Claude
AI_PROVIDER=anthropic
# Or use Qwen
AI_PROVIDER=qwen
# Or use OpenAI
AI_PROVIDER=openai
