Ralph:18K+ Star 的 AI 自主编程循环引擎——让 Agent 持续交付
Ralph:18K+ Star 的 AI 自主编程循环引擎——让 AI Agent 像工人一样持续交付
一个只有几百行 Bash 脚本的开源项目,如何撬动 AI 编程的无限可能?
1. 引子:什么是 Ralph?为什么值得写?
2025 年,AI 编程工具迎来了爆发式增长。从 Claude Code、Cursor 到 GitHub Copilot,每一个工具都在试图回答一个问题:AI 能帮我们写多少代码?
但大多数工具的使用模式是相同的:开发者打开终端,输入需求,AI 执行一次,然后停下来等下一个指令。这种”单次对话”模式固然方便,但在面对复杂功能时,往往需要开发者反复介入、反复补充上下文、反复修正方向。
直到 snarktank/ralph 在 GitHub 上出现——短短时间内狂揽 18,071+ Star,成为 AI Agent 工程领域最受关注的项目之一。
Ralph 是什么?
Ralph is an autonomous AI agent loop that runs AI coding tools (Amp or Claude Code) repeatedly until all PRD items are complete. Each iteration is a fresh instance with clean context. Memory persists via git history, progress.txt, and prd.json.
简单来说,Ralph 是一个 AI 编程的”循环引擎”。它基于 Geoffrey Huntley 首创的 Ralph pattern,由 Ryan Carson 在 snarktank 组织下开源。它的核心思想极其简单却极其有力:
给 AI 一份需求文档 → 它自动循环执行 → 每次检查完成度 → 直到全部完成。
没有复杂的编排框架,没有微服务架构,没有消息队列——只有一个几百行的 Bash 脚本,加上几个精心设计的数据文件。
为什么值得深入分析?
- 极简主义的力量:在 AI Agent 框架动辄上万行代码的今天,Ralph 证明了”循环 + 状态文件”的朴素模式可以解决实际问题。
- Fresh Context 范式:每次迭代使用全新上下文,彻底规避了长上下文导致的注意力稀释和幻觉累积。
- 需求驱动开发:以 User Story 为最小执行单元,将敏捷开发理念与 AI 编程深度融合。
- 可审计、可复现:所有状态通过 Git、prd.json、progress.txt 持久化,每一步都可追溯。
接下来,我们深入拆解 Ralph 的架构、设计决策和底层哲学。
2. 核心哲学:循环做一件事做到极致
Ralph 的哲学可以浓缩为一句话:
AI 不擅长一次性完成复杂任务,但擅长重复执行简单任务。
这看似矛盾,实则道出了当前大语言模型的核心局限与优势:
| 能力 | 现状 |
|---|---|
| 一次理解完整需求 | ❌ 容易遗漏、容易偏离 |
| 保持长时间注意力 | ❌ 上下文越长,注意力越分散 |
| 执行单一明确的任务 | ✅ 在清晰指令下表现优秀 |
| 遵循结构化流程 | ✅ 模板化指令执行准确 |
基于这个认知,Ralph 设计了一套**“循环执行 + 状态持久化”**的工作模式:
┌─────────────────────────────────────────────────────┐│ Ralph 循环引擎 ││ ││ PRD (需求文档) ││ │ ││ ▼ ││ ┌──────────┐ ┌──────────┐ ┌──────────┐ ││ │ 第 1 次迭代 │───▶│ 第 2 次迭代 │───▶│ 第 N 次迭代 │ ││ │ Fresh │ │ Fresh │ │ Fresh │ ││ │ Context │ │ Context │ │ Context │ ││ └────┬─────┘ └────┬─────┘ └────┬─────┘ ││ │ │ │ ││ ▼ ▼ ▼ ││ 完成 Story A 完成 Story B 完成 Story C ... ││ │ │ │ ││ └───────────────┴───────────────┘ ││ │ ││ ▼ ││ progress.txt (追加记录) ││ prd.json (状态更新) ││ Git (版本快照) │└─────────────────────────────────────────────────────┘这个循环的每一步都遵循相同的模式:
- 读取当前状态(prd.json、progress.txt)
- 选择最高优先级、未完成的 User Story
- 执行:在干净上下文中实现这个 Story
- 验证:运行 typecheck、tests、必要时浏览器验证
- 提交:检查通过则 commit,更新 prd.json
- 沉淀:将本轮 learnings 追加到 progress.txt
- 判断:是否全部完成?是 → 输出
<promise>COMPLETE</promise>;否 → 进入下一轮
这种设计的精妙之处在于——AI 不需要”记住”之前做了什么,因为它可以从 prd.json 和 progress.txt 中读取所有必要信息。每次迭代都是一个”干净的大脑”,带着”完整的记忆”开始工作。
3. 架构深度解析
3.1 ralph.sh:循环引擎——Bash 如何驱动 AI 编码工具反复执行
Ralph 的核心是一个 Bash 脚本 ralph.sh。这看似”原始”的选择,实际上蕴含了深刻的设计考量。
为什么选择 Bash?
- 零依赖:不需要 Python、Node.js 运行时,任何 Unix 环境都能跑
- 透明:没有隐藏逻辑,开发者可以逐行理解、逐行修改
- 可靠:Bash 的行为是确定性的,不会因为包版本变化而出问题
- 轻量:几百行代码,没有框架负担
脚本的核心执行流程
#!/bin/bash# Ralph Wiggum - Long-running AI agent loop# Usage: ./ralph.sh [--tool amp|claude] [max_iterations]脚本支持两种 AI 工具:Amp(默认)和 Claude Code。通过 --tool 参数指定:
./ralph.sh --tool amp 10./ralph.sh --tool claude 15max_iterations 默认为 10,防止无限循环。
脚本的核心循环结构如下:
for (( i=1; i<=max_iterations; i++ )); do echo "=== Iteration $i / $max_iterations ==="
# 调用 AI 工具执行 prompt if [ "$TOOL" = "amp" ]; then amp --dangerously-allow-all --print < prompt.md else claude --dangerously-skip-permissions --print < prompt.md fi
# 检测完成信号 if grep -q "<promise>COMPLETE</promise>" output.log; then echo "✅ All stories completed!" exit 0 fidone
echo "❌ Reached max iterations ($max_iterations) without completing all stories"exit 1--dangerously-allow-all 和 --dangerously-skip-permissions 是关键参数——它们让 AI 工具在无人工确认的情况下自由执行文件操作、终端命令等。这在自主循环中是必须的,因为人工介入会打破自动化流程。
--print 参数则确保 AI 的完整输出被打印到日志中,供循环引擎检测完成信号。
分支管理与自动归档
Ralph 的一个重要设计是:每次运行自动创建/切换到 feature branch,并在切换分支时归档上次的运行产物。
这意味着:
- 每次 Ralph 运行都在独立的分支上工作,不会污染主分支
- 如果开发者中途切换分支查看代码,Ralph 会自动将上次的中间状态归档保存
- 归档机制防止了多次运行之间的文件冲突
这种设计体现了 Ralph 对开发者工作流的尊重——它不会独占你的项目,你可以在 Ralph 运行的同时自由切换分支、查看进度。
3.2 prompt.md / CLAUDE.md:Agent 指令模板
如果说 ralph.sh 是 Ralph 的心脏,那么 prompt.md(或其等效的 CLAUDE.md)就是 Ralph 的大脑。
Agent 指令的核心内容
prompt.md 是每一轮迭代中发送给 AI 工具的指令模板。它的核心逻辑可以用以下伪代码表示:
=== 第 N 次迭代指令 ===
## 1. 读取状态- 读取 prd.json,获取所有 User Story 及其完成状态- 读取 progress.txt,获取历史 learnings
## 2. 选择任务- 找到 priority 最高且 passes: false 的 User Story- 一次只选一个!
## 3. 实现任务- 切换到 prd.json 中指定的 branchName 分支- 根据 Story 的 description 和 acceptanceCriteria 编写代码- 如果是前端 Story,必须通过 dev-browser 验证
## 4. 质量检查- 运行 typecheck- 运行 tests- 确保全部绿色
## 5. 知识沉淀- 如果本轮发现了新的代码模式或最佳实践,更新 AGENTS.md / CLAUDE.md- 这些模式会在后续迭代中被 AI 自动读取和遵循
## 6. 提交代码- 检查通过后,git commit- 更新 prd.json,将该 Story 标记为 passes: true- 将本轮 learnings 追加到 progress.txt
## 7. 完成判断- 如果所有 Story 都 passes: true → 输出 <promise>COMPLETE</promise>- 否则 → 结束本轮,等待下一轮循环指令模板的精妙之处
-
严格的单任务原则:“一次只选一个!“——强制 AI 专注,避免多任务导致的注意力分散。
-
浏览器验证要求:对于前端 Story,必须通过 dev-browser 验证。这意味着 AI 不仅要写代码,还要亲自”看”效果。这是 Ralph 对前端开发特殊性的深刻理解——代码正确 ≠ 视觉正确。
-
知识沉淀机制:AGENTS.md 是一个动态进化的文件。随着迭代进行,AI 会不断发现项目中的代码模式,并将其写入 AGENTS.md。后续的迭代会自动读取这些模式,确保代码风格一致性。这实际上是一种**“元学习”**机制。
-
XML 标签标记:
<promise>COMPLETE</promise>是一个精心设计的完成信号。XML 标签的使用避免了与自然语言输出混淆,确保循环引擎能准确检测。
3.3 prd.json:需求驱动机制
prd.json 是 Ralph 的”需求数据库”,也是整个循环的状态中枢。
结构示例
{ "project": "My Web App", "branchName": "feature/user-auth", "description": "实现用户认证系统,包括登录、注册、密码重置", "userStories": [ { "id": "US-001", "title": "用户注册页面", "description": "创建一个注册表单,包含邮箱、密码、确认密码字段", "acceptanceCriteria": [ "表单包含邮箱、密码、确认密码输入框", "密码强度验证(至少8字符,包含大小写和数字)", "邮箱格式验证", "提交后显示成功消息", "重复邮箱注册时显示错误提示" ], "priority": 1, "passes": false, "notes": "" }, { "id": "US-002", "title": "用户登录页面", "description": "创建登录表单,支持邮箱密码登录", "acceptanceCriteria": [ "表单包含邮箱和密码输入框", "登录失败时显示错误提示", "登录成功后跳转到首页", "支持'记住我'功能" ], "priority": 2, "passes": false, "notes": "" } ]}prd.json 的设计精髓
User Story 作为最小执行单元
每个 User Story 包含:
id:唯一标识符title:简短描述description:详细说明acceptanceCriteria[]:验收标准列表——这是 AI 判断”是否完成”的依据priority:优先级(数字越小越优先)passes:布尔值,标记是否完成notes:备注,用于记录特殊情况
这种结构的意义在于:
- 可量化:每个 Story 都有明确的验收标准,AI 可以逐条检查
- 可排序:通过 priority 字段控制执行顺序
- 可追踪:passes 字段提供实时进度
- 可扩展:notes 字段允许记录人工干预或特殊情况
与敏捷开发的深度契合
prd.json 的设计与敏捷开发中的 User Story 概念高度一致。在敏捷开发中,User Story 的标准格式是:
As a [角色], I want to [目标], so that [价值]。
Ralph 的 prd.json 虽然没有强制使用这种格式,但其设计哲学完全一致:以用户价值为导向,以可验证的标准为边界。
3.4 progress.txt:记忆持久化
progress.txt 是 Ralph 的”工作日志”。每一次迭代的 learnings 都会被追加到这个文件中。
作用机制
# Iteration 1 Learnings (2025-04-15 10:30)- 发现项目使用 Tailwind CSS 进行样式管理- 组件文件应放在 src/components/ 目录下- TypeScript 配置要求严格模式
# Iteration 2 Learnings (2025-04-15 10:45)- 注册表单需要使用 react-hook-form 进行表单管理- 密码验证使用 zod schema- API 调用使用 axios,基础 URL 从环境变量读取
# Iteration 3 Learnings (2025-04-15 11:00)- 登录成功后 token 存储在 localStorage- 路由保护使用 Higher-Order Component 模式- 错误消息使用统一的 ErrorBanner 组件这种追加式记录有几个关键好处:
- 增量知识积累:AI 每次迭代只写当轮的发现,不会覆盖历史
- 上下文无关:新的 Ralph 实例不需要从之前的对话中恢复状态,只需读取 progress.txt
- 人类可读:开发者可以随时查看 progress.txt 了解 Ralph 做了什么、发现了什么
- Git 友好:progress.txt 的变更可以 diff,可以回滚
3.5 AGENTS.md:知识沉淀
AGENTS.md(或 CLAUDE.md)是 Ralph 的”知识库”。它记录了项目在开发过程中发现的代码模式、最佳实践和约定。
内容示例
# AGENTS.md - Project Knowledge Base
## Code Patterns- 所有组件使用 TypeScript 函数组件- 使用 Tailwind CSS 的 className 进行样式管理- API 调用统一使用 src/api/ 目录下的函数- 错误处理使用 try/catch + toast 通知
## Conventions- 组件文件名使用 PascalCase- 工具函数文件名使用 camelCase- 环境变量前缀为 VITE_- Git commit message 遵循 Conventional Commits
## Learned from Iterations- Iteration 3: 表单验证使用 zod + react-hook-form 组合- Iteration 5: 日期格式化使用 date-fns 而非原生方法- Iteration 7: 列表组件需要实现虚拟滚动以避免性能问题AGENTS.md 与 progress.txt 的区别
| 维度 | progress.txt | AGENTS.md |
|---|---|---|
| 内容性质 | 每次迭代的原始记录 | 提炼后的知识沉淀 |
| 更新方式 | 追加式 | 追加 + 更新 |
| 用途 | 记录”做了什么” | 指导”怎么做” |
| 生命周期 | 随项目持续增长 | 持续精炼,保留有效模式 |
AGENTS.md 是 Ralph 实现**“自我进化”**的关键。随着迭代进行,AI 不断将有效的代码模式写入 AGENTS.md,后续迭代会自动遵循这些模式,从而确保整个项目的代码一致性。
这种机制类似于人类的”经验积累”——第一次做某件事时可能会犯错,但把经验记录下来后,下次就会做得更好。
4. 完整工作流:从 PRD 到自动交付
Ralph 的完整工作流程分为四个阶段:
阶段一:创建 PRD(Product Requirements Document)
开发者首先需要编写一份 PRD 文档,存放在 tasks/prd-[feature-name].md 中。
PRD 的内容通常包括:
- 功能描述
- 用户故事列表
- 技术要求
- 验收标准
PRD 的格式是自由的 Markdown,没有强制模板。这是因为 Ralph 认为需求表达应该是人类友好的,而不是机器友好的。
阶段二:转换 PRD 为 prd.json
Ralph 提供了一个转换脚本(或手动操作),将 PRD 中的 User Story 提取出来,生成结构化的 prd.json。
转换过程包括:
- 解析 Markdown 中的 User Story
- 为每个 Story 分配唯一 ID 和优先级
- 提取验收标准
- 生成 feature branch 名称
这个步骤是**“人类需求 → 机器可执行格式”**的关键转换点。Ralph 没有要求开发者直接编写 JSON,而是允许用自然的 Markdown 表达需求,然后自动转换。这体现了 Ralph 对开发者体验的重视。
阶段三:运行 Ralph
./scripts/ralph/ralph.sh --tool amp 10或者使用 Claude Code:
./scripts/ralph/ralph.sh --tool claude 15运行后,Ralph 会:
- 读取 prd.json
- 创建/切换到 feature branch
- 开始循环执行
阶段四:监控与交付
在 Ralph 运行期间,开发者可以:
- 实时查看 progress.txt 了解进度
- 检查 prd.json 查看哪些 Story 已完成
- 切换到 feature branch 查看代码变更
- 必要时手动干预(编辑 prd.json、补充 acceptanceCriteria)
当所有 Story 完成或达到 max_iterations 时,Ralph 停止运行。此时 feature branch 上已经有了完整的代码变更,等待开发者 code review 和合并。
5. 关键设计决策
5.1 每次迭代 = 全新上下文(Fresh Context)
这是 Ralph 最核心的设计决策,也是它与其他 AI 编程工具的最大区别。
问题背景:
当前的 AI 编程工具(Claude Code、Cursor 等)大多依赖上下文积累——随着对话的进行,AI 会记住之前说过的话、做过的修改。这种模式在短期对话中表现良好,但在长时间、多轮次的任务中存在严重问题:
- 注意力稀释:上下文越长,AI 对早期信息的注意力越弱
- 幻觉累积:早期的错误理解会被后续迭代不断放大
- Token 成本爆炸:长上下文意味着每次调用都需要传输大量历史数据
- 不可复现:相同的需求,在不同对话上下文中可能得到不同的结果
Ralph 的解决方案:
┌──────────────────────────────────────────────┐│ 传统模式 vs Fresh Context ││ ││ 传统模式: ││ Iteration 1: 上下文 = [] ││ Iteration 2: 上下文 = [Iteration 1 的全部对话] ││ Iteration 3: 上下文 = [Iteration 1 + 2] ││ ... ││ Iteration 10: 上下文 = [1+2+3+...+9] ← 💥 ││ ││ Ralph 模式: ││ Iteration 1: 上下文 = [prompt.md] ││ Iteration 2: 上下文 = [prompt.md] ││ Iteration 3: 上下文 = [prompt.md] ││ ... ││ Iteration 10: 上下文 = [prompt.md] ← ✅ 干净 │└──────────────────────────────────────────────┘每次迭代,AI 工具被作为一个全新的进程启动,没有任何历史对话。它需要的”记忆”全部来自:
- prd.json:当前需求和进度
- progress.txt:历史 learnings
- AGENTS.md:代码模式和约定
- Git 仓库:当前代码状态
这种设计带来了一个深刻的洞见:AI 的记忆不应该是对话历史,而应该是结构化的状态文件。
5.2 小故事拆分原则
Ralph 要求每个 User Story 必须足够小——能在一个 context window 内完成。
为什么?
如果一个 Story 太大,AI 在一次迭代中无法完成,就会出现:
- 代码写了一半但没有 commit
- 质量检查无法通过
- progress.txt 记录不完整
- 下一轮迭代不知道从哪里继续
拆分原则:
-
一个 Story = 一个可交付的功能点
- ❌ “实现用户管理系统”
- ✅ “实现用户注册页面”
- ✅ “实现用户登录页面”
- ✅ “实现密码重置功能”
-
每个 Story 有明确的验收标准
- 验收标准应该是可验证的、具体的
- 避免模糊的描述
-
Story 之间尽量独立
- 减少跨 Story 的依赖
- 如果必须依赖,通过 priority 控制顺序
拆分示例:
// ❌ 不好的拆分{ "id": "US-001", "title": "实现完整的用户系统", "description": "包括注册、登录、个人中心、密码修改等所有功能", "acceptanceCriteria": ["..."]}
// ✅ 好的拆分{ "id": "US-001", "title": "用户注册", "description": "创建注册表单,支持邮箱注册", "acceptanceCriteria": [ "表单包含邮箱和密码输入", "密码强度验证", "注册成功显示提示" ], "priority": 1},{ "id": "US-002", "title": "用户登录", "description": "创建登录表单,支持邮箱密码登录", "acceptanceCriteria": [ "表单包含邮箱和密码输入", "登录成功跳转首页", "登录失败显示错误" ], "priority": 2}5.3 反馈闭环:Typecheck/Test/CI 必须保持绿色
Ralph 强制要求每次迭代后运行质量检查:
实现 Story │ ▼运行 typecheck │ ▼运行 tests │ ▼全部绿色? ──── 是 ────▶ 提交代码 │ 否 │ ▼修复问题(在同一迭代内完成)这个闭环有几个关键意义:
- 即时反馈:问题在当前迭代内就被发现和修复,不会累积
- 质量保证:即使 AI 写的代码有 bug,也会被 typecheck 和 tests 捕获
- 可合并:每次提交的代码都通过了基本检查,降低了 review 成本
Ralph 没有依赖外部的 CI 系统(如 GitHub Actions),而是在每个迭代内部完成质量检查。这意味着:
- 不需要等待 CI 流水线
- 反馈是即时的
- AI 可以在发现问题后立即修复
5.4 浏览器自动验证:前端 Story 必须通过 dev-browser 验证
对于前端相关的 User Story,Ralph 要求通过 dev-browser 进行自动验证。
这意味着 AI 不仅要确保代码能通过 typecheck 和 tests,还要确保在浏览器中的表现符合预期。
这个设计解决了 AI 编程中的一个经典问题:代码正确 ≠ 视觉正确。
- TypeScript 类型检查通过?✅
- 单元测试通过?✅
- 但按钮的颜色不对、布局错位、交互不流畅?❌
dev-browser 验证确保了 AI 能够”亲眼看到”自己的代码效果,从而及时调整。这是 Ralph 对前端开发特殊性的深刻理解。
6. 代码分析:逐段解读 ralph.sh 核心逻辑
让我们逐段分析 ralph.sh 的核心逻辑。
6.1 参数解析
#!/bin/bash# Ralph Wiggum - Long-running AI agent loop# Usage: ./ralph.sh [--tool amp|claude] [max_iterations]
TOOL="amp"MAX_ITERATIONS=10
# 解析 --tool 参数while [[ $# -gt 0 ]]; do case "$1" in --tool) TOOL="$2" shift 2 ;; *) MAX_ITERATIONS="$1" shift ;; esacdone
# 验证工具选择if [[ "$TOOL" != "amp" && "$TOOL" != "claude" ]]; then echo "❌ Invalid tool: $TOOL. Use 'amp' or 'claude'." exit 1fi这段代码展示了 Ralph 的参数解析逻辑:
- 支持
--tool参数指定 AI 工具 - 支持位置参数指定最大迭代次数
- 默认使用 Amp 工具,最大迭代 10 次
- 参数验证确保工具名称合法
6.2 分支管理与自动归档
# 读取 prd.json 中的 branchNameBRANCH_NAME=$(jq -r '.branchName' prd.json)
# 检查是否需要归档上次运行if git rev-parse --verify "$BRANCH_NAME" >/dev/null 2>&1; then echo "📦 Archiving previous run on $BRANCH_NAME" # 创建归档分支,保留上次运行的中间状态 ARCHIVE_BRANCH="archive/${BRANCH_NAME}-$(date +%Y%m%d%H%M%S)" git branch -m "$BRANCH_NAME" "$ARCHIVE_BRANCH"fi
# 创建新的 feature branchgit checkout -b "$BRANCH_NAME"这段代码处理分支的生命周期:
- 从 prd.json 读取目标分支名
- 如果分支已存在,将其重命名为归档分支(带时间戳)
- 创建新的 feature branch 开始本次运行
归档机制确保了:
- 上次运行的中间状态不会丢失
- 本次运行在干净的分支上开始
- 开发者可以随时切换到归档分支查看历史
6.3 主循环
for (( i=1; i<=MAX_ITERATIONS; i++ )); do echo "" echo "═══════════════════════════════════════" echo "🔄 Iteration $i / $MAX_ITERATIONS" echo "═══════════════════════════════════════" echo ""
# 执行 AI 工具 echo "🤖 Running $TOOL..." if [ "$TOOL" = "amp" ]; then amp --dangerously-allow-all --print < scripts/ralph/prompt.md > "iteration-${i}.log" 2>&1 else claude --dangerously-skip-permissions --print < scripts/ralph/prompt.md > "iteration-${i}.log" 2>&1 fi
# 显示本轮输出摘要 echo "📋 Iteration $i output:" tail -20 "iteration-${i}.log"
# 检测完成信号 if grep -q "<promise>COMPLETE</promise>" "iteration-${i}.log"; then echo "" echo "🎉 All stories completed successfully!" echo "✅ Feature branch '$BRANCH_NAME' is ready for review." exit 0 fi
# 检查是否还有未完成的 Story REMAINING=$(jq '[.userStories[] | select(.passes == false)] | length' prd.json) if [ "$REMAINING" -eq 0 ]; then echo "" echo "🎉 All stories completed!" exit 0 fi
echo "📊 Remaining stories: $REMAINING"done主循环的逻辑清晰而优雅:
- 循环计数器:
for (( i=1; i<=MAX_ITERATIONS; i++ ))控制最大迭代次数 - AI 工具调用:根据
$TOOL选择 amp 或 claude,通过管道将 prompt.md 作为输入 - 日志记录:每次迭代的输出保存到
iteration-${i}.log - 完成检测:通过
grep搜索<promise>COMPLETE</promise>信号 - 备用检测:即使没有 COMPLETE 信号,也检查 prd.json 中是否还有未完成的 Story
- 进度显示:每次迭代结束后显示剩余 Story 数量
6.4 退出逻辑
# 达到最大迭代次数但未完成echo ""echo "❌ Reached max iterations ($MAX_ITERATIONS) without completing all stories"echo ""
REMAINING=$(jq '[.userStories[] | select(.passes == false)] | length' prd.json)echo "📊 Remaining stories: $REMAINING"echo ""echo "💡 Suggestions:"echo " 1. Review progress.txt for learnings"echo " 2. Check prd.json for failed stories"echo " 3. Consider increasing max_iterations"echo " 4. Manually complete remaining stories"echo ""
exit 1当达到最大迭代次数但仍有未完成的 Story 时,Ralph 不会静默退出,而是:
- 明确告知用户失败原因
- 显示剩余 Story 数量
- 提供具体的后续建议
- 以 exit code 1 退出,方便 CI 集成
6.5 完整的控制流
将以上部分整合,Ralph 的完整控制流如下:
开始 │ ▼解析参数 (--tool, max_iterations) │ ▼读取 prd.json (branchName) │ ▼分支管理 (归档旧分支 → 创建新分支) │ ▼┌─ 主循环 ───────────────────────┐│ ││ 显示迭代信息 ││ ││ 调用 AI 工具执行 prompt ││ ││ 检测 <promise>COMPLETE</promise>││ │ ││ ├─ 是 → 成功退出 (exit 0) ││ │ ││ └─ 否 → 继续 ││ ││ 检查 prd.json 是否全部完成 ││ │ ││ ├─ 是 → 成功退出 (exit 0) ││ │ ││ └─ 否 → 继续下一轮 ││ │└─ 达到 max_iterations ──────────┘ │ ▼显示失败信息和建议 │ ▼失败退出 (exit 1)7. 与其他 Agent 框架对比
7.1 vs. Claude Code 单次使用
| 维度 | Claude Code 单次使用 | Ralph |
|---|---|---|
| 执行模式 | 一次对话,完成后停止 | 循环执行,直到全部完成 |
| 上下文管理 | 依赖对话历史积累 | 每次 Fresh Context |
| 需求表达 | 自由文本 | 结构化的 prd.json |
| 进度追踪 | 无内置机制 | prd.json + progress.txt |
| 质量保证 | 开发者手动检查 | 每次迭代自动 typecheck/test |
| 适合场景 | 小型任务、快速原型 | 中型功能、多 Story 交付 |
关键差异:Claude Code 是一个工具,Ralph 是一个流程。Claude Code 解决了”如何让 AI 写代码”的问题,Ralph 解决了”如何让 AI 持续、可靠地交付完整功能”的问题。
7.2 vs. OpenClaw
OpenClaw 是另一个流行的 AI Agent 框架,它采用了不同的设计哲学:
| 维度 | OpenClaw | Ralph |
|---|---|---|
| 架构 | 复杂的多 Agent 协作系统 | 单一 Agent 循环 |
| 状态管理 | 内部状态机 | 外部状态文件(Git + JSON + TXT) |
| 可观测性 | 需要专用 Dashboard | 直接查看文件 |
| 学习曲线 | 高(需要理解框架概念) | 低(Bash 脚本 + JSON) |
| 定制性 | 通过配置和插件 | 直接修改脚本和模板 |
| 适用规模 | 大型项目、复杂编排 | 中小功能、快速迭代 |
核心差异:OpenClaw 追求的是通用性和扩展性,Ralph 追求的是简单性和实用性。Ralph 的哲学是:如果一个 Bash 脚本能解决问题,就不需要引入一个框架。
7.3 vs. 其他 Agent 框架
| 框架 | 核心思路 | 与 Ralph 的差异 |
|---|---|---|
| MetaGPT | 多角色协作(产品经理→架构师→工程师) | Ralph 是单一角色循环,更简单 |
| AutoGen | 多 Agent 对话 | Ralph 没有 Agent 间对话,只有循环 |
| CrewAI | 角色+任务+流程编排 | Ralph 的流程是固定的循环 |
| LangGraph | 图结构的状态机 | Ralph 是线性循环,无图结构 |
Ralph 的”反潮流”之处在于:在所有框架都在追求复杂编排的今天,它选择了最朴素的循环模式。但这恰恰是它的优势——简单、可靠、可理解。
8. 实际使用场景
8.1 适合的项目类型
Ralph 最适合以下类型的项目:
✅ 前端 Web 应用
- 有明确的用户界面需求
- 需要浏览器验证
- 有 typecheck 和 tests 基础设施
✅ API 服务
- 有明确的接口定义
- 有自动化测试
- 需求可以拆分为独立的 User Story
✅ 内部工具
- 需求明确,不需要大量用户调研
- 快速迭代,快速交付
- 对代码质量有要求但不需要极致优化
8.2 适合的需求类型
✅ 适合 Ralph 的需求:
- 功能明确的中等复杂度需求(5-15 个 User Story)
- 可以清晰拆分为独立 Story 的需求
- 有现成代码库作为基础的需求(Greenfield 项目也可以,但需要更多 setup Story)
❌ 不适合 Ralph 的需求:
- 需求不明确、需要大量探索性开发
- 需要深度架构设计的系统
- 高度依赖领域知识的需求
- 需要大量跨系统集成的需求
8.3 最佳实践
-
花时间在 PRD 上:Ralph 的输出质量直接取决于 PRD 的质量。花时间写好 PRD,拆分好 User Story,比任何优化都有效。
-
从小故事开始:第一次使用 Ralph 时,选择一个小功能(2-3 个 Story)进行试验,熟悉流程后再尝试更大的需求。
-
善用 progress.txt:定期检查 progress.txt,了解 Ralph 学到了什么。这些信息对于改进后续的 PRD 编写非常有价值。
-
保持 CI 绿色:确保项目的 typecheck 和 tests 能够快速运行。如果 CI 太慢,Ralph 的每次迭代都会浪费大量时间。
-
定期合并:不要等 Ralph 运行完所有 Story 才合并。每完成 2-3 个 Story 就可以创建一个 PR 进行 review,降低集成风险。
9. 局限性与改进空间
9.1 客观分析不足
没有任何工具是完美的。Ralph 也不例外。以下是其当前的局限性:
1. 需求拆分依赖人工
Ralph 要求开发者手动将 PRD 拆分为 prd.json 中的 User Story。对于不熟悉敏捷开发的开发者来说,这一步可能比较困难。如果 Story 拆分不合理(太大或太小),Ralph 的执行效率会大打折扣。
改进方向:引入 AI 辅助拆分——让 Claude Code 自动将 PRD 转换为 prd.json,自动拆分 Story。
2. 错误恢复能力有限
当 AI 在某次迭代中写了错误的代码但 typecheck/tests 未能捕获时,Ralph 会在错误的代码基础上继续迭代。错误的累积可能导致后续迭代越来越偏离正确方向。
改进方向:增加代码 diff review 机制,在每次 commit 前对变更进行自动化代码审查。
3. 依赖特定 AI 工具
Ralph 目前只支持 Amp 和 Claude Code。如果这两个工具不可用(网络问题、API 限制等),Ralph 无法运行。
改进方向:支持更多 AI 工具(Cursor CLI、GPT Engineer 等),增加工具降级策略。
4. 缺乏并行执行能力
Ralph 的循环是串行的——每次只处理一个 Story。对于可以并行开发的独立 Story,这导致效率低下。
改进方向:支持并行模式——同时启动多个 Ralph 实例,各自处理不同的 Story,最后合并。
5. 前端验证依赖 dev-browser
虽然浏览器自动验证是 Ralph 的亮点,但 dev-browser 的配置和使用可能比较复杂,尤其对于没有前端开发经验的 AI。
改进方向:集成更完善的端到端测试框架(如 Playwright),让 AI 能够编写和运行自动化 UI 测试。
6. 知识沉淀的噪声问题
progress.txt 和 AGENTS.md 会随着迭代不断增长,其中可能包含大量无效或过时的信息。如何让 AI 从海量记录中提取有用信息是一个挑战。
改进方向:引入知识精炼机制——定期清理 progress.txt,保留关键 learnings;AGENTS.md 增加过期标记。
9.2 与理想状态的差距
理想的 AI 自主编程系统应该具备以下能力:
- 自动理解模糊需求
- 自动拆分任务
- 自动发现架构问题
- 自动进行代码 review
- 自动处理冲突和合并
- 自主学习项目规范和模式
Ralph 在”自动循环执行”方面做得很好,但在其他方面仍然依赖人工。这是当前 AI 编程工具的共性限制,不是 Ralph 独有的问题。
10. 总结与展望
10.1 Ralph 的核心价值
回顾全文,Ralph 的核心价值可以总结为三个关键词:
简单(Simple)
- 几百行 Bash 脚本
- 几个状态文件(prd.json、progress.txt、AGENTS.md)
- 没有框架,没有依赖,没有黑盒
可靠(Reliable)
- Fresh Context 避免了长上下文的幻觉问题
- 每次迭代的质量检查确保代码可合并
- Git 版本控制确保每一步可追溯
可扩展(Extensible)
- 支持多种 AI 工具(Amp、Claude Code)
- prompt.md 可以根据项目需求定制
- prd.json 的格式可以根据需要扩展
10.2 Ralph 的启示
Ralph 给 AI 编程领域带来了几个重要的启示:
1. 简单往往比复杂更有效
在 AI Agent 框架追求越来越复杂的今天,Ralph 证明了:一个设计良好的循环 + 几个状态文件,就能解决实际问题。这不是”简陋”,而是”极简”。
2. 结构化状态优于对话历史
Ralph 用 prd.json、progress.txt、AGENTS.md 替代了传统的对话历史,让 AI 的”记忆”变得结构化、可查询、可编辑。这为 AI 编程的状态管理提供了一种新的范式。
3. Fresh Context 是一个被低估的模式
每次迭代使用全新上下文,虽然看起来”浪费”(AI 需要重新学习项目状态),但实际上避免了长上下文的诸多问题。这种”浪费”是一种刻意的trade-off——用更多的 API 调用换取更高的可靠性和更一致的质量。
10.3 未来展望
随着 AI 编码工具的不断进化,Ralph 的循环模式可能会演化为:
- 更智能的需求理解:AI 自动将自然语言需求转换为 prd.json
- 更好的错误恢复:自动检测偏离方向并回滚
- 并行执行:多实例同时处理独立 Story
- 跨项目知识迁移:AGENTS.md 的模式可以跨项目复用
- 与 CI/CD 深度集成:Ralph 运行完成后自动创建 PR、触发 CI、通知 reviewer
但无论未来如何演变,Ralph 的核心理念——循环执行、Fresh Context、结构化状态、需求驱动——都将继续影响 AI 编程工具的设计方向。
10.4 最后的思考
Ralph 不是一个完美的工具,但它代表了一种务实的、渐进式的 AI 编程方法论。它不追求”AI 替我写完整个项目”,而是追求”AI 替我完成一个个小故事,每个都质量可靠”。
这种**“化整为零、步步为营”**的思路,或许才是当前 AI 编程最务实的落地路径。
在这个追求 AGI 的时代,Ralph 提醒我们:有时候,最聪明的做法不是让 AI 变得更聪明,而是让任务变得更简单。
本文基于 snarktank/ralph 项目(GitHub)编写,项目 Star 数截至 2025 年。Ralph 基于 Geoffrey Huntley 的 Ralph pattern 开发,由 Ryan Carson 在 snarktank 组织下开源。
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!