Ralph Loops: 用简单循环替代复杂AI工作流
Ralph Loop 源自《辛普森一家》中的 Ralph Wiggum 角色------一遍遍地重复同样的事情,最终总能成功
这个概念由 Matt Pocock 提出:**让 AI 完成任务后,再用同样的提示让它重新执行,AI 会发现之前遗漏的内容并自我修正 **
这种"笨拙的重复循环"比精心设计的复杂工作流更有效
简单循环优于复杂编排
为什么复杂工作流会失败
用 N8N 构建的复杂新闻简报工作流:
- 包含多个并行分支(文章摘要流、链接抓取流、评论生成流)
- 需要大量调试,频繁失败
- 维护成本甚至高于手动完成工作本身
Claude Code 本身就是循环
Claude Code 的本质就是一个 Ralph Loop:
- 读取技能/指令
- 调用工具执行
- 回到起点,重复直到完成
#mermaid-svg-Bj5BfrLCeKTDoy8i{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Bj5BfrLCeKTDoy8i .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Bj5BfrLCeKTDoy8i .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Bj5BfrLCeKTDoy8i .error-icon{fill:#552222;}#mermaid-svg-Bj5BfrLCeKTDoy8i .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Bj5BfrLCeKTDoy8i .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Bj5BfrLCeKTDoy8i .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Bj5BfrLCeKTDoy8i .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Bj5BfrLCeKTDoy8i .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Bj5BfrLCeKTDoy8i .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Bj5BfrLCeKTDoy8i .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Bj5BfrLCeKTDoy8i .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Bj5BfrLCeKTDoy8i .marker.cross{stroke:#333333;}#mermaid-svg-Bj5BfrLCeKTDoy8i svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Bj5BfrLCeKTDoy8i p{margin:0;}#mermaid-svg-Bj5BfrLCeKTDoy8i .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-Bj5BfrLCeKTDoy8i .cluster-label text{fill:#333;}#mermaid-svg-Bj5BfrLCeKTDoy8i .cluster-label span{color:#333;}#mermaid-svg-Bj5BfrLCeKTDoy8i .cluster-label span p{background-color:transparent;}#mermaid-svg-Bj5BfrLCeKTDoy8i .label text,#mermaid-svg-Bj5BfrLCeKTDoy8i span{fill:#333;color:#333;}#mermaid-svg-Bj5BfrLCeKTDoy8i .node rect,#mermaid-svg-Bj5BfrLCeKTDoy8i .node circle,#mermaid-svg-Bj5BfrLCeKTDoy8i .node ellipse,#mermaid-svg-Bj5BfrLCeKTDoy8i .node polygon,#mermaid-svg-Bj5BfrLCeKTDoy8i .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Bj5BfrLCeKTDoy8i .rough-node .label text,#mermaid-svg-Bj5BfrLCeKTDoy8i .node .label text,#mermaid-svg-Bj5BfrLCeKTDoy8i .image-shape .label,#mermaid-svg-Bj5BfrLCeKTDoy8i .icon-shape .label{text-anchor:middle;}#mermaid-svg-Bj5BfrLCeKTDoy8i .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Bj5BfrLCeKTDoy8i .rough-node .label,#mermaid-svg-Bj5BfrLCeKTDoy8i .node .label,#mermaid-svg-Bj5BfrLCeKTDoy8i .image-shape .label,#mermaid-svg-Bj5BfrLCeKTDoy8i .icon-shape .label{text-align:center;}#mermaid-svg-Bj5BfrLCeKTDoy8i .node.clickable{cursor:pointer;}#mermaid-svg-Bj5BfrLCeKTDoy8i .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Bj5BfrLCeKTDoy8i .arrowheadPath{fill:#333333;}#mermaid-svg-Bj5BfrLCeKTDoy8i .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Bj5BfrLCeKTDoy8i .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Bj5BfrLCeKTDoy8i .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Bj5BfrLCeKTDoy8i .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Bj5BfrLCeKTDoy8i .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Bj5BfrLCeKTDoy8i .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Bj5BfrLCeKTDoy8i .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Bj5BfrLCeKTDoy8i .cluster text{fill:#333;}#mermaid-svg-Bj5BfrLCeKTDoy8i .cluster span{color:#333;}#mermaid-svg-Bj5BfrLCeKTDoy8i div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Bj5BfrLCeKTDoy8i .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Bj5BfrLCeKTDoy8i rect.text{fill:none;stroke-width:0;}#mermaid-svg-Bj5BfrLCeKTDoy8i .icon-shape,#mermaid-svg-Bj5BfrLCeKTDoy8i .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Bj5BfrLCeKTDoy8i .icon-shape p,#mermaid-svg-Bj5BfrLCeKTDoy8i .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Bj5BfrLCeKTDoy8i .icon-shape rect,#mermaid-svg-Bj5BfrLCeKTDoy8i .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Bj5BfrLCeKTDoy8i .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Bj5BfrLCeKTDoy8i .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Bj5BfrLCeKTDoy8i :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 读取Skill
调用工具
决定下一步
这种"读取→执行→再读取→再执行"的简单循环,最终产出的新闻简报质量反而更高
Ralph Loop 的三个发展阶段
第一阶段:基础循环
最简单的 Ralph Loop 只需要一个 while 循环:
bash
while true; do
claude "implement doc tickets/0.0.1"
done
操作步骤:
- 创建 tickets 文件夹,每张 ticket 是一个 markdown 文件
- 让 Claude 读取 ticket 并实现功能
- 完成后,用相同的提示再次执行
- AI 会发现遗漏并补充
示例 ticket 格式:
markdown
# Ticket 0.0.1: 实现状态查询功能
## 需求
能够查询当前 Pomodoro 的状态和剩余时间
## 验收标准
- `pomodoro status` 命令可用
- 显示已用时间和状态
第二阶段:合成反馈循环(Synthetic Feedback)
不需要等待生产数据,可以在本地快速测试迭代。
核心思路: 设计自动化的验证机制,让 AI 能够自我判断输出质量。
python
# 简单测试示例
def test_pomodoro():
result = subprocess.run(["python", "pomodoro.py", "start"], capture_output=True)
assert result.returncode == 0
Claude Code 的 Simplify 技能会启动三个子代理并行分析最近改动,找出代码改进点。
第三阶段:自改进循环
输出质量随着运行次数自动提升:
第1次运行 → 完成基本功能
第2次运行 → 补充测试用例
第3次运行 → 发现遗漏,更新状态
第N次运行 → 持续优化
定期让 AI 更新技能文件(skill),记录本次运行中应该做得更好的地方
Pomodoro Timer 项目
项目结构
pomodoro-workshop/
├── pomodoro.py # 主程序
├── test_pomodoro.py # 测试
└── tickets/
├── 0.0.1.md # ticket 文件
├── 0.0.2.md
└── ...
运行 Ralph Loop 的命令
bash
# 使用 Claude Code
claude "implement doc tickets/0.0.1"
# 使用 Claude -P 模式(无交互)
claude -p --dangerously_skip_permissions <<< "implement doc tickets/0.0.1"
# 创建自动循环脚本
while true; do
claude -p <<< "implement the next most important ticket"
if [ $? -ne 0 ]; then
break
fi
done
Claude Code 的内置循环功能
使用 /loop 命令设置定时重复:
/loop every 1 hour "check linear for new bug reports"
这会创建一个 cron 任务,每小时检查一次 Linear 上的新 bug。
权限与沙箱安全
"致命三要素"(Lethal Trifecta)
如果同时满足以下三个条件,数据泄露几乎必然发生:
- 非可信 token(Untrusted tokens)
- 互联网访问(Internet access)
- 访问敏感数据(Access to secrets/important data)
安全实践
| 方法 | 说明 |
|---|---|
| VPS 隔离 | 在独立服务器上运行,避免接触主机器 |
| 专用 API Key | 给 AI 独立的 key,便于审计追踪 |
| Docker Sandbox | 使用 docker sandbox claude 限制文件系统访问 |
| 细粒度权限 | 配置 Claude permissions,只允许操作必要范围 |
| Lobox 项目 | 自动拦截读取到非可信 token 后的文件系统访问 |
bash
# Docker 沙箱运行 Claude
docker sandbox claude run
核心原则: if reversible without embarrassment → allow
Skill 管理
Skills 是打包好的上下文和脚本集合,可以复用到不同场景:
bash
# 查看已安装的 skills
ls ~/.claude/skills/
# 自定义 skill 示例:slide skill
# 用于自动生成 PPT 演示文稿
Chris 的 Skills 清单
- Startup Skill - 运行整个创业框架的循环
- Worker Loop - 每15分钟检查日历、发送 Telegram 消息
- Morning Loop - 早上6点生成工作简报
- Simulate Audience - 多 persona 并行审阅内容
- Image Skill - 生成图片并验证质量
- Simplify - 代码重构与去重
版本控制问题
目前 Skills 版本控制存在摩擦:
- 单个 skill 需要单独 GitHub 仓库 → 太重
- 分享需要 zip/文件传输 → 不方便
- 多人协作时贡献者改动难以管理
maybe airSkills 项目来解决这个问题。
团队协作
扩展 Ralph Loops 到团队
- 让 AI 主动更新 tickets - 与 Linear/Jira 集成,claim ticket、移动到 Doing column
- 减少团队规模 - 协调开销是主要瓶颈,可能需要更小的团队
- 处理依赖关系 - 让 AI 自己判断依赖,而不是预先规划
- 定期回顾 - 持续改进循环定义
理论约束(Theory of Constraints)
任何系统总有且只有一个瓶颈。先解决最大的瓶颈。
- 如果团队用了 AI 后反而变慢 → 瓶颈不在编码速度,在其他流程
- 可能是发布流程(每月发布200个PR)、代码审查流程等
- 阅读推荐:《The Goal》by Eliyahu Goldratt
反馈机制设计
好的反馈机制
markdown
# Ralph Loop Skill 示例结构
## Role Definition
你是一个工程师,一次只做一个变更...
## Context
- 项目结构
- 测试运行方式
- 提交流程
## Behavior Rules
- 每次运行前检查 git status
- 工作目录 dirty 且 tests pass → 可能已完成
- tests fail → 可能是中途失败,考虑丢弃
## Verification
1. 检查测试是否通过
2. 验证实际行为
3. 运行 linting
4. 检查是否有遗漏的功能点
子代理验证
使用子代理进行"对抗性审查"(adversarial review):
- 子代理从新的小上下文开始,避免确认偏差
- 比同上下文的自检更有效
知识管理
Chris 的双目录系统
| 目录 | 用途 |
|---|---|
~/code/ |
代码项目 |
~/vault/ |
所有其他知识(数千个文件) |
Zettelkasten 方法
- 每个想法一个笔记 → 扁平文件夹
- 使用
slash projects汇总相关内容 - 使用 litellm 做 embeddings,构建可搜索的知识库
工具推荐
- Obsidian - 本地笔记
- Lianne - 命令行 embeddings 工具
- Andy Matuschak 的 LLM wiki 方法
问答
Q: 如何决定循环何时停止?
在 loop skill 中明确定义退出条件:
- 运行超出上下文限制
- 遇到不可逆操作
- 达到预定目标
报告机制:更新项目文件,准备好供人类审核。
Q: AI 会替代人类工作吗?
- AI 适合:可逆的、执行性的工作
- 人类应该保留:战略性思考、决策、安全敏感操作
让 AI 完成所有可逆的准备工作,人类专注于自己真正擅长和享受的工作。
Q: 循环中的 token 消耗是否值得优化?
A: 不要优化 token,优化自己的时间:
- Claude Max 订阅每月 $200 并不贵
- AI 能力会持续提升,成本会下降
"Everything is a loop. As an engineer, I'm definitely on a loop. As a designer, I'm definitely on a loop. Everything can be loopified."