mcpField
R
ralph-review-deep

ralph-review-deep

github.com/jimwellerAgent 工作流69 次安装
代码仓库

关于 ralph-review-deep

ralph-review-deep 会验证 Ralph 文件和 bd 图状态,再通过 opencode 并行运行三个独立模型审查。它面向需要跨模型复核的场景,与单子 Agent 的 ralph-review 不同。

主要功能

  1. 01验证必需文件和 bd 图
  2. 02并行运行三个模型审查
  3. 03为每个模型生成独立报告
  4. 04跟踪进度、费用和错误
  5. 05保留日志供后续检查

适用场景

  1. 01比较多个独立的 Ralph 计划审查
  2. 02结合图检查结果核查计划缺陷
  3. 03查看模型运行状态和日志

安装

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

$npx skills add https://github.com/jimweller/clanker-skills --skill ralph-review-deep

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

详细介绍

STARTER_CHARACTER = 🔬

Ralph 深度评审

验证 beads 图,并通过 opencode run 使用不同模型并行启动三项独立的 ralph 产物评审。每个模型都会生成一份评审文件,评估目标是否清晰、任务拆解、排序、计划完整性、风险与缺漏,以及可行性。

如需使用内部子 Agent 进行更快的单模型评审,请改用 ralph-review 技能(/ralph-review,$ralph-review)。这个深度版本以更长耗时和更高成本换取跨模型共识。

模型

标签模型 ID
openaiopenai/gpt-5.5
geminigoogle/gemini-3.1-pro-preview
claudeaz-anthropic/claude-opus-4-6

流程

步骤 1:验证产物是否存在
PROJECT_ROOT=$(git rev-parse --show-toplevel)

验证以下各项均存在:

  • $PROJECT_ROOT/.llmtmp/ralph-plan.md
  • $PROJECT_ROOT/.llmtmp/ralph-prompt-insession.md
  • $PROJECT_ROOT/.llmtmp/ralph-prompt-external.md
  • $PROJECT_ROOT/.beads/(目录;通过 bd list >/dev/null 2>&1 进行 bd 感知探测)

如果缺少任何一项,则中止。

步骤 2:验证 bd 图

启动 opencode 前运行以下检查。此处的失败属于高严重性问题,应中止或明确标记。

bd 图按每次运行的 epic 组织。slug 根据当前分支生成;通过 ralph:<slug> 标签查找 epic。所有范围限定的检查都使用 --parent ${EPIC} 过滤。

cd "$PROJECT_ROOT"

SLUG=$(git branch --show-current | tr '/' '-')

# 1. Single open epic for this run
EPIC_COUNT=$(bd list -t epic -l "ralph:${SLUG}" --json 2>/dev/null | jq '[.[] | select(.status=="open")] | length')
if [[ "$EPIC_COUNT" -ne 1 ]]; then
  echo "HIGH: expected exactly one open epic with label ralph:${SLUG}, found ${EPIC_COUNT}"
fi
EPIC=$(bd list -t epic -l "ralph:${SLUG}" --json 2>/dev/null | jq -r '[.[] | select(.status=="open")] | .[0].id // empty')

# 2. Cycles
if ! bd dep cycles >/dev/null 2>&1; then
  echo "HIGH: bd graph has dependency cycles"
  bd dep cycles
fi

# 3. Minimum child count under the run epic
COUNT=$(bd list --parent "$EPIC" --json 2>/dev/null | jq 'length')
if [[ "$COUNT" -eq 0 ]]; then
  echo "HIGH: run epic ${EPIC} has no child tasks"
fi

# 4. At least one ready task under the run epic
READY_COUNT=$(bd ready --parent "$EPIC" --json 2>/dev/null | jq 'length')
if [[ "$READY_COUNT" -eq 0 && "$COUNT" -gt 0 ]]; then
  echo "HIGH: run epic ${EPIC} has tasks but no ready tasks (deadlock or all closed unexpectedly)"
fi

# 5. Isolated nodes within the run epic
if [[ "$COUNT" -gt 1 ]]; then
  bd list --parent "$EPIC" --json 2>/dev/null \
    | jq -r '.[] | select(.dependency_count == 0 and .dependent_count == 0) | "MEDIUM: isolated task " + .id + " " + .title'
fi

# 6. Description coverage: every child carries the worker's instructions
bd list --parent "$EPIC" --json 2>/dev/null \
  | jq -r '.[] | select(((.description // "") | length) == 0) | "HIGH: task " + .id + " has empty description: " + .title'

# 7. Parent set equals label set (defense-in-depth orphan detection)
PARENT_IDS=$(bd list --parent "$EPIC" --json 2>/dev/null | jq -r '.[].id' | sort)
LABEL_IDS=$(bd list --label "ralph:${SLUG}" --json 2>/dev/null | jq -r '.[] | select(.issue_type != "epic") | .id' | sort)
if [[ "$PARENT_IDS" != "$LABEL_IDS" ]]; then
  echo "HIGH: parent set (--parent ${EPIC}) and label set (--label ralph:${SLUG} excluding epic) differ"
  echo "Parent-only (label missing): $(comm -23 <(echo "$PARENT_IDS") <(echo "$LABEL_IDS"))"
  echo "Label-only (orphan, parent missing): $(comm -13 <(echo "$PARENT_IDS") <(echo "$LABEL_IDS"))"
fi

保存这些检查结果;评审者会在最终报告中引用它们。

步骤 3:清理之前的评审
rm -f "$PROJECT_ROOT"/.llmtmp/ralph-review-openai.md \
      "$PROJECT_ROOT"/.llmtmp/ralph-review-gemini.md \
      "$PROJECT_ROOT"/.llmtmp/ralph-review-claude.md
步骤 4:读取文件并构建提示词上下文

将以下文件的内容串联为一个 CONTEXT 字符串:

  1. .llmtmp/ralph-plan.md
  2. .llmtmp/ralph-prompt-insession.md
  3. .llmtmp/ralph-prompt-external.md
  4. 在步骤 2 中解析出的 slug 和 epic ID(字面标签 SLUG=... 和 EPIC=...)
  5. bd list --parent "$EPIC" --json 的输出
  6. bd ready --parent "$EPIC" --json 的输出
  7. bd list --label "ralph:${SLUG}" --json 的输出
  8. 步骤 2 中的 bd 图验证结果
  9. 计划的 plan documents: 行中列出的计划文档。解析该行,以逗号拆分并去除空白,然后读取每个路径。将每项包装为 === plan-documents/<path> ===,以便评审者将其与基线内容区分开。值为空表示无需加载计划文档。
  10. 项目根目录中的 CLAUDE.md 和 README.md(如果存在)
  11. .llmdocs/ 中的所有 .md 文件

将每项包装为:

=== <relative-path or label> ===
<contents>
步骤 5:构建评审提示词

构建每个 opencode 进程执行的提示词。替换 <PROJECT_ROOT> 和 <CONTEXT>:

PROMPT="You are a plan reviewer running headless in a non-interactive session. There is no user present. Do not ask questions. Do not prompt for confirmation. Do not stop to wait for input.

YOUR PRIMARY OBJECTIVE IS TO WRITE A FILE. Everything else is preparation. After completing your review, your VERY NEXT action must be a tool call that writes the output file. Do not summarize, do not reflect, do not plan — write the file immediately.

OUTPUT RULES: You are running headless. Nobody reads your text responses. ALL review content goes exclusively into the output file via tool calls. Any text you generate outside of a tool call is wasted tokens and risks hitting the output token limit before you can write the file. Keep text responses to one short sentence at most.

PROJECT_ROOT: <PROJECT_ROOT>

## Context

<CONTEXT>

## How Ralph Loops Work

A ralph loop is an autonomous, iterative execution mechanism. Two execution modes share the same artifacts:

- **In-session (ralph-loop plugin)**: a Stop hook re-feeds the prompt to the same Claude session. Cheap on short runs; expensive on long runs because context grows quadratically.
- **External (scripts/ralph.sh)**: a bash while-loop spawns a fresh `claude --print` per iteration. Higher fixed overhead per iteration; stays in the cheap part of the cost curve indefinitely.

Authority sources in CONTEXT:

The CONTEXT contains two distinct authority categories. Treat them differently.

- **Plan documents** (under `=== plan-documents/...` blocks): forward-looking intent the planner consulted, e.g., a PRD, a Jira ticket, a design note. The plan must faithfully render these. Flag the plan if it omits, contradicts, or stale-references a requirement from a plan document.
- **Baseline docs** (`CLAUDE.md`, `README.md`, `.llmdocs/*`): the system's current state. The plan's job is to change this state. Do NOT flag the plan for deviating from baseline. Flag only if the plan changes baseline without including a corresponding docs-update bead (typically delegated to the docs skill).

Mechanics that apply to both modes:

- The bd graph is the state machine. The graph is shared across worktrees of the same repo. Each ralph run is organized under a per-run epic so concurrent runs in different worktrees stay isolated by `--parent` filtering. `bd ready --parent <epic> --json` finds the next unblocked task within this run.
- The run epic carries the label `ralph:<slug>` where `<slug>` is derived from the current branch. Every child task carries both `--parent <epic>` and the same `ralph:<slug>` label. The two signals are independent so the reviewer can detect orphans.
- The plan's "Run Identity" section records the literal slug and epic ID. The agent reads them directly from the plan each iteration, no derivation.
- One task per iteration. The agent reads `bd ready --parent <epic> --json`, takes the first result, runs the per-task workflow, then closes the task.
- When the ready queue is empty, the agent closes the epic and emits the sentinel as the terminal action. The epic is not closed by `bd` automatically.
- Resumable. A partially-completed graph resumes cleanly. Partial completion is normal; iterations are cheap.
- Every action is a bd task, including ralph lifecycle scaffolding. The branch creation, BEGIN tag, code work, docs, and END tag are all first-class beads, all parented to the run epic.
- Each bead carries its full per-task instructions in its description: files to touch, expected behavior, verification command, commit message. The worker reads `bd show <id>` and executes the description exactly.
- Run-wide conventions (commit style, language, build command, test command) live in `ralph-plan.md`, not in every description.
- Environment is a precondition. Credentials, network, toolchain, and runtime dependencies are the operator's responsibility. Do not flag missing environment setup as a gap.

Do NOT recommend: collapsing tasks into bundles, adding environment preflight checks, treating partial completion as a risk, modifying the prompt body, replacing the bd graph with a markdown checklist, or reintroducing a workflow-label taxonomy. The `ralph:<slug>` label is run-identity for partition and orphan detection, not workflow dispatch; do not flag it as a label taxonomy.

Flag as HIGH severity if: zero or more than one open epic exists for `ralph:<slug>`; any open child has an empty description; the bd graph contains cycles; the run epic has no children; the run epic has children but no ready tasks; the parent set under the epic differs from the label set for `ralph:<slug>` (orphans or planning typos); the per-task workflow does not explicitly stop after `bd close` (the agent will do multiple beads in one context, defeating the Ralph design); the per-task workflow does not close the epic before emitting the sentinel; the plan lacks a "Run Identity" section recording the literal slug and epic ID; the plan lacks an "Inputs" section with a `plan documents:` line; the plan omits or contradicts a material requirement explicit in any plan document; the plan's Approach prose declares an ordering ("X first", "after Y") that the bd dependency edges do not enforce. Flag as MEDIUM if: a description omits the verification command or commit message; an isolated task exists in a multi-task graph; the plan duplicates information that already lives in bead descriptions; a bead that touches README.md/CLAUDE.md/.llmdocs/ authors edits inline instead of running the docs skill.

## Your Task

Review the Ralph artifacts:

- ralph-plan.md (mode-neutral execution plan)
- ralph-prompt-insession.md (slash-command wrapper for the in-session driver)
- ralph-prompt-external.md (body for scripts/ralph.sh)
- The bd graph (issues, dependencies, ready/closed state)

Evaluate across these areas:

### 1. Goal Clarity

- Is the objective well-defined and unambiguous?
- Would a fresh-context iteration understand what success looks like from the plan alone?

### 2. Task Decomposition

- Are tasks the right granularity (one focused deliverable each)?
- Is each task independently completable?
- Are there missing tasks needed to achieve the goal?
- Are there unnecessary or redundant tasks?
- Do titles name deliverables rather than techniques?
- Do descriptions carry enough detail (files, verification, commit message) for a cold-start worker?

### 3. Sequencing and Dependencies

- Are dependencies correct in the bd graph?
- Would executing in `bd ready --json` order produce correct results?
- Are there implicit dependencies that should be explicit edges?
- Are there cycles or isolated nodes?

### 4. Plan Completeness

- Do the instructions cover repo-specific conventions, tools, and commands?
- Are build, test, and lint commands accurate?
- Is the per-task workflow clear (read description, execute it, close)?
- Does the plan have a "Run Identity" section that records the literal branch slug, the literal epic ID, and the epic label `ralph:<slug>`?
- Does the Per-Task Workflow read the epic ID from the "Run Identity" section and scope `bd ready` with `--parent <epic-id>`?
- Does the Per-Task Workflow close the epic via `bd close <epic-id>` before emitting the sentinel when the ready queue is empty?
- Does the Per-Task Workflow explicitly say STOP after `bd close` so the agent does not loop within a single context?
- Does the Git Workflow section require a `ralph/` feature branch and BEGIN/END tags?
- Is the Per-Task Workflow explicit that `bd close` for the current task runs BEFORE the sentinel?
- Do beads that touch `README.md`, `CLAUDE.md`, or `.llmdocs/` invoke the docs skill (/docs, $docs) rather than authoring edits inline?

### 5. Risk and Gaps

- What could go wrong during autonomous execution?
- Are there tasks that require human judgment or external access?
- Could any task leave the repo in a broken state?

### 6. Feasibility

- Can a single iteration realistically complete each task?
- Are there tasks that exceed what a fresh context can do autonomously?

For each area, list specific findings with severity (high/medium/low) and actionable recommendations.

## Output

Your VERY NEXT action after the review must be a tool call that writes the file. No intermediate steps.

Determine your model label:

- Claude variants: claude
- GPT variants: openai
- Gemini variants: gemini

Write to `<PROJECT_ROOT>/.llmtmp/ralph-review-$MODEL_LABEL.md` using this template:

\`\`\`markdown
# Ralph Loop Review
**Model**: <MODEL_LABEL>

## Goal Clarity

- **[medium]** Short title. Explanation...

## Task Decomposition

- **[high]** Short title. Explanation...

## Sequencing and Dependencies

- **[medium]** Short title. Explanation...

## Plan Completeness

- **[low]** Short title. Explanation...

## Risk and Gaps

- **[high]** Short title. Explanation...

## Feasibility

- **[medium]** Short title. Explanation...

## Summary

<overall assessment and top 3 recommendations>
\`\`\`

Finding format: \`- **[severity]** Title. Description.\`

Every section must be present. If no findings for an area, write 'No findings.' under its heading.

Then verify: \`ls -la '<PROJECT_ROOT>/.llmtmp/ralph-review-<MODEL_LABEL>.md'\`

If the file does not exist, write it again. Do not exit without the file."
步骤 6:将提示词写入文件

避免大型提示词出现 shell 插值问题:

STATE_DIR="$PROJECT_ROOT/.llmtmp/ralph_review_state"
mkdir -p "$STATE_DIR"
OPENAI_DIR=$(mktemp -d)
GEMINI_DIR=$(mktemp -d)
CLAUDE_DIR=$(mktemp -d)
cat > /tmp/ralph-review-prompt.txt <<'PROMPT_EOF'
<the prompt from Step 5>
PROMPT_EOF
步骤 7:启动 3 个独立的后台 Bash 任务

每个 opencode 进程都必须作为独立的后台 Bash 任务运行。不要在单个 shell 中用 & 将它们串联起来;父进程退出时,子进程会被终止。

OpenAI:

STATE_DIR="<PROJECT_ROOT>/.llmtmp/ralph_review_state" && \
opencode run \
  -m openai/gpt-5.5 \
  --format json \
  --print-logs \
  --log-level INFO \
  --dir "<OPENAI_DIR>" \
  --title "Ralph Review - OpenAI" \
  "$(cat /tmp/ralph-review-prompt.txt)" \
  > "$STATE_DIR/openai.ndjson" 2>"$STATE_DIR/openai.log"

Gemini:

STATE_DIR="<PROJECT_ROOT>/.llmtmp/ralph_review_state" && \
opencode run \
  -m google/gemini-3.1-pro-preview \
  --format json \
  --print-logs \
  --log-level INFO \
  --dir "<GEMINI_DIR>" \
  --title "Ralph Review - Gemini" \
  "$(cat /tmp/ralph-review-prompt.txt)" \
  > "$STATE_DIR/gemini.ndjson" 2>"$STATE_DIR/gemini.log"

Claude:

STATE_DIR="<PROJECT_ROOT>/.llmtmp/ralph_review_state" && \
opencode run \
  -m az-anthropic/claude-opus-4-6 \
  --format json \
  --print-logs \
  --log-level INFO \
  --dir "<CLAUDE_DIR>" \
  --title "Ralph Review - Claude" \
  "$(cat /tmp/ralph-review-prompt.txt)" \
  > "$STATE_DIR/claude.ndjson" 2>"$STATE_DIR/claude.log"

3 个任务都要分别启动为后台任务。不要在单个 shell 中使用 &。

输出流

每个 opencode 进程都会生成两个输出文件:

  • <label>.ndjson(标准输出):来自 --format json 的结构化 NDJSON 事件。用于以编程方式跟踪进度。
  • <label>.log(标准错误):纯文本信息级日志。用于诊断启动失败、权限问题、MCP 服务错误和插件加载问题。

日志行是结构化文本,每行一条:

INFO  2026-03-13T00:54:25 +4ms service=default directory=/private/tmp creating instance
步骤 8:监控并等待

轮询每个后台任务,直到 3 个任务全部完成。

NDJSON 进度(将 $NDJSON 替换为实际路径):

# Count completed steps
grep -c '"type":"step_finish"' "$NDJSON" 2>/dev/null || echo 0

# Check if done (last step_finish has reason "stop")
tail -1 "$NDJSON" 2>/dev/null | jq -r '.part.reason // empty'

# Check for errors
grep '"type":"error"' "$NDJSON" 2>/dev/null

文本日志(将 $LOGFILE 替换为实际路径):

# Errors or warnings
grep -E "^(ERROR|WARN)" "$LOGFILE" 2>/dev/null

# Recent activity
tail -5 "$LOGFILE" 2>/dev/null
步骤 9:报告结果

对于每个模型,检查 .llmtmp/ralph-review-<label>.md 是否存在。

按模型报告:

  • 成功或失败(文件是否存在)
  • 总成本:汇总所有 step_finish 事件中的 cost
  • 是否发生过错误

在报告顶部单独列出步骤 2 中 bd 图验证的结果。

步骤 10:清理

保留状态目录,以便运行后检查(每个模型的 NDJSON 事件流和文本日志有助于诊断审查失败、校准回归和成本趋势)。

rm -f /tmp/ralph-review-prompt.txt

故意不删除 $STATE_DIR(.llmtmp/ralph_review_state/)。后续每次审查运行都会原地覆盖各模型的文件;如果需要保留历史记录,请在重新运行前归档该目录。

预期输出文件

共 3 个文件,每个模型各 1 个:

  • .llmtmp/ralph-review-openai.md
  • .llmtmp/ralph-review-gemini.md
  • .llmtmp/ralph-review-claude.md

NDJSON 日志格式参考

每个 opencode 进程都会将 NDJSON 写入 $STATE_DIR/<label>.ndjson。每行一个 JSON 对象。跳过解析失败的行(部分写入)。

关键事件类型:

  • step_start - 新的大模型轮次开始。
  • text - 模型输出的文本:{"type":"text","part":{"text":"..."}}
  • tool_use - 工具调用:{"type":"tool_use","part":{"tool":"bash","state":{"status":"completed","metadata":{"exit":0}}}}
  • step_finish - 轮次完成:{"type":"step_finish","part":{"reason":"stop","cost":0,"tokens":{"total":13494}}}。reason: "stop" = 完成,reason: "tool-calls" = 继续。
  • error - 会话错误:{"type":"error","error":{"data":{"message":"..."}}}

实用的 jq 查询(将 $NDJSON 替换为实际路径):

NDJSON="<PROJECT_ROOT>/.llmtmp/ralph_review_state/openai.ndjson"
# Is done?
tail -1 "$NDJSON" | jq -r 'select(.type=="step_finish") | .part.reason'
# Total cost
jq -s '[.[] | select(.type=="step_finish") | .part.cost] | add' "$NDJSON"
# All errors
jq -r 'select(.type=="error") | .error.data.message' "$NDJSON"

将 $LOGFILE 替换为文本日志路径:

grep -E "^(ERROR|WARN)" "$LOGFILE"

规则

  • 调用 Agent 仅负责启动。所有审查工作都在 opencode 进程内部完成。
  • 不要直接进行任何审查分析。审查工作由 opencode 进程处理。
  • 执行期间不要提问。这是非交互式流程。
  • 并行启动全部 3 个进程。不要等一个进程完成后再启动另一个。
  • 使用普通消息调用,不要使用 --command。--command 标志与 context7 MCP 服务存在已知问题。
  • 报告结果后保留状态目录。NDJSON 和日志文件留待运行后检查。
  • 如果某个模型失败,仍需等待其他模型并报告结果。
  • 步骤 2 中的 bd 图验证在调用 Agent 中运行,而不是在 opencode 中运行。验证结果会作为上下文传递给 opencode 审查者。

评论

支持 Markdown