mcpField
R
ralph

ralph

github.com/snarktank开发47 次安装
代码仓库

关于 ralph

ralph 是一项技能,可将功能规划为规模较小、带依赖关系的任务,并为 Ralph 执行循环做好准备。它支持规划新功能或设置现有任务,适用于使用 task_list 和 scripts/ralph 文件的团队。

主要功能

  1. 01通过澄清问题规划功能
  2. 02创建父任务和子任务
  3. 03按依赖关系排列任务
  4. 04准备 Ralph 进度文件
  5. 05检查任务状态和就绪情况

适用场景

  1. 01将功能拆分为单轮可完成的任务
  2. 02为 Ralph 设置现有任务
  3. 03查看就绪或受阻的任务

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/snarktank/amp-skills --skill ralph

安装后在 Claude Code 中输入/ralph确认已加载。

详细介绍

Ralph 功能设置

通过交互式功能规划创建可供 Ralph 使用且带有依赖关系的任务。


任务

两种模式:

模式 1:新功能
  1. 讨论功能:提出澄清问题
  2. 拆分为小任务:每个任务都能在一次迭代中完成
  3. 创建 task_list 任务:父任务 + 带有 dependsOn 的子任务
  4. 设置 Ralph 文件:保存父任务 ID,重置 progress.txt
模式 2:现有任务
  1. 查找现有父任务:搜索或让用户指定
  2. 验证结构:检查子任务是否设置了正确的 dependsOn
  3. 设置 Ralph 文件:将父任务 ID 保存到 parent-task-id.txt
  4. 显示状态:哪些任务已就绪、已完成或受阻

询问用户需要哪种模式:

Are you:
1. Starting a new feature (I'll help you plan and create tasks)
2. Using existing tasks (I'll set up Ralph to run them)

第 1 步:了解功能

首先询问用户有关功能的信息。不要想当然——要询问:

What feature are you building?

然后提出澄清问题:

  • 面向用户的目标是什么?
  • 这会涉及代码库的哪些部分?(数据库、UI、API 等)
  • 是否有任何现有模式可供参考?
  • 完成后应该是什么样子?

持续提问,直到掌握足够的信息来拆分任务。


第 2 步:拆分任务

每个任务都必须能在一次 Ralph 迭代(约一个上下文窗口)中完成。

Ralph 每次迭代都会启动一个全新的 Amp 实例,不会记得之前的工作。如果任务太大,大模型会在完成之前耗尽上下文。

合适大小的任务:
  • 添加数据库列和迁移
  • 创建单个 UI 组件
  • 实现一个服务端操作
  • 为现有列表添加筛选器
  • 为一个模块编写测试
太大的任务(请拆分):
  • “构建整个仪表板” → 拆分为:架构、查询、组件、筛选器
  • “添加身份验证” → 拆分为:架构、中间件、登录 UI、会话处理
  • “重构 API” → 每个端点拆分为一个任务

经验法则: 如果无法用 2-3 句话描述变更,那任务就太大了。


第 3 步:按依赖关系排序

任务根据 dependsOn 执行。依赖任务必须等前置任务完成后才能开始。

典型顺序:

  1. 架构/数据库变更(迁移)
  2. 服务端操作 / 后端逻辑
  3. 使用后端的 UI 组件
  4. 集成 / E2E 测试

使用 dependsOn 表示依赖关系:

Task 1: Schema (no dependencies)
Task 2: Server action (dependsOn: [task-1])
Task 3: UI component (dependsOn: [task-2])
Task 4: Tests (dependsOn: [task-3])

互不依赖的并行任务可以使用相同的依赖项。


第 4 步:创建任务

首先,创建父任务:
task_list create
  title: "[Feature Name]"
  description: "[One-line description of the feature]"
  repoURL: "https://github.com/snarktank/untangle"

保存返回的任务 ID——创建子任务时需要用到。

然后,创建带有 parentID 和 dependsOn 的子任务:
task_list create
  title: "[Task title - action-oriented]"
  description: "[Detailed description with:
    - What to implement
    - Files to create/modify
    - Acceptance criteria
    - How to verify (typecheck, tests, browser)]"
  parentID: "<parent-task-id>"
  dependsOn: ["<previous-task-id>"]  // omit for first task
  repoURL: "https://github.com/snarktank/untangle"
任务描述格式:

编写任务描述时,应确保未来的 Ralph 迭代无需上下文也能继续处理:

Implement category name to ID mapping for expenses.

**What to do:**
- Create function mapExpenseCategoryNameToId(name, isChildExpense)
- Query item_category table with category_type filter
- Add alias mapping for common synonyms (rent → Rent or Mortgage)

**Files:**
- workflows/tools/upsert-expense.ts

**Acceptance criteria:**
- Function returns category ID for valid names
- Returns null for unknown categories
- npm run typecheck passes

**Notes:**
- Follow pattern from upsert-income.ts
- EXPENSE type for family, CHILD_EXPENSE for child

第 5 步:设置 Ralph 文件

创建所有任务后,运行“最终设置(两种模式均需执行)”部分中的共享设置步骤。

这可确保:

  • 父任务 ID 已保存到 scripts/ralph/parent-task-id.txt
  • 如果之前的 progress.txt 有内容,则将其归档
  • 创建新的 progress.txt,并保留 Codebase Patterns

第 6 步:确认设置

向用户展示创建的内容:

✅ Ralph is ready!

**Parent task:** [title] (ID: [id])

**Subtasks:**
1. [Task 1 title] - no dependencies
2. [Task 2 title] - depends on #1
3. [Task 3 title] - depends on #2
...

**To start Ralph:** Say "run ralph" or "start the loop" - I'll use handoff to execute the first ready task, and each task will hand off to the next until complete.

---

## Mode 2: Setting Up Existing Tasks

If the user already has tasks created, help them set up Ralph to run them.

### Find the parent task:

**First, check if a parent task is already saved:**

```bash
cat scripts/ralph/parent-task-id.txt

如果此文件存在且包含任务 ID,就使用它!通过获取任务来验证其有效性:

task_list action: "get", taskID: "<id-from-file>"

仅当没有已保存的父任务时,才询问用户:

What's the parent task? You can give me:
- The task ID directly
- A search term and I'll find it
- Or say "list recent" to see recent tasks

搜索任务时(始终使用 limit 以避免上下文溢出):

task_list list
  repoURL: "https://github.com/snarktank/untangle"
  limit: 10
验证子任务是否存在:

获取父任务 ID 后,检查是否有子任务(始终使用 limit):

task_list list
  parentID: "<parent-task-id>"
  limit: 10

如果没有找到子任务,父任务本身可能就是要执行的工作(而非容器任务)。请询问:

This task has no subtasks. Is this:
1. A parent task with subtasks I should find differently?
2. The actual work task (I should create it as a parent with this as the first subtask)?
检查依赖关系:

查看子任务并验证:

  • 是否正确设置了 dependsOn?
  • 是否存在循环依赖?
  • 第一个任务(或多个任务)是否没有依赖项,以便 Ralph 可以开始?

如果缺少依赖关系,请提出修复:

These tasks don't have dependencies set. Should I:
1. Add dependencies based on their order?
2. Leave them parallel (Ralph picks any ready task)?
设置 Ralph 文件:

运行下方“最终设置(两种模式均需执行)”部分中的共享设置步骤。

显示状态:
✅ Ralph is ready to use existing tasks!

**Parent task:** [title] (ID: [id])

**Status:**
- ✅ Completed: 3 tasks
- 🔄 Ready to work: 2 tasks  
- ⏳ Blocked: 5 tasks (waiting on dependencies)

**Next task Ralph will pick:**
[Task title] - [brief description]

**To start Ralph:** Say "run ralph" or "start the loop"

---

## Final Setup (Required for Both Modes)

**ALWAYS run these steps after creating tasks OR setting up existing tasks:**

### 1. Save parent task ID:

```bash
echo "<parent-task-id>" > scripts/ralph/parent-task-id.txt

验证是否已保存:

cat scripts/ralph/parent-task-id.txt
2. 检查是否需要归档 progress.txt:

读取当前的 progress.txt:

cat scripts/ralph/progress.txt

符合以下条件时进行归档:

  • 文件内容超出标题(包含上一个功能的经验总结)
  • 上一个功能与当前功能不同

归档命令:

DATE=$(date +%Y-%m-%d)
FEATURE="previous-feature-name-here"
mkdir -p scripts/ralph/archive/$DATE-$FEATURE
cp scripts/ralph/progress.txt scripts/ralph/archive/$DATE-$FEATURE/
echo "Archived to scripts/ralph/archive/$DATE-$FEATURE/"
3. 重置 progress.txt:

保留上次运行中有用的代码库模式,然后重置:

cat > scripts/ralph/progress.txt << 'EOF'
# Ralph Progress Log
Started: [current date]

## Codebase Patterns
[Copy any patterns from previous run that are still relevant]
---
EOF
4. 确认设置已完成:
# Confirm parent ID is saved
cat scripts/ralph/parent-task-id.txt

# Confirm progress.txt is reset
head -10 scripts/ralph/progress.txt

# List subtasks to confirm they exist
# (use task_list list with parentID)

仅在完成全部 4 个步骤后,Ralph 才能开始运行。


各任务的验收标准

每项任务描述都必须包含可验证的验收标准:

好的标准(可验证):
  • “为 investor 表添加 investorType 列,默认值为 'cold'”
  • “筛选下拉菜单包含以下选项:All、Cold、Friend”
  • “npm run typecheck 通过”
  • “npm test -- path/to/test.ts 通过”
不好的标准(含糊不清):
  • ❌ “运行正常”
  • ❌ “用户体验良好”
  • ❌ “能处理边界情况”
始终包含:
npm run typecheck passes
对于包含可测试逻辑的任务:
npm test passes
对于 UI/浏览器任务:

功能测试(检查行为,而非外观):

Use Chrome DevTools MCP with take_snapshot to read page content (NOT screenshots)
  • take_snapshot 会以文本形式返回 a11y 树,Ralph 可以读取并验证
  • take_screenshot 会返回图像,Ralph 无法据此进行功能检查
  • 仅在测试视觉外观和体验时使用截图

视觉测试(检查外观):

Use take_screenshot to capture and verify visual appearance

对话示例

用户: 为法律 Agent 设置 Ralph,以添加费用跟踪功能

助手: 你正在构建什么功能?

用户: 我希望 Grace(我们的法律聊天 Agent)能够在用户提到费用时创建、更新和删除这些费用。

助手: 明白了——这是一个供法律 Agent 使用的费用新增或更新工具。我有几个问题:

  1. 法律 Agent 中是否有我可以参考的现有工具?
  2. 费用是否分为不同类型(家庭和子女)?
  3. 是否还需要列出费用,还是只要 CRUD?
  4. 是否需要任何任务完成逻辑?

用户: 参考 upsert-income.ts。是的,家庭和子女费用(使用不同的表)。是的,也要列出费用。将 APP_EXPENSES_ENTERED 任务标记为已完成。

助手: 很好。以下是我建议的任务拆分:

  1. 创建工具骨架 - Zod 模式、基本结构
  2. 类别映射 - 将“rent”等名称映射到类别 ID
  3. 金额解析 - 处理不同货币格式,允许 $0
  4. 重复项检测 - 创建前进行检查
  5. 创建家庭费用 - 插入 expense 表
  6. 创建子女费用 - 插入 child_expense 表
  7. 更新操作 - 修改现有费用
  8. 删除操作 - 删除费用
  9. 列表操作 - 显示所有费用及总额
  10. 任务完成 - 将 APP_EXPENSES_ENTERED 标记为已完成
  11. 注册工具 - 添加到法律聊天工作流
  12. UI 进度指示器 - 显示工具使用过程中的进度
  13. 单元测试 - 测试辅助函数
  14. 端到端测试 - 通过聊天界面测试

这样安排合适吗?有没有要添加或删除的任务?

用户: 看起来不错,创建这些任务吧

助手: [创建父任务,然后创建带依赖关系的子任务,并保存 parent-task-id.txt]

✅ Ralph 已准备就绪!

父任务: 法律 Agent 费用新增或更新工具(ID:task-abc123)

子任务: 已创建 14 项任务并设置依赖关系

开始运行: 说“run ralph”或“start the loop”


Ralph 如何完成工作

当所有子任务都完成后:

  1. Ralph 将父任务标记为 completed
  2. 报告“✅ 构建完成——所有任务已完成!”
  3. 总结已完成的工作

重要提示: Ralph 使用 limit: 5 查询任务,以避免上下文溢出。如果有很多子任务,系统会分多次迭代处理。


创建任务前的检查清单

  • 已讨论功能并了解其范围
  • 每项任务都能在一次迭代中完成(规模足够小)
  • 任务按依赖顺序排列(架构 → 后端 → UI → 测试)
  • 每项任务的描述中都包含“npm run typecheck passes”
  • UI 任务的描述中包含浏览器验证
  • 描述足够详细,Ralph 无需上下文即可实现
  • 父任务 ID 已保存到 scripts/ralph/parent-task-id.txt
  • 如果 progress.txt 中有内容,已归档上一次运行

阶段 2:执行循环

完成设置后,Ralph 会运行自主循环,逐项实现任务。


循环工作流

0. 获取父任务 ID

首先,读取用于限定此功能范围的父任务 ID:

cat scripts/ralph/parent-task-id.txt

如果此文件不存在,请询问用户要处理哪个父任务。

检查这是否是新功能: 将父任务 ID 与 scripts/ralph/progress.txt 标题中的 ID 进行比较。如果二者不同(或 progress.txt 不存在),则这是一个新功能——重置 progress.txt:

# Build Progress Log
Started: [today's date]
Feature: [parent task title]

## Codebase Patterns
(Patterns discovered during this feature build)

---

这样可以确保每个功能都从干净的状态开始。Progress.txt 仅作为当前功能的短期记忆。

1. 检查就绪任务(支持嵌套层级)

任务层级可能有多级(父任务 → 容器任务 → 叶子任务)。使用以下方法查找所有后代任务:

步骤 1:获取仓库的所有任务

task_list action: "list", repoURL: "<repo-url>", ready: true, status: "open", limit: 10

重要: 始终使用 limit(5-10),以避免任务过多导致上下文溢出。

步骤 2:构建后代任务集合 从父任务 ID 开始,收集所有后代任务:

  1. 查找 parentID 等于父任务 ID 的任务(直接子任务)
  2. 对找到的每个子任务,递归查找其子任务
  3. 持续查找,直到没有更多后代任务

步骤 3:筛选可执行任务 从后代任务集合中,选出满足以下条件的任务:

  • ready: true(所有依赖均已满足)
  • status: "open"
  • 叶子任务(没有自己的子任务)——这些才是真正的工作项

关键: 跳过仅用于归纳其他任务的容器任务。若其他任务的 parentID 为某任务 ID,则该任务是容器任务。

2. 如果没有就绪任务

检查所有后代任务是否已完成:

  • 使用 repoURL: "<repo-url>" 执行 task_list list 查询(不添加就绪状态筛选)
  • 构建完整的后代任务集合(采用步骤 1 中相同的递归方法)
  • 如果后代任务集合中的所有叶子任务都处于 completed 状态:
    1. 归档 progress.txt:
      DATE=$(date +%Y-%m-%d)
      FEATURE="feature-name-here"
      mkdir -p scripts/ralph/archive/$DATE-$FEATURE
      mv scripts/ralph/progress.txt scripts/ralph/archive/$DATE-$FEATURE/
      
    2. 使用空模板创建新的 progress.txt
    3. 清空 parent-task-id.txt:echo "" > scripts/ralph/parent-task-id.txt
    4. 提交:git add scripts/ralph && git commit -m "chore: archive progress for [feature-name]"
    5. 将父任务标记为 completed
    6. 停止并报告“✅ 构建完成——所有任务均已完成!”
  • 如果有些任务受阻:报告哪些任务受阻以及原因
3. 如果存在就绪任务

选择下一项任务:

  • 优先选择与刚完成的任务相关的任务(同一模块/领域、依赖工作)
  • 如果没有先前上下文,则选择第一项就绪任务

执行任务:

使用 handoff 工具并采用以下目标:

Implement and verify task [task-id]: [task-title].

[task-description]

FIRST: Read scripts/ralph/progress.txt - check the "Codebase Patterns" section for important context from previous iterations.

When complete:

1. Run quality checks: `npm run typecheck` and `npm test`
   - If either fails, FIX THE ISSUES and re-run until both pass
   - Do NOT proceed until quality checks pass

2. Update AGENTS.md files if you learned something important:
   - Check for AGENTS.md in directories where you edited files
   - Add learnings that future developers/agents should know (patterns, gotchas, dependencies)
   - This is LONG-TERM memory - things anyone editing this code should know
   - Do NOT add task-specific details or temporary notes

3. Update progress.txt (APPEND, never replace) - this is SHORT-TERM memory for the current feature:

[Date] - [Task Title]

Thread: [current thread URL] Task ID: [task-id]

  • 实现内容
  • 更改的文件
  • 供后续迭代参考的经验:
    • 发现的模式
    • 遇到的注意事项
    • 有用的上下文


4. If you discovered a reusable pattern for THIS FEATURE, add it to the `## Codebase Patterns` section at the TOP of progress.txt

5. Commit all changes with message: `feat: [Task Title]`

6. Mark task as completed: `task_list action: "update", taskID: "[task-id]", status: "completed"`

7. Invoke the ralph skill to continue the loop

进度文件格式

# Build Progress Log
Started: [date]
Feature: [feature name]
Parent Task: [parent-task-id]

## Codebase Patterns
(Patterns discovered during this feature build)

---

## [Date] - [Task Title]
Thread: https://ampcode.com/threads/[thread-id]
Task ID: [id]
- What was implemented
- Files changed
- **Learnings for future iterations:**
  - Patterns discovered
  - Gotchas encountered
---

注意: 当新功能使用不同的父任务 ID 时,请彻底重置 progress.txt。长期经验应记录在 AGENTS.md 文件中,而不是 progress.txt。


任务发现

在工作过程中,发现问题时要积极创建新任务,包括:

  • 测试失败或测试覆盖不足
  • 需要重构的代码
  • 缺少错误处理
  • 文档缺失
  • 代码中的 TODO 或 FIXME
  • 构建或 lint 警告
  • 性能问题

立即使用 task_list action: "create"。设置适当的 dependsOn 关系。


浏览器验证

对于 UI 任务,指定合适的验证方法:

功能测试(检查行为,而非外观):

Use agent-browser with snapshot -i to read page content
  • agent-browser snapshot -i 会返回可验证的交互元素及其 refs
  • 适用于:按钮是否存在、文本是否显示、表单是否可用
  • 示例:使用 agent-browser snapshot -i | grep "Submit" 验证按钮是否存在

视觉测试(检查外观):

Use agent-browser screenshot to capture and verify visual appearance
  • agent-browser screenshot tmp/result.png 会保存截图
  • 适用于:布局、颜色、样式、动画

质量要求

在将任何任务标记为完成之前:

  • npm run typecheck 必须通过
  • npm test 必须通过
  • 更改必须提交
  • 必须记录进度

停止条件

当没有待执行任务且所有任务均已完成时:

  1. 输出:“✅ 构建完成——所有任务均已完成!”
  2. 总结已完成的工作

重要说明

  • 列出任务时始终使用 ready: true,只获取依赖条件已满足的任务
  • 列出任务时始终使用 limit: 5-10,避免上下文溢出
  • 每次交接都会在全新线程中运行,并提供干净的上下文
  • Progress.txt 是不同迭代之间的记忆——请保持更新
  • 优先选择与刚完成工作属于同一领域的任务,以便更好地延续上下文
  • 交接目标必须包含更新 progress.txt、提交更改并重新调用此技能的说明

评论

支持 Markdown