Ralph AI代理解读

这是我见过的最简单的自主代码循环——以及它为何如此有效。

你懂那种感觉吗?你又提交了一个 commit。测试不稳定。你的大脑已经一片空白。而待办事项列表仍然像在盯着你一样,仿佛知道你已经筋疲力尽。

去年我遇到了这种困境。说实话,我开始思考是否有其他的工作方式。不是那种“人工智能将取代工程师”的无稽之谈,而是更枯燥、更实用的东西。它能让我停下来,它却能继续运行。

这就是 Ralph 的用武之地。

现在大家都在热议 Ralph,我完全理解。它并不花哨,也不神奇,简单到几乎让人失望。

但它能持续输出代码,即使你睡着了。

让我带你了解它究竟是什么,它是如何工作的,以及为什么这种方法会悄然改变我们构建软件的方式。

1、Ralph 的本质

Ralph 是一个自主的 AI 编码循环。

它不是代理框架,也不是 SaaS 控制面板,更不是研究演示。

它只是一个持续运行的 bash 脚本,不断地向 AI 编码代理提供指令,并让 git 充当内存。

这就是它的精髓所在。

这是我真希望早点有人告诉我的思维模型:

Ralph 与其说像个天才工程师,不如说更像个不知疲倦、严格按照指令执行、并且把所有事情都记录下来的初级开发人员。

说实话……这就足够了。

2、核心思想

Ralph 的核心在于不断重复做一件事:

  • 读取一系列明确的小任务
  • 选择下一个任务
  • 执行该任务
  • 运行检查
  • 如果检查通过则提交
  • 记录学习到的内容
  • 重复

没有长期隐藏记忆。没有向量数据库。没有“人工智能认知”。

只有文件。以及 Git。

这就是它有效的原因。

3、循环的工作原理

让我们放慢速度,就像你坐在我旁边,我们一起阅读代码一样,一步一步地来。

Ralph 是一个 Bash 循环,它执行以下操作:

  • 将提示信息传递给你的 AI 代理
  • 代理从 prd.json 中选择下一个故事
  • 执行该故事
  • 运行类型检查和测试
  • 如果通过则提交
  • 将故事标记为已完成
  • 记录学习成果
  • 再次循环

就是这样。

内存仅保留在以下位置:

  • Git 提交
  • progress.txt(学习成果)
  • prd.json(任务状态)

除此之外没有其他状态。这乍一看似乎有些局限,但当你意识到……这正是人类团队协作的方式时,一切就迎刃而解了。

4、文件结构

以下是完整的 Ralph 设置:

scripts/ralph/
├── ralph.sh
├── prompt.md
├── prd.json
└── progress.txt

四个文件。这就是整个系统。

如果这让你感觉简洁明了,那是因为它的确如此。

4.1 循环:ralph.sh

这是引擎。请仔细阅读。

#!/bin/bash
set -e

MAX_ITERATIONS=${1:-10}
SCRIPT_DIR="$(cd "$(dirname \
  "${BASH_SOURCE[0]}")" && pwd)"
echo "Starting Ralph"
for i in $(seq 1 $MAX_ITERATIONS); do
  echo "═══ Iteration $i ═══"
  
  OUTPUT=$(cat "$SCRIPT_DIR/prompt.md" \
    | amp --dangerously-allow-all 2>&1 \
    | tee /dev/stderr) || true
  
  if echo "$OUTPUT" | \
    grep -q "<promise>COMPLETE</promise>"
  then
    echo "Done!"
    exit 0
  fi
  
  sleep 2
done
echo "Max iterations reached"
exit 1

有几点需要注意。

首先,这不是“AI 编排”。它是一个 for 循环。

其次,AI 智能体无法决定何时完成。代码可以。循环只有在智能体明确输出以下内容时才会停止:

<promise>COMPLETE</promise>

这个约束比它看起来更重要。它迫使智能体思考任务完成情况,而不是仅仅闲逛。

是的,你可以更换智能体。人们也在使用 Claude Code:

claude --dangerously-skip-permissions

循环不会在意这一点。

4.2 使其可运行

一个虽小但重要的步骤:

chmod +x scripts/ralph/ralph.sh

如果你忘记了这种细节,智能体就会出错。说实话,人类也会犯同样的错误。

4.3 大脑:prompt.md

这个文件里住着拉尔夫的“个性”。所谓个性,我指的是规则。

# Ralph Agent Instructions

## Your Task
1. Read `scripts/ralph/prd.json`
2. Read `scripts/ralph/progress.txt`
   (check Codebase Patterns first)
3. Check you're on the correct branch
4. Pick highest priority story 
   where `passes: false`
5. Implement that ONE story
6. Run typecheck and tests
7. Update AGENTS.md files with learnings
8. Commit: `feat: [ID] - [Title]`
9. Update prd.json: `passes: true`
10. Append learnings to progress.txt
## Progress Format
APPEND to progress.txt:
## [Date] - [Story ID]
- What was implemented
- Files changed
- **Learnings:**
  - Patterns discovered
  - Gotchas encountered
---
## Codebase Patterns
Add reusable patterns to the TOP 
of progress.txt:
## Codebase Patterns
- Migrations: Use IF NOT EXISTS
- React: useRef<Timeout | null>(null)
## Stop Condition
If ALL stories pass, reply:
<promise>COMPLETE</promise>
Otherwise end normally.

这里蕴含着一个微妙却强大的理念。

Ralph 并非被要求“构建一个功能”,而是被要求按照清单执行操作。

这就是混乱与稳步推进之间的区别。

4.4 任务清单:prd.json

这是你的待办事项列表,但结构清晰,代理不会产生任何误解。

{
  "branchName": "ralph/feature",
  "userStories": [
    {
      "id": "US-001",
      "title": "Add login form",
      "acceptanceCriteria": [
        "Email/password fields",
        "Validates email format",
        "typecheck passes"
      ],
      "priority": 1,
      "passes": false,
      "notes": ""
    }
  ]
}

以下三个字段的重要性远超人们的想象:

  • priority — 优先级越低,优先级越高
  • passes — 唯一权威的验证结果
  • acceptanceCriteria — 不可协商

如果你在这里含糊其辞,Ralph 会惩罚你,发布一些毫无意义的内容。而这完全是你的错,与AI代理无关。

4.5 内存:progress.txt

此文件最初很简单:

# Ralph Progress Log
Started: 2024-01-15

## Codebase Patterns
- Migrations: IF NOT EXISTS
- Types: Export from actions.ts
## Key Files
- db/schema.ts
- app/auth/actions.ts
---

然后它不断增长。

每次处理完一个故事后,Ralph 都会添加以下内容:

  • 更改内容
  • 更改位置
  • 学习到的内容

随着时间的推移,这些信息变得非常有价值。到第 10 个故事时,代理不再猜测,而是遵循它自己发现的模式。

这就是默默无闻的魔力。

5、运行 Ralph

这部分感觉有点虎头蛇尾。

./scripts/ralph/ralph.sh 25

就这样。

最多 25 次迭代。每个用户:

  • 拉取下一个故事
  • 执行
  • 提交
  • 继续

当所有任务都完成后,它会自动停止。

6、为什么它真的有效

让我先发表一下我的看法。

大多数自主编码系统失败是因为它们试图变得“聪明”。Ralph 之所以有效,是因为它以正确的方式保持“愚蠢”。

以下是真正的成功因素。

6.1 小故事

这是人们容易犯错的地方。

 Too big:
> "Build entire auth system"

这肯定会失败。每次都会失败。

 Right size:
> "Add login form"
> "Add email validation"
> "Add auth server action"

如果它无法在一个上下文窗口中显示,就不应该放在 Ralph 中。

要果断。

6.2 快速反馈循环

Ralph 需要快速知道它是否破坏了什么。

至少需要:

  • npm run typecheck
  • npm test

如果没有这些命令,错误会悄无声息地累积。然后,由于第 2 次迭代出错,第 8 次迭代就会崩溃。

6.3 明确的验收标准

这是“能用”和“真正能用”之间的区别。

 Vague:
> "Users can log in"
 Explicit:
> - Email/password fields
> - Validates email format
> - Shows error on failure
> - typecheck passes
> - Verify at localhost:$PORT/login (PORT defaults to 3000)

Ralph 不会推断意图。它只是执行指令。

这是一个特性。

6,4 经验累积

这是人们低估的部分。

到第 10 个故事时,Ralph 已经知道:

  • 如何编写迁移脚本
  • 类型存储在哪里
  • 哪些测试容易出错
  • 哪些模式可以复用

这些经验记录在两个地方:

  • progress.txt — 短期记忆
  • AGENTS.md — 长期文档

这就是系统如何在不增加复杂性的情况下不断改进的方式。

6.5 AGENTS.md 的重要性

当 Ralph 发现可复用的内容时,它会更新 AGENTS.md 文件。

优秀示例:

- "When modifying X, also update Y"
- "This module uses pattern Z"
- "Tests require dev server running"

糟糕示例:

- Story-specific notes
- Temporary hacks
- Things already in progress.txt

可以将 AGENTS.md 视为机构记忆。它既服务于人类,也服务于机器。

6.6 浏览器测试(用于 UI 工作)

UI 工作需要人眼。

Ralph 也可以使用 dev-browser 技能来实现:

# Start the browser server
~/.config/amp/skills/dev-browser/server.sh &
# Wait for "Ready" message

然后启动一个脚本化的浏览器会话:

cd ~/.config/amp/skills/dev-browser && npx tsx <<'EOF'
import { connect, waitForPageLoad } from "@/client.js";

const client = await connect();
const page = await client.page("test");
await page.setViewportSize({ width: 1280, height: 900 });
const port = process.env.PORT || "3000";
await page.goto(`http://localhost:${port}/your-page`);
await waitForPageLoad(page);
await page.screenshot({ path: "tmp/screenshot.png" });
await client.disconnect();
EOF

如果没有截图,故事就还没完成。就这么简单。

7、常见陷阱

你会遇到的一些问题。

幂等迁移:

ADD COLUMN IF NOT EXISTS email TEXT;

交互式提示:

echo -e "\n\n\n" | npm run db:generate

模式更改的影响:

编辑模式后,务必检查:

  • 服务器操作
  • UI 组件
  • API 路由

修复相关文件不是范围蔓延,而是现实。

8、监控进度

这部分很有成就感。

# Story status
cat scripts/ralph/prd.json | \
jq '.userStories[] | {id, passes}'
# Learnings
cat scripts/ralph/progress.txt
# Commits
git log --oneline -10

一边做其他事一边看着提交记录出现,感觉……出奇地平静。

9、成果

我们使用 Ralph 构建了一个评估系统。

  • 13 个用户故事
  • 约 15 次迭代
  • 每次迭代 2-5 分钟
  • 总共约 1 小时

到最后,代理不再进行实验,而是直接执行。

就是这样这就是迭代和自动化的区别。

10、何时不应使用 Ralph

首先要明确一点。它并非万能工具。

请勿将 Ralph 用于:

  • 探索性工作
  • 缺乏标准的重大重构
  • 安全关键代码
  • 任何需要人工判断的工作

Ralph 是一个执行者,而非架构师。

11、更大的转变

以下几点让我印象深刻。

Ralph 不会取代工程师,而是取代浪费的精力。

它将清晰的思考转化为可重复的执行。这非常强大。

如果你能将工作分解成诚实、可测试的步骤……如果你能明确“完成”的真正含义……如果你愿意稍微放手……

那么,是的,你或许终于可以睡个安稳觉了。

醒来就能看到已经交付的代码。


原文链接:Claude Code + Ralph: How I Built an AI That Ships Production Code While I Sleep

汇智网翻译整理,转载请标明出处