mcpField
G
graph

graph

github.com/smallnestAgent 工作流296252 次安装6 周前更新
代码仓库

关于 graph

graph 是一项将任务、规格或 Issue 集转为依赖工作图的技能,并通过子 Agent 并行实现独立节点。它使用隔离的 git worktree、波次屏障和检查点协调执行。

主要功能

  1. 01将任务拆分为依赖节点
  2. 02校验 DAG 并识别范围冲突
  3. 03将工作分层为并行波次
  4. 04在隔离的 git worktree 中运行子 Agent
  5. 05保存检查点并生成 HTML 跟踪页

适用场景

  1. 01并行处理 PRD 或 Issue 集中的独立任务
  2. 02按任务依赖协调分阶段实现
  3. 03从已保存的波次检查点恢复执行

安装

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

$npx skills add https://github.com/smallnest/goal-workflow --skill graph

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

附带文件scripts/render_graph_html.py

详细介绍

graph — 将任务/PRD 转换为并行执行图

将任务(或 PRD/SPEC/问题集)转换为一个有向无环图,将其分层为超步(波次),并使用子 Agent 并发实现每个波次中的独立节点。每个节点都在自己的 Git worktree 中运行完整的 /goal → /review-it → /ship-it 流程,因此并行节点绝不会相互覆盖对方的工作树。波次之间会通过汇入屏障合并结果,并重新规划下一波。

这是 /loop-it 的并行版本。/loop-it 严格按顺序执行(一个 worktree,一次处理一个问题)。/graph 则会在每个波次中同时分发所有独立节点。


心智模型(借鉴自 LangGraph/图工程)

概念此处含义
节点一个可实现的工作单元(一个问题/子任务)
边依赖关系:B depends on A → 边 A → B
超步/波次依赖项均已满足的一组节点——并发运行
分出为当前波次中的每个节点分派一个子 Agent
汇入(屏障)启动下一波之前,等待当前波次中的所有节点完成
状态通道.graph_state——共享检查点,在波次之间重写(恢复来源)
实时跟踪器graph.html——Claude 风格的浅色主题仪表板,在每个检查点根据 .graph_state 重新渲染
动态重新规划波次结束后,如果出现新的工作/依赖关系,则修订图

核心原则: 同一波次中的独立节点没有共享状态,也不存在顺序依赖,因此可以真正并行运行。依赖关系决定了唯一的执行顺序。其他工作均同时运行。


概览

Input (task / PRD / SPEC / issues)
        │
        ▼
1. Decompose into nodes  ─────────►  nodes = {id, title, deps, criteria, scope}
        │
        ▼
2. Build DAG + validate  ─────────►  detect cycles, orphan deps
        │
        ▼
3. Topological layering  ─────────►  waves = [[n1,n2,n3], [n4,n5], [n6]]
        │
        ▼
4. Render graph + confirm with user
        │
        ▼  (write .graph_state + graph.html — open graph.html to watch live)
┌──────────── per wave (superstep) ────────────┐
│                                               │
│  FAN-OUT: 1 subagent per node (parallel)      │
│    each subagent, in its own git worktree:    │
│      /goal (inline implement) → /review-it    │
│                              → /ship-it        │
│                                               │
│  FAN-IN barrier: wait for ALL nodes           │
│    integrate, update .graph_state             │
│    re-render graph.html                        │
│    re-plan next wave if graph changed         │
│                                               │
└───────────────────────────────────────────────┘
        │
        ▼
All waves done → final summary

第 1 步:定位并分解输入

接受以下任意输入:自由格式的任务描述、PRD/SPEC 文件,或现有问题集(GitHub/本地 .md)。

  • PRD/SPEC → 复用 /to-issues 的分解规则(每个 User Story 对应一个节点;拆分大型项,合并琐碎项)。
  • 现有问题 → 每个问题对应一个节点;从问题正文中解析依赖关系(Depends on: #3、Dependencies: #3, #5)。
  • 自由格式任务 → 自行拆分为可独立交付的最小单元。

每个节点都必须包含:

Node #N
  title:      short imperative title
  deps:       [list of node ids] or []
  criteria:   acceptance criteria (checklist) — how the subagent knows it's done
  type:       backend | frontend | fullstack | ui | infra | docs
  scope_hint: which files/dirs this node is expected to touch (for conflict analysis)

scope_hint 很重要:没有依赖边但文件范围重叠的两个节点,并非真正独立——参见第 3 步。


第 2 步:构建 DAG 并验证

根据 deps 构建边,然后进行验证:

检查失败时的操作
循环(A → B → A)输出 ⚠️ 循环依赖: #A ↔ #B。按节点 ID 顺序打破循环,警告用户,并要求用户确认或修正。
悬空依赖(#7 depends on #99,不存在该节点)输出警告,并删除虚假边。
范围冲突(两个无依赖节点编辑相同文件)添加一条软边,按较低 ID 优先串行执行,或标记给用户。绝不能让两个并行 worktree 争用相同文件。

热点文件例外: 几乎每个节点都必须修改的共享接线文件(例如 router.go、main.go、mod.rs、DI 容器或 __init__ 重新导出文件)不算范围冲突——若将其视为冲突,整个图就会被串行化成一条链。对于此类文件,假设仅追加的修改可以顺利合并,并优先采用以下方式之一:(a) 指定一个节点负责接线,让其他节点提供注册钩子;或 (b) 在最后一个波次中追加一个小型的“接好所有部分”节点。范围冲突规则仅适用于多个节点修改同一文件中的相同逻辑(例如两个处理器重写同一个函数)。

步骤 3:拓扑分层为多个波次

使用 Kahn 算法计算波次:

  1. 波次 0 = 所有 deps == [] 且彼此之间没有作用域冲突的节点。
  2. 移除波次 0 的节点;波次 1 = 依赖项现已全部满足的节点。
  3. 重复上述步骤,直到所有节点都已分配。
  4. 在一个波次内,如果两个节点编辑了同一文件中的同一段逻辑(根据步骤 2 中热文件的例外情况判定为真实冲突),则将 ID 较大的节点推迟到下一波。仅仅重叠于接线文件不会触发此规则。

**ID 约定(始终一致):**ID 较小者优先——环依赖按 ID 从小到大打破(步骤 2),作用域冲突按 ID 从小到大串行处理(ID 较大的节点推迟到下一波)。

输出分层计划:

📊 Graph: 6 nodes, 3 waves

Wave 0 (parallel ×3):  #1 db schema   #2 config loader   #3 logging util
Wave 1 (parallel ×2):  #4 API handler (deps #1)   #5 CLI flags (deps #2)
Wave 2 (parallel ×1):  #6 integration (deps #4,#5)

Max parallelism: 3 subagents in Wave 0.

同时为用户生成 Mermaid 图:

```mermaid
graph LR
  n1[#1 db schema] --> n4[#4 API handler]
  n2[#2 config loader] --> n5[#5 CLI flags]
  n3[#3 logging util]
  n4 --> n6[#6 integration]
  n5 --> n6
```

**在派发任何子 Agent 之前,等待用户确认。**允许用户调整节点、依赖项或最大并行度上限。


步骤 4:执行前检查

在第一波开始前(与 /loop-it 的理念相同):

git rev-parse --is-inside-work-tree   # in a repo?
git status --porcelain                # clean tree? (dirty → stash/abort)
git branch --show-current             # on main/master?
git ls-remote --heads origin          # remote reachable?
gh auth status                        # if shipping to GitHub

任何硬性失败 → 输出错误并停止。与用户确认最大并发上限(默认并行运行 3–4 个子 Agent;更多可能导致触及速率限制并增加审查噪声)。

然后初始化状态通道和实时跟踪器(仅执行一次,在计划确认后、首次扇出前立即执行):

# 1. Write the initial checkpoint (all nodes pending, current_wave 0).
cat > .graph_state <<'JSON'
{ "version": 1, "task": "...", "repo": "owner/repo",
  "waves": [[1,2,3],[4,5],[6]], "current_wave": 0,
  "nodes": { "1": {"title":"...","deps":[],"status":"pending","wave":0}, ... } }
JSON

# 2. Keep it out of git.
grep -qxF '.graph_state' .gitignore || printf '.graph_state\ngraph.html\n' >> .gitignore

# 3. Render the Claude-style light-theme dashboard.
python3 skills/graph/scripts/render_graph_html.py .graph_state graph.html

告知用户:在浏览器中打开 graph.html — 它每 5 秒自动刷新,因此可以实时跟踪执行情况(波次、节点状态、进度条,以及按状态着色的 Mermaid DAG)。每个检查点都要重新运行渲染命令(见步骤 5b)以推送更新。


步骤 5:逐波执行(扇出 → 扇入)

按顺序逐个处理每个波次:

5a. 扇出 — 每个节点派发一个子 Agent,并行执行

在单条回复中派发该波次的所有节点(在一条消息中发起多个 Agent/子 Agent 调用即可并发执行)。每个子 Agent 都在自己的 git worktree 中工作,避免并行编辑文件时发生冲突:

# The orchestrator creates a worktree per node BEFORE dispatching:
git worktree add -b feat/node-{N}-{slug} ../.graph-worktrees/node-{N} main

每个子 Agent 都会收到一份自包含提示词(不会继承编排器的上下文):

You are implementing ONE node of a task graph, working in an ISOLATED git worktree.

Worktree:  ../.graph-worktrees/node-{N}   (already created on branch feat/node-{N}-{slug})
Node #{N}: {title}
Type:      {type}
Scope:     {scope_hint}  — stay within these files; do not touch other nodes' scope

Acceptance criteria (all must pass):
- [ ] {criterion 1}
- [ ] {criterion 2}

Context (deps already merged into main, pull first):
{summaries of dependency nodes' outputs, or the referenced PRD/SPEC excerpt}

Your pipeline (run all three, in order):
1. IMPLEMENT (inline /goal): read the node + any referenced PRD/SPEC, read adjacent
   code, implement to satisfy EVERY acceptance criterion, run build + tests + lint
   (e.g. go build ./... && go vet ./... && go test ./...). Iterate until all green.
2. REVIEW (/review-it): run code review on your changes, apply accepted findings,
   re-run focused tests, repeat until review is clean (max 2 rounds).
3. SHIP (/ship-it): commit (message references the node/issue), push branch,
   create PR, merge, close the issue.

Constraints:
- Work ONLY inside your worktree. Do NOT edit files outside {scope_hint}.
- Do NOT try to call `goal` via the Skill tool (it's a UI command, not a skill) —
  "implement" means you write the code yourself. /review-it and /ship-it ARE skills.
- If you cannot satisfy a criterion, STOP and report what's blocking — don't fake it.

Return: node id, PASS/FAIL, PR/commit refs, files changed, and — if you discovered new required work or a dependency the graph didn't capture — a `NEW_WORK:` line describing it (title + which nodes it blocks). Emit `NEW_WORK: none` if there's nothing.

为什么使用 worktree,而不仅是分支:/goal 会修改工作树。两个子 Agent 在同一个 checkout 中编辑会相互破坏。每个节点使用一个 worktree,可为其提供独立文件系统 checkout 和独立分支——这才真正实现了安全的并行波次。

5b. 扇入 — 屏障、集成、重新规划

等待该波次中的每个子 Agent 返回(BSP 屏障——本波提交前,下一波不能开始)。然后:

  1. 阅读每个子 Agent 的摘要。将节点标记为 shipped 或 failed。
  2. git checkout main && git pull — 依赖项的输出现已合并到 main,供下一波使用。
  3. 移除已完成的 worktree:git worktree remove ../.graph-worktrees/node-{N}(失败的 worktree 保留以供调查)。
  4. 将检查点写入 .graph_state,然后重新渲染跟踪器: python3 skills/graph/scripts/render_graph_html.py .graph_state graph.html(已打开的 graph.html 会在下次自动刷新时加载更新)。
  5. 动态重新规划(类似 LangGraph 的条件边):检查每个子 Agent 的 NEW_WORK: 行。如果有任何一行不是 none,则添加新节点/边,并在开始下一波前对剩余节点重新分层。向用户展示变更。
  6. 如果本波有任何节点失败,则将依赖于它的所有节点标记为 blocked 并跳过(其输入尚未就绪)。

继续处理下一波。

状态文件:.graph_state(+ 实时跟踪器 graph.html)

.graph_state 位于仓库根目录,必须写入 .gitignore。它是唯一可信来源:每个波次结束后都要保存检查点,这样发生崩溃时才能从波次边界恢复;并从中重新生成 graph.html,以便浏览器仪表板保持实时更新。graph.html 是一个派生视图——切勿手动编辑;应从 .graph_state 重新生成。

{
  "version": 1,
  "updated_at": "2026-07-21T10:30:00Z",
  "task": "Add user auth",
  "repo": "owner/repo",
  "waves": [[1, 2, 3], [4, 5], [6]],
  "current_wave": 1,
  "nodes": {
    "1": { "title": "db schema", "deps": [], "status": "shipped", "branch": "feat/node-1-db-schema", "pr": 43, "wave": 0 },
    "2": { "title": "config loader", "deps": [], "status": "shipped", "wave": 0 },
    "3": { "title": "logging util", "deps": [], "status": "failed", "wave": 0, "error": "test TestLog failed", "attempts": 2 },
    "4": { "title": "API handler", "deps": [1], "status": "in_progress", "wave": 1 },
    "6": { "title": "integration", "deps": [4, 5], "status": "blocked", "wave": 2, "reason": "depends on #3 (failed)" }
  }
}

状态值:pending | in_progress | shipped | failed | blocked | skipped。每个节点都包含 title + deps,这样 graph.html 就能直接根据检查点绘制 DAG 和卡片。

随时可以渲染跟踪器:

python3 skills/graph/scripts/render_graph_html.py .graph_state graph.html

恢复时:读取 .graph_state,跳过 shipped,询问如何处理 failed(重试/跳过),重新推导剩余波次,并重新渲染 graph.html。


安全防护

  • 必须隔离工作树——绝不能在同一检出目录中运行两个并行的 /goal 会话。
  • 必须设置汇入屏障——在第 N 波的所有节点都返回并合并之前,绝不能启动第 N+1 波。
  • 作用范围冲突时应串行执行——无依赖的节点若会修改相同文件,必须安排在不同波次。
  • 切勿在 /ship-it 前跳过 /review-it。
  • 限制并发数——默认 3–4 个;更多并发容易触发速率限制并造成合并冲突。
  • **绝不能强制推送到 main。**每个节点都通过自己的分支/PR 发布。
  • 失败的节点会阻塞其依赖节点——不要在输入条件未满足时发布。
  • 限制每个节点的最大重试次数——复用 /loop-it 的错误分类,别无限循环。
  • 首次扇出前确认计划。

常见错误

错误修正方法
在不同响应中派发子 Agent在一个响应中发起多个调用 = 并行。分开调用 = 串行。
未使用工作树 → 并行编辑会破坏工作树每个节点使用一个 git worktree。
两个“独立”节点编辑同一个文件添加软边;将它们安排在不同波次。
所有节点尚未合并就启动下一波强制执行汇入屏障。
过度拆分为 20 个琐碎节点合并小单元;节点应是有意义且可发布的单元。
忽略失败节点的依赖节点将它们标记为 blocked,并跳过。

与其他技能的关系

/prd → /prd-to-spec → /to-issues ─┬─► /loop-it   (sequential: one node at a time)
                                   └─► /graph     (parallel: whole wave at once)
                                          │
                     each node: inline /goal → /review-it → /ship-it (in its own worktree)
  • /to-issues——复用分解规则来构建节点。
  • /loop-it——串行执行的对应技能;节点大量共享文件或需要串行保障时使用。
  • /graph——本技能;DAG 中存在真正的并行性(独立子系统)时使用。
  • /review-it、/ship-it——每个节点的子 Agent 都会调用的实际技能。

评论

支持 Markdown