@master0071/loop-graph-cli
v0.1.0
Published
给 AI 编码 agent(opencode/claude code/kilo code)安装 Loop Engineering 闭环能力的 CLI 工具:脚本管硬约束 + 编排者管决策 + 三角色 Task 协作闭环。
Maintainers
Readme
@master0071/loop-graph-cli
给 AI 编码 agent(opencode / claude code / kilo code / qwen / codebuddy / qoder)安装 Loop Engineering(循环工程) + Graph Engineering(图工程) 闭环能力的 CLI 工具。
它解决什么问题
AI 编码 agent 单次执行容易跑偏、不收敛、无法自我验证。本工具给 agent 装上一套两层循环闭环:
- 外层(脚本管终止边界):
MAX_ITER/BUDGET_S硬熔断保证有界,STALL_LIMIT+ 可选VERIFY_CMD叠加客观信号降低空转/虚报 - 内层(编排者管决策):orchestrator 用 Task 工具委派 executor / reviewer / fixer 三角色协作,跑 执行→审查→修复→再审 的完整闭环
两档可选:
- 档位 A: Loop Engineering — 单节点自环(
/loop-task),适合绝大多数顺序任务 - 档位 B: Graph Engineering — 多节点图(
/graph-task),用 nodes/edges/state 声明拓扑,需要更细粒度路由时启用
外层 while (loop-task.sh | graph-run.sh) 内层闭环 (orchestrator 进程内)
┌──────────────────────────┐ ┌─────────────────────────────────┐
│ iter < MAX_ITER? │ │ 读状态 → 拆步骤 │
│ spawn orchestrator ────┼─────────────│→ Task(executor) 执行 │
│ 查硬约束: │ │ Task(reviewer) 验证+审查 │
│ goal_met & approved? │ │ fail? Task(fixer) → 再审 │
│ → DONE │ │ 写状态 → 判 DONE 退出 │
│ stalled/budget/iter? │ └─────────────────────────────────┘
│ → ABORT │
└──────────────────────────┘
图模式额外(graph-run.sh + graph-orchestrator):
- 读 state.graph 拓扑,从 entry 出发按边路由
- 每节点由 statectl graph-next 算下一节点(共享收敛点)
- 触达 __done__ 写终态;触达 __abort__ 转人工安装
npm install -g @master0071/loop-graph-cli使用
1. 给项目装 loop 能力
在你的项目根目录(已用 opencode/claude/kilo 的项目)里:
# 装到 opencode 项目
loop-graph install --to opencode
# 装到 claude code 项目
loop-graph install --to claude
# 装到 kilo code 项目
loop-graph install --to kilo
# 预览将写入的文件(不实际写盘)
loop-graph install --to opencode --dry-run
# 覆盖已存在文件重装
loop-graph install --to opencode --force安装后会在项目里生成 .opencode/(或 .claude/ / .kilo/ / .qwen/ / .codebuddy/ / .qoder/):
.opencode/
├── statectl.sh # 状态读写工具(jq)+ graph-next 子命令
├── loop-task.sh # Loop Engineering 外层(硬约束 + spawn 编排者)
├── graph-run.sh # Graph Engineering 外层(硬约束 + spawn 图编排者)
├── loop-review.sh # 复盘命令
├── state-schema.json # 状态 schema(v1 + v2 联合)
├── STATE_CONTRACT.md # 状态契约(含图拓扑/节点状态归属)
├── agents/
│ ├── orchestrator.md # 编排者(决策层,Loop Engineering)
│ ├── graph-orchestrator.md # 图编排者(决策层,Graph Engineering 档位 B)
│ ├── executor.md # 执行者
│ ├── reviewer.md # 审查者(验证+语义)
│ └── fixer.md # 修复者
└── commands/
├── loop-task.md # /loop-task 斜杠命令入口
├── graph-task.md # /graph-task 斜杠命令入口(档位 B)
└── loop-review.md # /loop-review 复盘命令frontmatter 由安装器按平台生成:
payload/templates/下的 agent/command 模板只含正文,不带 frontmatter。 安装时 src/install.ts 根据目标平台的frontmatterStyle生成对应格式(缩进由代码保证,避免占位符拼 YAML 错位):| 平台 | agent frontmatter | command frontmatter | |------|-------------------|---------------------| | opencode / kilo |
mode: subagent+temperature+steps+permission(orchestrator/graph-orchestrator 自动带task权限块) |loop-task/graph-task带agent: <对应编排者>+subtask: false| | claude / qwen / codebuddy / qoder |name+description+tools(工具集由角色决定:orchestrator/graph-orchestrator 含Task,executor/fixer 含Edit/Write,reviewer 只读) | 仅description(agent/subtask为 opencode 专用) |新增平台只需在
PLATFORMS里声明合适的frontmatterStyle。
Loop vs Graph:怎么选
两种模式都给 agent 装"外层硬约束循环 + 内层三角色协作闭环",区别在内层怎么组织工作流:
| | Loop(档位 A) | Graph(档位 B) |
|---|---|---|
| 工作流形态 | 单节点自环,编排者自由拆步骤 | 显式图拓扑,按 nodes/edges 的边路由 |
| 入口 | /loop-task → loop-task.sh | /graph-task → graph-run.sh |
| 编排者 | orchestrator | graph-orchestrator |
| 默认流程 | 编排者自主决定三角色顺序与次数 | 写死:exec→review→(approved→完成 / changes_requested→fix→再审 / blocked→中止) |
一句话:拿不准就用 Loop;只有当你想要"固定的、可审计的多阶段流水线"时才用 Graph。
2. 在 agent 工具里启动闭环
2a. Loop Engineering(单节点循环,档位 A)
/loop-task 修复登录页 500 错误 登录成功且 E2E 测试通过也可在命令行直接跑(调试 / CI / 无 agent 场景):
bash .opencode/loop-task.sh "修复登录页 500 错误" "登录成功且 E2E 测试通过"格式都是 ...loop-task "任务描述" "达成标准"(达成标准可省略,由 reviewer 判定)。
"单节点"的含义:状态文件里没有显式步骤图,编排者根据上下文自由编排三角色的调用顺序与次数,外层脚本只管硬约束(别跑超时、别空转)。编排者会自动:
- 读任务目标,拆解步骤
- Task 委派 executor 执行
- Task 委派 reviewer 验证(跑测试/编译)+ 语义审查
- 未过则 Task 委派 fixer 修复,再复审
- goal_met & approved → DONE
2b. Graph Engineering(多节点图,档位 B)
/graph-task 修复登录页 500 错误 登录成功且 E2E 测试通过默认图(不带 --graph 时跑的流程,等价于一条标准 exec→review→fix 流水线):
exec-1 ──► review-1 ──approved──► __done__(完成)
│
├──changes_requested──► fix-1 ──► review-1(再审)
│
└──blocked──► __abort__(转人工)适用场景:你想要"固定流程、不让编排者自由发挥"时,直接用默认图即可;想要不同流程再注入自定义图。
图编排者会:
- 读
state.graph图拓扑 - 从
entry出发,逐节点串行执行(不并行——档位 B 锁定决策) - 用
statectl graph-next <node_id> <result>计算下一节点(由边条件when驱动) - 触达虚拟终点
__done__时写终态,触达__abort__时转人工
注入自定义图(可选):
# 准备图定义文件(格式见 payload/state-schema.json 中 graph 字段的 schema)
cat > /tmp/my-graph.json <<'EOF'
{
"entry": "plan",
"nodes": [
{"id": "plan", "role": "executor"},
{"id": "build", "role": "executor"},
{"id": "test", "role": "reviewer"}
],
"edges": [
{"from": "plan", "to": "build"},
{"from": "build", "to": "test"},
{"from": "test", "to": "__done__", "when": "approved"},
{"from": "test", "to": "build", "when": "changes_requested"}
]
}
EOF
/graph-task 重构登录模块 单元测试覆盖率 > 80% 并 E2E 通过 --graph /tmp/my-graph.json图定义规则(graph-run.sh 启动时校验,不合法则报错退出):
- 顶层必须含
entry/nodes/edges三字段,缺任一或 JSON 非法即退出。 - 节点
role只能是executor/reviewer/fixer三选一(不创造新角色)。 - 虚拟终点
__done__(完成) /__abort__(转人工)只能作边的to值。 - 边
when缺省 = 无条件顺序边;设了则匹配节点的result决定路由(常见取值approved/changes_requested/blocked)。
3. 复盘
/loop-review # 复盘全部任务
/loop-review <状态文件> # 复盘指定任务自检(MOCK)
不接真实 agent,用内置 mock 编排者验证安装/控制流能否收敛(本项目的 npm test 也是这么跑的):
MOCK=1 bash .opencode/loop-task.sh "测试任务" "标准" # 验证 Loop 控制流
MOCK=1 bash .opencode/graph-run.sh "测试任务" "标准" # 验证 Graph 控制流约束与闸门(可配置)
| 项 | 默认值 | 环境变量 | 作用 |
|------|--------|----------|------|
| 最大迭代轮数 | 20 | MAX_ITER | 硬信号:防无限循环 |
| 总预算(秒) | 3600 | BUDGET_S | 硬信号:防超时 |
| 停滞熔断阈值 | 3 | STALL_LIMIT | 连续 N 轮无进展且工作区无改动则终止 |
| 客观校验命令 | (无) | VERIFY_CMD | 配置后每轮脚本亲自跑,退出码 0 才认可 DONE |
| VCS 类型 | auto | LOOP_VCS | auto|git|tfvc|none,影响回滚点建议(变更检测不依赖 VCS) |
覆盖示例:
MAX_ITER=5 BUDGET_S=120 bash .opencode/loop-task.sh "任务" "标准"
# 加客观闸门:编排者写 goal_met 还不够,得 npm test 真的过才算完成
VERIFY_CMD='npm test' bash .opencode/loop-task.sh "修复登录" "登录流程绿灯"
# TFS(TFVC)工作区:显式指定,开跑前会提醒手动 tf shelve 备份
LOOP_VCS=tfvc bash .opencode/loop-task.sh "任务" "标准"
# 硬约束对 Graph 模式同样适用(换 graph-run.sh 即可)
VERIFY_CMD='npm test' bash .opencode/graph-run.sh "修复登录" "登录流程绿灯"依赖
- 目标项目侧:
jq(JSON 处理)- Git Bash: 下载 jq.exe 放入 PATH
- macOS:
brew install jq - Linux:
apt install jq/yum install jq
- agent 工具: opencode / claude code / kilo code 任一(需支持 markdown subagent + Task 委派)
支持的平台
| 平台 | 安装目录 | 子代理工具 | 状态 |
|------|----------|-----------|------|
| OpenCode | .opencode/ | task | ✅ |
| Claude Code | .claude/ | Task | ✅ |
| Kilo Code | .kilo/ | task | ✅ |
| Qwen Code | .qwen/ | 隐式子代理(自动路由) | ✅ |
| CodeBuddy | .codebuddy/ | 隐式子代理(自动路由) | ✅ |
| Qoder | .qoder/ | Agent | ✅ |
Trae / ZCode 采用配置驱动(非 markdown subagent),暂不支持。
架构设计
为什么是两层循环
- 纯脚本驱动(每轮调一个子 agent):硬约束强,但子 agent 之间不共享上下文,且只 opencode 支持外部 CLI 调子 agent
- 纯 prompt 编排(循环全在 prompt 里):覆盖广但硬约束靠 LLM 自觉,易跑飞
- 本工具(两层):外层脚本管硬约束,内层编排者管多 agent 协作——两者兼得
关于"硬约束"的准确边界(别误解):
- 真正硬的只有
MAX_ITER与BUDGET_S(确定性,保证有界性)。progress_delta/goal_met/review都是 agent 自报的软信号,脚本只转述不验真——防“无限跑/超时”,不天然防“跑偏”。- 可用
VERIFY_CMD加客观闸门(脚本亲自跑、退出码 0 才认可 DONE),停滞判定也叠加了“工作区是否真改动”(mtime,不依赖 VCS)。- “共享上下文”仅在单轮编排者进程内;跨轮靠状态文件的
history字段接续。- 安全:executor/fixer 的 bash 受命令白名单约束(opencode/kilo 在
permission.bash逐条 allow + 兜底*: deny,失败方向安全;完整列表见src/install.ts的SAFE_BASH)。白名单刻意不含通用解释器裸调用(node/python— 因-e/-c能执行任意代码架空白名单,需跑脚本请走tsx/pytest/npx等带文件入口的工具)。注意:这是防意外损坏的护栏,不是防恶意 Agent 的沙箱——要防 prompt-injection 触发的破坏性操作,请在隔离主机/容器中运行,不要在开发者工作机上裸跑。开跑前按 VCS(git/tfvc/none)提示回滚点。- 详见 STATE_CONTRACT.md 的“信号硬度”一节。
为什么用 Node CLI + 纯 sh payload
- Node CLI(安装器):npm 发布要求,仅安装时跑一次(渲染占位符 + 复制 payload)
- 纯 sh payload(装到目标项目):agent 调用统一
bash xxx.sh,对 Node 透明,目标项目不依赖 Node
开发
npm install # 装依赖
npm run build # 编译 TS → dist/
npm run typecheck # 类型检查
npm run dev -- --list # 用 tsx 直接跑(开发模式)目录结构
loop-graph-cli/
├── src/ # Node CLI 安装器
│ ├── cli.ts # 入口
│ ├── platforms.ts # 6 家平台配置(opencode/claude/kilo/qwen/codebuddy/qoder)
│ └── install.ts # 渲染 + 复制 payload
├── payload/ # 装到目标项目的资产(纯 sh + jq)
│ ├── statectl.sh # 状态读写 + graph-next
│ ├── loop-task.sh # Loop Engineering 外层
│ ├── graph-run.sh # Graph Engineering 外层(档位 B)
│ ├── loop-review.sh # 复盘命令
│ ├── state-schema.json # 状态 schema(v1 + v2 联合)
│ ├── STATE_CONTRACT.md # 状态契约
│ └── templates/ # agent/command 模板(带 {{占位符}})
│ ├── agents/
│ │ ├── orchestrator.md
│ │ ├── graph-orchestrator.md # 档位 B
│ │ ├── executor.md
│ │ ├── reviewer.md
│ │ └── fixer.md
│ └── commands/
│ ├── loop-task.md
│ ├── graph-task.md # 档位 B
│ └── loop-review.md
└── tests/ # 测试(selfcheck.sh)License
MIT
