news 2026/9/9 21:03:45

goose Ralph Loop 实战指南:以“全新上下文 + 双模型交叉评审”把 Agent 迭代任务自动推进到可交付

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
goose Ralph Loop 实战指南:以“全新上下文 + 双模型交叉评审”把 Agent 迭代任务自动推进到可交付

goose Ralph Loop 实战指南:以“全新上下文 + 双模型交叉评审”把 Agent 迭代任务自动推进到可交付

【免费下载链接】goosean open source, extensible AI agent that goes beyond code suggestions - install, execute, edit, and test with any LLM项目地址: https://gitcode.com/GitHub_Trending/goose3/goose

Ralph Loop 是 goose 生态中一种面向复杂开发任务的迭代式执行模式:它让 goose 在每一轮迭代都从零开始新建会话,只通过文件在轮次之间传递任务、总结与评审反馈,从而彻底规避标准 Agent 循环中“历史噪声累积”导致的质量衰减问题。本文以 Ralph Loop 官方教程 为骨架,结合仓库中真实可用的 ralph-loop.sh、ralph-work.yaml 与 ralph-review.yaml 三个文件,讲解它的设计动机、搭建步骤、状态文件协议与 recipe 文件逐段语义,读完即可在你的终端里跑通“干活模型 + 评审模型”协同完成任务的完整闭环。

为什么要引入 Ralph Loop:标准 Agent 循环的上下文累积问题

单次 goose 会话里,Agent 会反复执行“思考 → 调用工具 → 得到结果”的循环。如果任务一次没有做完,常见的做法是让它在同一个会话里继续改,但这会带来一个隐蔽而严重的问题:每一次失败的尝试都会留在对话历史里

  • 模型每次发起请求都必须重新处理整段历史,token 消耗随迭代次数线性甚至超线性增长;
  • 会话越长,早期有用信息越容易被后期的大量噪音淹没,模型的注意力被稀释;
  • 多次失败的历史还会“传染”后续决策——模型倾向于沿用旧思路反复修补,而不是重新审视问题。

Ralph Loop 化解这个问题的核心思想只有一个:每一轮迭代都从全新上下文开始。这一思路源自 Geoffrey Huntley 提出的 Ralph Wiggum 技术,而本项目教程在此基础上进一步扩展出了“跨模型评审”(cross-model review)机制——一个模型负责干活,另一个模型负责把关,循环往复直到任务达到可交付(SHIP)标准。

核心机制一览:文件传状态,会话不延续

Ralph Loop 的两个阶段分工如下:

Iteration 1: WORK PHASE → Model A does work, writes to files REVIEW PHASE → Model B reviews the work → SHIP? Exit successfully ✓ → REVISE? Write feedback, continue to iteration 2 Iteration 2: WORK PHASE → Model A reads feedback, fixes things (fresh context!) REVIEW PHASE → Model B reviews again → SHIP? Exit successfully ✓ → REVISE? Continue... ... repeats until SHIP or max iterations

关键点在于:迭代结束后,只有工作总结与评审反馈落在磁盘文件上,会话历史不会保留。下一轮开始后,新会话里的模型只需读取.goose/ralph/目录下的状态文件,就能精确地从上一轮结束的位置继续。工作产物(代码、配置等)天然留在工作目录里,跨轮次共享;而“意图类”信息(做了什么、还缺什么)则通过状态文件显式交接,二者互不干扰。

前置准备

动手前需要满足两个条件:

  1. 安装 goose CLI:Ralph Loop 全程在终端里驱动,参考 安装指南 完成 goose 命令行工具安装。
  2. 配置两个模型:分别扮演 worker(干活)与 reviewer(评审)角色。参考 Providers 配置。官方教程建议使用两个不同模型以获得更高质量的评审视角,但同一模型同时承担两角色时循环依然可以工作(脚本只会给出警告)。

获取 Ralph Loop 的 Recipe 文件

Ralph Loop 由三个文件组成,它们在当前仓库中的真实位置如下(教程正文即引用自这些文件):

  • ralph-loop.sh:Bash 编排脚本,驱动 work/review 循环;
  • ralph-work.yaml:Work 阶段 recipe,告诉 worker 模型如何推进任务;
  • ralph-review.yaml:Review 阶段 recipe,告诉 reviewer 模型如何评判与给出反馈。

下载到 goose 的 recipe 默认目录后赋予执行权限:

mkdir -p ~/.config/goose/recipes # 将仓库 documentation/src/pages/recipes/data/recipes/ 下的三个文件复制到该目录 cp documentation/src/pages/recipes/data/recipes/ralph-loop.sh ~/.config/goose/recipes/ cp documentation/src/pages/recipes/data/recipes/ralph-work.yaml ~/.config/goose/recipes/ cp documentation/src/pages/recipes/data/recipes/ralph-review.yaml ~/.config/goose/recipes/ chmod +x ~/.config/goose/recipes/ralph-loop.sh

说明:脚本本身内置了RALPH_RECIPE_DIR环境变量用于覆盖 recipe 目录,其默认值正是$HOME/.config/goose/recipes(见下文脚本源码第 23 行),所以复制到上述位置后无需任何额外参数。你也可以选择不下载,直接从 Recipe Files 章节 复制文件内容。

仓库的 recipe 加载逻辑也与该约定一致:goose 会扫描全局配置目录下的recipes子目录、当前工作目录下的.goose/recipes,以及.agents/recipes等位置(见 local_recipes.rs),并支持通过GOOSE_RECIPE_PATH环境变量追加自定义搜索路径。

三步跑通 Ralph Loop

Step 1:启动循环

打开终端,进入你要 goose 开发的项目目录(注意 Ralph Loop 会把.goose/ralph/状态目录创建在当前工作目录下),把任务描述放在引号里传给脚本:

~/.config/goose/recipes/ralph-loop.sh "Create a simple browser using Electron and React"

教程用它演示的正是这个场景:从零构建一个基于 Electron + React 的简易浏览器,观察迭代循环如何在交付前拦截缺失功能(如非法 URL 缺少错误处理、缺少前进/后退导航按钮)。

针对复杂任务的小技巧:字符串参数并不总是够用。当任务是 PRD、详细规格说明书或任何适合迭代式开发的多步骤需求时,直接传入文件路径:

~/.config/goose/recipes/ralph-loop.sh ./prd.md

脚本会检测到参数是一个存在的文件,将其内容复制为任务描述(cp "$INPUT" "$STATE_DIR/task.md")。

Step 2:交互式配置模型

首次运行且未通过环境变量预设模型时,脚本会引导你逐步填写配置,随后显示成本警告并要求确认:

Worker model [gpt-4o]: Worker provider [openai]: Reviewer model (should be different from worker): claude-sonnet-4-20250514 Reviewer provider: anthropic Max iterations [10]: ⚠️ Cost Warning: This will run up to 10 iterations, each using both models. Estimated token usage could be significant depending on your task. Continue? [y/N]: y

各配置项含义如下:

变量描述
Worker model真正执行编码工作的模型。若已设置GOOSE_MODEL环境变量,则作为默认值出现在方括号中
Worker providerWorker 模型所属的 provider(如openaianthropic),默认取自GOOSE_PROVIDER
Reviewer model负责评审工作的模型。为获得最佳效果应区别于 worker 模型
Reviewer providerReviewer 模型所属的 provider
Max iterations放弃前最多执行多少轮 work/review 循环,默认 10

值得注意的两处内置校验(见 ralph-loop.sh 第 39-103 行的prompt_for_settings函数):

  • 必要项缺失直接退出:worker/reviewer 的模型与 provider 均不允许为空;
  • 同模型降级警告:当 worker 与 reviewer 的(model, provider)完全一致时,脚本会明确提示“为获得最佳交叉评审效果请使用不同模型”,并要求输入y才继续——这印证了同模型也能跑、但质量打折扣的设计取舍。

跳过交互式提示:如果你希望循环完全无人值守(例如接入 CI),可以预先设置环境变量,脚本检测到四项配置齐全后会直接跳过所有问答:

RALPH_WORKER_MODEL="gpt-4o" \ RALPH_WORKER_PROVIDER="openai" \ RALPH_REVIEWER_MODEL="claude-sonnet-4-20250514" \ RALPH_REVIEWER_PROVIDER="anthropic" \ ~/.config/goose/recipes/ralph-loop.sh "Create a simple browser using Electron and React"

Step 3:观察循环运行

终端会交替显示 WORK PHASE 与 REVIEW PHASE。成功的一次运行大致长这样:

═══════════════════════════════════════════════════════════════ Ralph Loop - Multi-Model Edition ═══════════════════════════════════════════════════════════════ Task: Create a simple browser using Electron and React Worker: gpt-4o (openai) Reviewer: claude-sonnet-4-20250514 (anthropic) Max Iterations: 10 ─────────────────────────────────────────────────────────────── Iteration 1 / 10 ─────────────────────────────────────────────────────────────── ▶ WORK PHASE ... (goose creates initial implementation) ... ▶ REVIEW PHASE ... (goose reviews the work) ... ↻ REVISE - Feedback for next iteration: Missing error handling for invalid URLs. Also needs back/forward navigation buttons. ─────────────────────────────────────────────────────────────── Iteration 2 / 10 ─────────────────────────────────────────────────────────────── ▶ WORK PHASE ... (goose addresses feedback) ... ▶ REVIEW PHASE ... (goose reviews again) ... ═══════════════════════════════════════════════════════════════ ✓ SHIPPED after 2 iteration(s) ═══════════════════════════════════════════════════════════════

注意“REVISE - Feedback for next iteration”后面的文字并非人为输入,而是 reviewer 模型在评审阶段写进review-feedback.txt的内容,由脚本原样打印——这也是下一次 WORK PHASE 的修改依据。示例里 reviewer 在第 1 轮拦截到“缺少非法 URL 错误处理”和“缺少前进/后退导航按钮”,第 2 轮 worker 修复后即通过评审。

成本警告

:::warning 成本提示 Ralph Loop 会在循环中多次运行 Agent(默认最多 10 轮迭代),每轮都会同时消耗 worker 与 reviewer 两个模型的 token。请密切关注用量,必要时通过RALPH_MAX_ITERATIONS调低上限。 :::

状态文件协议:模型间的“文件级 API”

.goose/ralph/是循环状态的唯一事实来源。worker 与 reviewer 两个模型不共享任何记忆,它们之间通过以下文件“对话”:

文件用途
task.md任务描述(脚本在启动时写入)
iteration.txt当前迭代序号
work-summary.txt本轮 worker 做了什么(无论完成与否都会写)
work-complete.txt当 worker 声明任务完成时创建
review-result.txt评审结论:SHIPREVISE
review-feedback.txt给下一轮的改进反馈
.ralph-complete成功完成时创建(内容含时间戳)
RALPH-BLOCKED.md若 worker 判定任务被阻塞则创建

从 ralph-loop.sh 的编排逻辑可以看到这些文件的读写顺序:

  1. 每次启动先把INPUT(字符串或文件)写入task.md,并清空上一轮的review-result.txtreview-feedback.txtwork-complete.txtwork-summary.txt(第 137-149 行);
  2. 每轮迭代开始把轮次号写入iteration.txt(第 166 行);
  3. WORK PHASE 结束后检查RALPH-BLOCKED.md,存在即打印内容并退出(第 176-181 行);
  4. REVIEW PHASE 结束后读取review-result.txt去除所有空白字符后与SHIP比较(第 192 行)——这一细节保证了即使模型写出了带换行或空格的SHIP也能正确匹配;
  5. 结果为SHIP:写入.ralph-complete、打印成功横幅并以退出码 0 结束;结果为REVISE:打印反馈文件内容,清理work-complete.txtreview-result.txt后进入下一轮(第 194-215 行);
  6. 循环正常耗尽时打印“Max iterations reached”并以退出码 1 结束(第 218-219 行)。

由于脚本头部开启了set -e(第 20 行),WORK 或 REVIEW 阶段任何一次goose run失败(goose 自身报错)都会导致整个循环立即中止,避免带病继续。

Recipe 文件逐段解析

Ralph Loop 的“智能”全部浓缩在三个文件里。在逐一拆解前,先看一下 goose 是如何解析 recipe 的,这能帮我们理解每个字段的真实含义。

从源码看 Recipe 结构

goose 的 recipe 是一份 YAML(也支持 JSON)格式的 Agent 配置,其数据模型定义在 crates/goose/src/recipe/mod.rs。核心字段包括:

  • version:文件格式版本,采用 semver,缺省值为1.0.0
  • title/description:recipe 的标题与描述,均为必填;
  • instructions:注入会话的系统级指令;
  • prompt:启动会话时使用的初始提示词。promptinstructions至少需要一个(见同一文件第 413-415 行的RecipeBuilder::build校验);
  • extensions:recipe 启用的一组扩展(extension)配置;
  • settings/activities/author/parameters/sub_recipes/response等可选字段。

CLI 侧,goose run通过--recipe参数接受“recipe 名称或 recipe 文件的完整路径”(cli.rs)。真正运行时,extract_from_cli.rs 会把prompt映射为会话初始内容、把instructions映射为额外的系统提示词——这解释了为什么两份 recipe 都同时提供instructions(长期约束)和prompt(阶段性行动清单)两个字段。

Bash 编排脚本(ralph-loop.sh)

这是整个循环的“指挥中枢”,从参数校验、模型提示、状态目录初始化到阶段切换全部由它完成。完整内容如下:

#!/bin/bash # # Ralph Loop - Multi-Model Edition # # Fresh context per iteration + cross-model review # Based on Geoffrey Huntley's technique # # Usage: ./ralph-loop.sh "your task description here" # or: ./ralph-loop.sh /path/to/task.md # # Environment variables: # RALPH_WORKER_MODEL - Model for work phase (prompts if not set) # RALPH_WORKER_PROVIDER - Provider for work phase (prompts if not set) # RALPH_REVIEWER_MODEL - Model for review phase (prompts if not set) # RALPH_REVIEWER_PROVIDER - Provider for review phase (prompts if not set) # RALPH_MAX_ITERATIONS - Max iterations (default: 10) # RALPH_RECIPE_DIR - Recipe directory (default: ~/.config/goose/recipes) # set -e INPUT="$1" RECIPE_DIR="${RALPH_RECIPE_DIR:-$HOME/.config/goose/recipes}" RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' if [ -z "$INPUT" ]; then echo -e "${RED}Error: No task provided${NC}" echo "Usage: $0 \"your task description\"" echo " or: $0 /path/to/task.md" exit 1 fi # Function to prompt for settings prompt_for_settings() { local default_model="${GOOSE_MODEL:-}" local default_provider="${GOOSE_PROVIDER:-}" # Worker model if [ -n "$default_model" ]; then echo -ne "${BLUE}Worker model${NC} [${default_model}]: " read -r user_input WORKER_MODEL="${user_input:-$default_model}" else echo -ne "${BLUE}Worker model${NC}: " read -r WORKER_MODEL if [ -z "$WORKER_MODEL" ]; then echo -e "${RED}Error: Worker model is required${NC}" exit 1 fi fi # Worker provider if [ -n "$default_provider" ]; then echo -ne "${BLUE}Worker provider${NC} [${default_provider}]: " read -r user_input WORKER_PROVIDER="${user_input:-$default_provider}" else echo -ne "${BLUE}Worker provider${NC}: " read -r WORKER_PROVIDER if [ -z "$WORKER_PROVIDER" ]; then echo -e "${RED}Error: Worker provider is required${NC}" exit 1 fi fi # Reviewer model echo -ne "${BLUE}Reviewer model${NC} (should be different from worker): " read -r REVIEWER_MODEL if [ -z "$REVIEWER_MODEL" ]; then echo -e "${RED}Error: Reviewer model is required${NC}" echo "The reviewer should be a different model to provide fresh perspective." exit 1 fi # Reviewer provider echo -ne "${BLUE}Reviewer provider${NC}: " read -r REVIEWER_PROVIDER if [ -z "$REVIEWER_PROVIDER" ]; then echo -e "${RED}Error: Reviewer provider is required${NC}" exit 1 fi # Same model warning if [ "$WORKER_MODEL" = "$REVIEWER_MODEL" ] && [ "$WORKER_PROVIDER" = "$REVIEWER_PROVIDER" ]; then echo -e "${YELLOW}Warning: Worker and reviewer are the same model.${NC}" echo "For best results, use different models for cross-model review." echo -ne "Continue anyway? [y/N]: " read -r confirm if [ "$confirm" != "y" ] && [ "$confirm" != "Y" ]; then exit 1 fi fi # Max iterations echo -ne "${BLUE}Max iterations${NC} [10]: " read -r user_input MAX_ITERATIONS="${user_input:-10}" } # Initialize from environment variables WORKER_MODEL="${RALPH_WORKER_MODEL:-}" WORKER_PROVIDER="${RALPH_WORKER_PROVIDER:-}" REVIEWER_MODEL="${RALPH_REVIEWER_MODEL:-}" REVIEWER_PROVIDER="${RALPH_REVIEWER_PROVIDER:-}" MAX_ITERATIONS="${RALPH_MAX_ITERATIONS:-10}" # If any required setting is missing, prompt for all settings if [ -z "$WORKER_MODEL" ] || [ -z "$WORKER_PROVIDER" ] || [ -z "$REVIEWER_MODEL" ] || [ -z "$REVIEWER_PROVIDER" ]; then prompt_for_settings fi # Cost warning and confirmation loop while true; do echo "" echo -e "${YELLOW}⚠️ Cost Warning:${NC} This will run up to ${MAX_ITERATIONS} iterations, each using both models." echo " Estimated token usage could be significant depending on your task." echo "" echo -ne "Continue? [y/N]: " read -r confirm if [ "$confirm" = "y" ] || [ "$confirm" = "Y" ]; then break else echo "" prompt_for_settings fi done STATE_DIR=".goose/ralph" mkdir -p "$STATE_DIR" if [ -f "$INPUT" ]; then cp "$INPUT" "$STATE_DIR/task.md" echo -e "${BLUE}Reading task from file: $INPUT${NC}" else echo "$INPUT" > "$STATE_DIR/task.md" fi TASK=$(cat "$STATE_DIR/task.md") rm -f "$STATE_DIR/review-result.txt" rm -f "$STATE_DIR/review-feedback.txt" rm -f "$STATE_DIR/work-complete.txt" rm -f "$STATE_DIR/work-summary.txt" echo -e "${BLUE}═══════════════════════════════════════════════════════════════${NC}" echo -e "${BLUE} Ralph Loop - Multi-Model Edition${NC}" echo -e "${BLUE}═══════════════════════════════════════════════════════════════${NC}" echo "" echo -e " Task: ${YELLOW}$TASK${NC}" echo -e " Worker: ${WORKER_MODEL} (${WORKER_PROVIDER})" echo -e " Reviewer: ${REVIEWER_MODEL} (${REVIEWER_PROVIDER})" echo -e " Max Iterations: $MAX_ITERATIONS" echo "" for i in $(seq 1 "$MAX_ITERATIONS"); do echo -e "${BLUE}───────────────────────────────────────────────────────────────${NC}" echo -e "${BLUE} Iteration $i / $MAX_ITERATIONS${NC}" echo -e "${BLUE}───────────────────────────────────────────────────────────────${NC}" echo "$i" > "$STATE_DIR/iteration.txt" echo "" echo -e "${YELLOW}▶ WORK PHASE${NC}" GOOSE_PROVIDER="$WORKER_PROVIDER" GOOSE_MODEL="$WORKER_MODEL" goose run --recipe "$RECIPE_DIR/ralph-work.yaml" || { echo -e "${RED}✗ WORK PHASE FAILED${NC}" exit 1 } if [ -f "$STATE_DIR/RALPH-BLOCKED.md" ]; then echo "" echo -e "${RED}✗ BLOCKED${NC}" cat "$STATE_DIR/RALPH-BLOCKED.md" exit 1 fi echo "" echo -e "${YELLOW}▶ REVIEW PHASE${NC}" GOOSE_PROVIDER="$REVIEWER_PROVIDER" GOOSE_MODEL="$REVIEWER_MODEL" goose run --recipe "$RECIPE_DIR/ralph-review.yaml" || { echo -e "${RED}✗ REVIEW PHASE FAILED${NC}" exit 1 } if [ -f "$STATE_DIR/review-result.txt" ]; then RESULT=$(cat "$STATE_DIR/review-result.txt" | tr -d '[:space:]') if [ "$RESULT" = "SHIP" ]; then echo "" echo -e "${GREEN}═══════════════════════════════════════════════════════════════${NC}" echo -e "${GREEN} ✓ SHIPPED after $i iteration(s)${NC}" echo -e "${GREEN}═══════════════════════════════════════════════════════════════${NC}" echo "COMPLETE: $(date)" > "$STATE_DIR/.ralph-complete" exit 0 else echo "" echo -e "${YELLOW}↻ REVISE - Feedback for next iteration:${NC}" if [ -f "$STATE_DIR/review-feedback.txt" ]; then cat "$STATE_DIR/review-feedback.txt" fi fi else echo -e "${RED}✗ No review result found${NC}" exit 1 fi rm -f "$STATE_DIR/work-complete.txt" rm -f "$STATE_DIR/review-result.txt" echo "" done echo -e "${RED}✗ Max iterations ($MAX_ITERATIONS) reached${NC}" exit 1

(同文件同时保留于 documentation/src/pages/recipes/data/recipes/ralph-loop.sh。)

脚本中最值得关注的两处设计:

  1. 两阶段模型切换:脚本用内联环境变量方式调用 goose(第 171 行与 186 行)——GOOSE_PROVIDER="$WORKER_PROVIDER" GOOSE_MODEL="$WORKER_MODEL" goose run --recipe ...。这意味着 goose 会话的实际模型由环境变量在每次调用前被覆盖,而无需修改任何 goose 全局配置;
  2. 失败即终止:无论是 goose 命令本身出错、模型声明 BLOCKED、还是评审结束却没有产出review-result.txt,脚本都会立即退出并给出明确的失败原因,不会在错误状态上空转。

Work 阶段 Recipe(ralph-work.yaml)

这份 recipe 决定 worker 模型每一轮的行为,其完整内容与仓库文件 ralph-work.yaml 一致:

version: 1.0.0 title: Ralph Work Phase description: Single iteration of work - fresh context each time instructions: | You are in a RALPH LOOP - one iteration of work. Your work persists through FILES ONLY. You will NOT remember previous iterations. STATE FILES (in .goose/ralph/): - task.md = The task you need to accomplish (READ THIS FIRST) - iteration.txt = Current iteration number - review-feedback.txt = Feedback from last review (if any) - work-complete.txt = Create when task is DONE (reviewer will verify) FIRST: Check your state 1. cat .goose/ralph/task.md (YOUR TASK) 2. cat .goose/ralph/iteration.txt 2>/dev/null || echo "1" 3. cat .goose/ralph/review-feedback.txt 2>/dev/null 4. ls -la to see existing work THEN: Make progress - If review-feedback.txt exists, ADDRESS THAT FEEDBACK FIRST - Read existing code/files before modifying - Make meaningful incremental progress - Run tests/verification if applicable FINALLY: Signal status - If task is complete: echo "done" > .goose/ralph/work-complete.txt - Always write a summary: echo "what I did" > .goose/ralph/work-summary.txt prompt: | ## Ralph Work Phase Read your task from: .goose/ralph/task.md 1. Read the task: `cat .goose/ralph/task.md` 2. Check iteration: `cat .goose/ralph/iteration.txt 2>/dev/null || echo "1"` 3. Check for review feedback: `cat .goose/ralph/review-feedback.txt 2>/dev/null` 4. List existing files: `ls -la` 5. Do the work (address feedback if any, otherwise make progress) 6. Write summary: `echo "summary" > .goose/ralph/work-summary.txt` 7. If complete: `echo "done" > .goose/ralph/work-complete.txt` extensions: - type: builtin name: developer timeout: 600

逐段拆解其语义:

  • instructions 是“世界观”:它用最高优先级告知模型“你处于 Ralph Loop 的单轮工作中;你的成果只通过文件持久化,你不会记得上一轮”。这句话是整套机制能运转的心理基础——模型一旦误以为自己在长会话里,就可能跳过读取反馈,破坏循环;
  • 状态读取的确定性cat task.mdcat iteration.txt 2>/dev/null || echo "1"cat review-feedback.txt 2>/dev/null的组合确保了三件事——任务永远被读到、迭代号缺失时回退为 1、首次运行时“没有反馈”不会报错而是被当作正常状态处理;
  • 推进优先级:有评审反馈就先解决反馈(ADDRESS THAT FEEDBACK FIRST),其次才是新增功能,并且要求动手前先读已有代码、尽量做“有意义的增量”、条件允许就跑测试验证——这些约束把“修补”和“新开发”的顺序固定下来;
  • 收尾信号:完成时写work-complete.txt(供 reviewer 验证),无论完成与否都必须写work-summary.txt(供 reviewer 了解工作内容)。两个文件职责分离:一个是“完成声明”,一个是“工作摘要”;
  • extensionstype: builtin+name: developer表示加载 goose 内置的 developer 扩展(提供文件操作、命令执行等开发工具),timeout: 600把该扩展的调用超时放宽到 600 秒,避免大型构建或长测试被过早中断。

Review 阶段 Recipe(ralph-review.yaml)

评审是 Ralph Loop 相对原始 Ralph Wiggum 技术的增量所在。完整内容与仓库文件 ralph-review.yaml 一致:

version: 1.0.0 title: Ralph Review Phase description: Cross-model review of work - returns SHIP or REVISE instructions: | You are a CODE REVIEWER in a Ralph Loop. Your job: Review the work done and decide SHIP or REVISE. You are a DIFFERENT MODEL than the worker. Your fresh perspective catches mistakes. STATE FILES (in .goose/ralph/): - task.md = The original task (READ THIS FIRST) - work-summary.txt = What the worker claims to have done - work-complete.txt = Exists if worker claims task is complete REVIEW CRITERIA: 1. Does the code/work actually accomplish the task? 2. Does it run without errors? 3. Is it reasonably complete, not half-done? 4. Are there obvious bugs or issues? BE STRICT but FAIR: - Don't nitpick style if functionality is correct - DO reject incomplete work - DO reject code that doesn't run - DO reject if tests fail OUTPUT: If approved: echo "SHIP" > .goose/ralph/review-result.txt If needs work: echo "REVISE" > .goose/ralph/review-result.txt echo "specific feedback" > .goose/ralph/review-feedback.txt prompt: | ## Ralph Review Phase 1. Read the task: `cat .goose/ralph/task.md` 2. Read work summary: `cat .goose/ralph/work-summary.txt` 3. Check if complete: `cat .goose/ralph/work-complete.txt 2>/dev/null` 4. Examine the actual files created/modified 5. Run verification (tests, build, etc.) 6. Decide: SHIP or REVISE If SHIP: `echo "SHIP" > .goose/ralph/review-result.txt` If REVISE: `echo "REVISE" > .goose/ralph/review-result.txt` `echo "specific feedback" > .goose/ralph/review-feedback.txt` extensions: - type: builtin name: developer timeout: 300

要点解读:

  • 评审依据不是“摘要”,而是“事实”:prompt 第 4-5 步要求 reviewer 亲自检查实际创建/修改的文件并运行验证(测试、构建等),而不是仅凭work-summary.txt的自我描述就下结论——这正是“质量闸门”成立的关键;
  • 评审标准的可操作化:四条判据把“任务是否真正完成、能否无错运行、是否只是半成品、有无明显缺陷”显式列出;再叠加“严格但公平”的边界约束:不抠风格(功能正确时不吹毛求疵),但坚决拒绝不完整的工作、跑不起来的代码和测试失败的结果;
  • 两种退出路径:通过则写SHIP,否则写REVISE并给出具体可执行的反馈(要求“specific feedback”而非泛泛而谈)。反馈质量直接决定下一轮 worker 的修复质量;
  • timeout 差异:评审阶段同样加载 developer 扩展以运行验证命令,但超时收紧为 300 秒——评审通常比开发更快,较短的超时可避免卡死在评审上。

使用建议与适用边界

何时适合使用 Ralph Loop

  • 复杂、多步骤任务:需要多轮迭代才能收敛的任务能从“每轮重来”中获得显著收益;
  • 有明确完成判据的任务:例如测试通过、构建成功——这类客观信号能让 reviewer 的SHIP决策变得可靠;
  • 希望在交付前设置质量闸门:当你不信任单次一键生成的结果、又不想逐轮人工检查时,用另一个模型把关是一种低成本的替代方案。

何时属于过度设计

  • 简单的一次性任务(一轮就能完成,循环纯属浪费 token);
  • 交互式 / 探索性工作(需要人工持续介入决策,不适合无人循环);
  • 缺乏可验证完成标准、无法让 reviewer 客观判断“是否真的做完了”的任务。

重置与重新开始

如果上一轮运行卡死、或你想在同一个目录里开启一个全新任务,请清空状态目录:

rm -rf .goose/ralph

脚本启动时本来就会重建.goose/ralph并清空四个评审相关文件,但手动清理可以同时清除可能残留的RALPH-BLOCKED.mdwork-complete.txt等标记,确保从绝对干净的状态开始。

小结

Ralph Loop 用三条简单而有力的工程约定,解决了长任务中 Agent 质量随上下文累积而衰退的痛点:

  1. 每轮全新会话——噪声不再残留,模型每一轮都以干净上下文面对任务;
  2. 文件即状态——.goose/ralph/目录充当 worker 与 reviewer 之间的协议层,用task.mdwork-summary.txtreview-feedback.txtreview-result.txt等文件传递信息;
  3. 双模型交叉评审——不同的 reviewer 模型以“严格但公平”的标准执行测试与检查,输出SHIP/REVISE结论,把质量闸门从人工移到 Agent 侧。

整个模式由三个可复制的文件落地(ralph-loop.sh、ralph-work.yaml、ralph-review.yaml),recipe 的底层结构由 crates/goose/src/recipe/mod.rs 解析、由 crates/goose-cli/src/recipes/extract_from_cli.rs 映射为实际会话。想要进一步钻研的读者,可以从这几处源码入口继续深入,也可以对照 Ralph Loop 教程原文 查看原始排版与上下文。

【免费下载链接】goosean open source, extensible AI agent that goes beyond code suggestions - install, execute, edit, and test with any LLM项目地址: https://gitcode.com/GitHub_Trending/goose3/goose

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/9 21:03:36

单例初始化耗时操作拖死主线程?从ANR事故到根治方案

一提到“单例初始化”,很多人第一反应是设计模式里的标准写法:double-check、volatile、私有构造器,背得滚瓜烂熟。但真要出了线上问题,主线程卡死、首帧白屏、启动比竞品慢两秒,罪魁祸首往往就是这个看起来人畜无害的…

作者头像 李华
网站建设 2026/9/9 21:03:08

基于Hadoop+Spark+Hive的游戏推荐系统毕业设计实战

1. 项目核心架构与为什么选择这套大数据技术栈1.1 游戏推荐系统的毕业设计到底在做什么游戏推荐系统,本质上是把市面上那些电商推荐、视频推荐的思路,搬到了游戏分发场景里。用户打开一个游戏平台,系统根据他的历史行为——玩过什么、下载过什…

作者头像 李华
网站建设 2026/9/9 21:02:00

模拟器与真机协同的移动端自动化测试方案

做移动端自动化测试的同学,大概率都经历过这种尴尬:模拟器上跑得好好的用例,一上真机就翻车;或者为了验证一个功能,IT 那边临时借来一筐真机,插上数据线手动跑半天。我这边团队之前也在这个坑里耗了很久&am…

作者头像 李华
网站建设 2026/9/9 21:00:59

免费代理为什么总是打不开维基百科?原因与对策解析

这个问题我几乎每隔几天就会在爬虫交流群里看到一次。提问的人通常是在做数据采集、语料整理或者学术研究的开发者,他们从免费的代理站点上抓下来一堆代理IP,配置好 requests 或者 scrapy,然后对着维基百科的页面发请求,结果不是超…

作者头像 李华
网站建设 2026/9/9 21:00:49

LabVIEW+汇川H5U+海康相机视觉对位方案实战拆解

简介:面向非标自动化领域工程师的LabVIEW与汇川PLC联合控制参考包,整合上位机程序、PLC下位机逻辑、EtherCAT伺服驱动及海康相机视觉对位等完整链路。使用者可从中学习LabVIEW通过网口控制汇川H5U与EtherCAT伺服的方法,并了解视觉模块与DSC模…

作者头像 李华