ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Ralph Loops 实战:用 while 循环 + Skill 重构 Claude Code 的 AI 工作流

Ralph Loops 实战:用 while 循环 + Skill 重构 Claude Code 的 AI 工作流 1. 为什么我开始用 while 循环替代复杂 AI 工作流Ralph Loops 这个词最近在 Claude Code 圈子里被反复提起核心思路其实很朴素与其花几天时间搭一套多分支、多节点的复杂编排不如让 AI 在同一个提示上反复跑靠重复和自我修正把活干完。我第一次看到这个概念时是怀疑的——重复执行同一个 promptAI 不会原地打转吗实测下来只要 Skill 里写清了验收标准和退出条件第二次、第三次运行确实能补上第一次漏掉的边界情况。Ralph Loops 适合谁适合已经在用 Claude Code 写代码、但被复杂工作流折磨过的开发者。你可能试过用可视化编排工具拉一堆并行分支结果调试时间比手写代码还长。Ralph Loops 的思路是反过来的把复杂度压到一个 while 循环加一个 Skill 文件里让 AI 自己决定下一步做什么、什么时候算完成。这篇文章我会给出可复制的 Skill 配置骨架、循环脚本以及一次完整的验证动作。你跟着做能在本地跑通一个最小可用的循环式工作流。前置条件只有一个你需要一个能调用 Claude 系列模型的 API Key我用的是 TaoToken 的接入方式后面会讲怎么配。2. TaoToken 前置准备拿到能跑循环的 API KeyClaude Code 本身就是一个循环体——读取 Skill、调用工具、决定下一步、回到起点。要让这个循环跑起来你得先有一个稳定的模型调用入口。我选 TaoToken 的原因很简单它的 API 格式和 Anthropic 官方兼容Claude Code 的配置几乎不用改而且模型对话、Coding Plan、API Keys 管理都在一个控制台里。2.1 注册与获取 API Key打开官网 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 注册后进入控制台。在 API Keys 页面创建一个新 Key建议给这个 Key 起个能识别的名字比如ralph-loop-dev方便后面审计调用来源。创建完成后复制 Key它只会显示一次。如果你打算长期跑循环建议单独建一个 Key 专用于循环任务这样在控制台看用量时能一眼区分是人工调试还是自动循环消耗的。2.2 配置 Claude Code 指向 TaoTokenClaude Code 通过环境变量读取 API 地址和 Key。在终端里设置export ANTHROPIC_BASE_URLhttps://taotoken.net/api export ANTHROPIC_API_KEYsk-你的Key如果你用的是 Claude Code 的配置文件方式可以写进~/.claude/settings.json{ env: { ANTHROPIC_BASE_URL: https://taotoken.net/api, ANTHROPIC_API_KEY: sk-你的Key } }注意API 地址不要加 UTM 参数只保留https://taotoken.net/api即可否则部分客户端会拼接出错误的请求路径。配置完成后先用一次简单对话验证连通性再进入循环脚本的编写。模型对话入口在 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 你可以在那里确认当前可用的模型列表。3. 可复制的 Skill 配置骨架与循环脚本这一节是全文的核心。我会先给出 Skill 文件的目录结构和内容骨架再给出 while 循环脚本最后说明退出条件怎么写。3.1 Skill 目录结构Claude Code 默认从~/.claude/skills/读取 Skill。每个 Skill 是一个独立文件夹里面至少有一个SKILL.md。我建议的目录结构~/.claude/skills/ └── ralph-loop/ ├── SKILL.md └── scripts/ └── verify.shSKILL.md定义角色、上下文、行为规则和验收标准scripts/verify.sh放你的自动化验证命令比如跑测试、跑 lint。3.2 SKILL.md 骨架下面这个骨架可以直接复制改掉项目相关的部分即可## Role Definition 你是一个工程师每次运行只做一个最小变更。不要一次性重写整个文件。 ## Context - 项目根目录/path/to/your/project - 测试命令pytest -q - 代码检查ruff check . - 当前任务来源tickets/ 目录下的 markdown 文件 ## Behavior Rules - 每次运行前先执行 git status确认工作区状态 - 如果工作区 dirty 且测试通过说明上一次可能已完成检查是否还有未实现的 ticket - 如果测试失败判断是中途失败还是引入了回归必要时回滚 - 只处理 tickets/ 目录中编号最小的未完成 ticket - 完成后更新 ticket 文件在末尾追加 ## Status: done ## Verification 1. 运行 pytest -q确认全部通过 2. 运行 ruff check .确认无新增告警 3. 对照 ticket 的验收标准逐条检查 4. 如果验收标准中有未覆盖项在 ticket 中标注并继续 ## Exit Conditions - 所有 ticket 均已标记 done - 遇到需要人工决策的不可逆操作 - 连续两次运行没有产生任何文件变更这个骨架的关键在于 Exit Conditions。没有退出条件的循环会一直烧 token所以必须写清楚什么情况下停下来。3.3 while 循环脚本最基础的循环脚本长这样#!/bin/bash # ralph-loop.sh MAX_ITER20 ITER0 while [ $ITER -lt $MAX_ITER ]; do ITER$((ITER 1)) echo Iteration $ITER claude -p 读取 ralph-loop skill处理 tickets/ 中编号最小的未完成 ticket \ --dangerously-skip-permissions if [ $? -ne 0 ]; then echo Claude 调用失败退出循环 break fi # 检查是否还有未完成的 ticket REMAINING$(grep -L Status: done tickets/*.md | wc -l) if [ $REMAINING -eq 0 ]; then echo 所有 ticket 已完成退出循环 break fi sleep 2 done echo 循环结束共执行 $ITER 次几个要点MAX_ITER是硬性上限防止脚本失控grep -L找出还没标记 done 的 ticketsleep 2给文件系统一点缓冲时间。--dangerously-skip-permissions会跳过权限确认只在隔离环境里用后面安全部分会讲。3.4 ticket 文件格式ticket 是循环的输入格式要统一AI 才能稳定解析# Ticket 0.0.1: 实现状态查询功能 ## 需求 能够查询当前任务的运行状态和剩余时间。 ## 验收标准 - task status 命令可用 - 输出包含已用时间和当前状态 - 状态为 running/paused/stopped 三种之一 ## Status: pending每轮循环结束后AI 会把pending改成done脚本据此判断是否继续。4. 验证请求跑一次完整循环并检查结果配置写完了现在跑一次真实循环确认整条链路通。4.1 准备测试项目建一个最小项目来验证mkdir -p ~/ralph-demo/tickets cd ~/ralph-demo git init echo print(hello) main.py创建两个 ticketcat tickets/0.0.1.md EOF # Ticket 0.0.1: 添加 add 函数 ## 需求 在 main.py 中添加一个 add(a, b) 函数。 ## 验收标准 - add(1, 2) 返回 3 - 有对应的测试 ## Status: pending EOF cat tickets/0.0.2.md EOF # Ticket 0.0.2: 添加命令行入口 ## 需求 让 main.py 支持 python main.py add 1 2 输出结果。 ## 验收标准 - 命令行调用返回正确结果 - 无参数时打印用法说明 ## Status: pending EOF4.2 运行循环把前面的ralph-loop.sh放到项目根目录赋予执行权限后运行chmod x ralph-loop.sh ./ralph-loop.sh第一轮循环Claude 会读取0.0.1.md在main.py里加函数和测试然后把 ticket 标记为 done。第二轮处理0.0.2.md加命令行入口。第三轮检查时发现没有 pending ticket退出。4.3 检查结果循环结束后检查文件状态cat tickets/0.0.1.md | tail -3 cat tickets/0.0.2.md | tail -3 python main.py add 1 2预期输出两个 ticket 都显示Status: done命令行返回3。如果某个 ticket 还是 pending说明那一轮 AI 没完成验收标准可以手动看下 ticket 里有没有标注未覆盖项。提示第一次跑建议把MAX_ITER设小一点比如 5观察每轮的实际行为后再放开。5. 本篇常见错排查循环跑不起来多半是下面几个原因。我按出现频率排了序。5.1 Claude 调用返回 401 或 403先确认环境变量有没有生效echo $ANTHROPIC_BASE_URL echo $ANTHROPIC_API_KEY | head -c 10如果ANTHROPIC_BASE_URL是空的说明当前 shell 没加载配置。写进~/.bashrc或~/.zshrc后重新开终端。如果 Key 显示正常但还是 401去控制台的 API Keys 页面确认这个 Key 没有被禁用或删除。5.2 循环空转每轮都没有文件变更这是最典型的问题通常是 Skill 里的 Exit Conditions 没写清楚AI 不知道什么时候算完成。检查两点ticket 的验收标准是否可量化比如“有对应的测试”比“代码质量好”更容易判断Skill 里有没有“连续两次无变更则退出”这类规则。如果 ticket 本身写得模糊AI 会反复尝试但不敢标记 done。把验收标准改成可执行的具体命令比如“pytest -q全部通过”。5.3 ticket 被标记 done 但测试没通过说明 AI 跳过了 Verification 步骤。在 SKILL.md 的 Behavior Rules 里加一条硬性要求- 标记 ticket 为 done 之前必须实际运行 pytest -q 并确认返回码为 0 - 如果测试失败不得标记 done应在 ticket 中记录失败原因同时把verify.sh挂到 Skill 的 Verification 环节让验证变成脚本调用而不是靠 AI 自觉。5.4 循环消耗 token 过快先看是不是 MAX_ITER 设太大或者每轮处理的 ticket 粒度太粗。一个 ticket 对应一个最小变更不要在一个 ticket 里塞三个功能。另外claude -p每次都会重新加载上下文如果项目很大考虑在 Skill 里限定只读取相关文件而不是整个仓库。如果用量确实上来了去控制台看下调用记录确认没有异常的重试。Coding Plan 页面 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 有适合长期循环任务的套餐说明可以对比一下按量调用和套餐的成本差异。5.5 权限报错导致循环中断--dangerously-skip-permissions在部分环境下会被拦截。如果你在容器或沙箱里跑确认沙箱允许文件写入。如果不想跳过权限可以在 Skill 里预先声明允许的操作范围让 Claude Code 只对特定目录放行。安全上有个原则值得记住可逆的操作放手让 AI 做不可逆的操作删库、推送到主分支、调用外部付费接口必须人工确认。循环脚本里可以加一道检查遇到git push或rm -rf这类命令时暂停。6. 把循环接进你的日常开发流跑通最小循环之后下一步是把它接到真实项目里。我的做法是保留tickets/目录作为任务队列每天早上花十分钟把当天要做的事拆成 ticket然后让循环在后台跑。人只需要在循环结束后 review 变更而不是全程盯着。如果你想让循环更稳定有两个实践值得试。一是给每个 ticket 加一个## Depends字段让 AI 自己判断依赖顺序而不是你预先排好二是定期让 AI 更新 SKILL.md把这次运行中踩到的坑写进 Behavior Rules下一轮循环就会自动避开。API Keys 和接入文档在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 和 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 配置细节都在里面。Claude Code 的接入方式在 https://taotoken.net/ClaudeCodeAnthropic?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 有专门说明照着改环境变量就行。最后说一个我踩过的坑循环脚本里的grep -L在 ticket 文件名带空格时会出错如果你的 ticket 命名不规范先把文件名统一成0.0.1.md这种格式或者改用find加xargs处理。这个细节不影响主流程但会让退出判断失准值得在第一次跑之前就处理好。
返回列表