循环工程 (Loop Engineering)
建立一个循环:一个自主系统,它会提示代理,这样您就无需手动操作。您只需定义一次目标和停止条件;循环会自行发现工作、执行、检查、记录完成情况,并重复运行,直到目标达成。此技能在您现有项目内部搭建这样一个循环:它会读取您现有的测试、构建和跟踪工作方式,然后使循环适配您的约定,而不是强加通用约定。
一个循环由六个基本原语构成。仅设置目标所需的原语。
| 原语 | 在循环中的角色 | Claude Code 机制 |
|---|---|---|
| 触发器 (Trigger) | 按计划或事件启动每个周期 | /goal(跨轮次工作直到条件满足)、/loop、计划任务、钩子、GitHub Actions |
| 状态 (State) | 循环在周期间的持久记忆 | 一个 markdown 文件 (LOOP.md) 或通过 MCP 连接的问题追踪器 |
| 发现 (Discovery) | 查找本轮需要处理的工作 | 一个分类步骤,读取 CI、问题、差异、队列 |
| 执行者 (Maker) | 执行一个工作单元 | ./claude/agents/ 中的一个子代理 |
| 检查者 (Checker) | 独立验证执行者的工作 | ./claude/agents/ 中的一个不同子代理 |
| 停止条件 (Stop condition) | 结束循环的规则 | 由检查者运行的可验证检查 |
对于任何无人值守运行的循环,请添加一个监视器 (monitor):一个监督代理,它整体监控循环,并在发生偏离目标 (drift)、空转 (spinning) 或超出边界 (crossed bound) 时停止循环。执行者和检查者确保每个项目正确;监视器确保整个循环始终指向目标,这样循环就不会悄悄偏离并运行数小时。
还有两个可选的附加组件:工作树 (worktrees) (git worktree) 隔离并行的执行者,使它们不会编辑相同的文件;MCP 连接器 (MCP connectors) 让循环触及真实工具(打开 PR、更新工单、发布状态)。当目标需要并行性或外部副作用时添加它们。
设置步骤
此操作在现有项目内部运行。调用时请遵循以下步骤。在涉及副作用(计划任务、推送、工单写入、部署)之前请先与用户确认。
-
首先阅读项目。 在搭建任何东西之前,了解仓库:如何运行测试、构建和代码检查(检查
package.json、Makefile、CI 配置、CLAUDE.md);已有哪些约定、现有技能或.claude/agents/;以及工作来自哪里(CI、问题追踪器、待办事项、队列)。循环必须适配此项目。重用其真实的命令和约定,不要发明新的。 -
确定目标和停止条件。 询问用户循环的一个目标和可验证的完成条件(测试退出码为 0、队列为空、零失败检查)。没有停止条件的循环是绝对不能交付的。如果用户无法指定,则设置一个有边界的备选方案(在 N 个周期后停止),并明确说明。在 Claude Code 中,
/goal <condition>使之可执行:Claude 会跨轮次持续工作,直到条件满足,而/goal clear则提前结束。 -
编写状态文件。 将
${CLAUDE_SKILL_DIR}/templates/LOOP.md复制到仓库根目录,并填入目标、停止条件、节奏和人工门禁。它包含三个由循环维护的动态部分:## Open(已找到,未完成)、## Done(附有验证证据)、## Blocked(需要人工介入),以及一个## Rules部分,其中包含循环中每个代理都遵守的常设指令集。循环在每个周期最先读取此文件,最后写入。 -
创建执行者子代理。 将
${CLAUDE_SKILL_DIR}/templates/loop-maker.md复制到.claude/agents/loop-maker.md,并将其指向您在步骤 1 中找到的约定和测试命令。它只处理## Open中的一个项目,遵循项目现有的技能和约定,并且从不标记自己的工作为已完成。如果同名文件已存在,则更新而非盲目覆盖。 -
创建检查者子代理。 将
${CLAUDE_SKILL_DIR}/templates/loop-checker.md复制到.claude/agents/loop-checker.md。它是一个与执行者不同的代理,它运行项目实际的验证(来自步骤 1 的真实测试、构建或代码检查命令,而不是对其的描述),并且它是唯一允许将项目移到## Done的代理。 -
创建监视器子代理(建议用于任何无人值守循环)。 将
${CLAUDE_SKILL_DIR}/templates/loop-monitor.md复制到.claude/agents/loop-monitor.md,并每隔几个周期或按比循环更慢的计时器运行它。它监控整个循环而非单个项目:它检查循环是否仍在收敛于目标,并在出现偏离(工作不为目标服务)、空转(无净进展,项目在 Open 和 Blocked 之间来回)或超出边界时停止循环并向人工上报。这就是阻止循环悄悄偏离并运行数小时的关键。 -
设置代码审查和安全审计的节奏(询问用户)。 询问用户循环应该以何种频率运行审查,并将两者记录在
LOOP.md中。提供清晰的选项,并始终包含从不 (never):- 代码审查 (
/code-review):每次变更时、每次 PR 或合并之前、每 N 个周期、每周、或从不。 - 安全审计 (
/security-review):每次变更时、每次 PR 或合并之前、每周、每月、或从不。
在选定的节奏下,循环运行内置的检查,并将其发现作为新工作项归档到
## Open中,以便执行者修复、检查者验证修复。如果用户选择了“从不”,则完全跳过该检查,并在LOOP.md中记录“从不”,这样循环就不会重新引入它。 - 代码审查 (
-
定义发现机制。 编写分类步骤,从该项目实际工作所在的位置(CI 状态、未解决的问题、最近的提交、工作队列)填充
## Open,并描述如何将发现转化为离散的、可独立检查的项目。尽可能使其确定。 -
选择隔离(可选)。 如果一个周期要运行多个执行者,为每个执行者分配一个独立的
git worktree和分支,这样它们就不会写入相同的文件。每个项目一个工作树。 -
连接连接器(可选)。 如果循环必须打开 PR、更新工单或发布状态,请连接相应的 MCP 服务器。否则,循环的输出保持本地,由人工传递。
-
设置触发器。 选择适合节奏的最轻量级机制:
- 在当前会话中持续运行直到目标达成 →
/goal <stop condition>(Claude 跨轮次工作直到条件为真;/goal clear提前结束) - 按节奏重复,按需触发 →
/loop - 周期性和无人值守 → 计划任务(或 cron / GitHub Action 用于 CI 侧的循环)
- 响应事件(推送、PR、文件变更)→ 钩子或 GitHub Action
在创建任何计划任务前与用户确认。
- 在当前会话中持续运行直到目标达成 →
-
试运行、验证、然后启用。 手动运行一个周期。读取它产生的所有内容。确认检查者确实阻止了错误的输出,并且状态已被写入。然后才能打开触发器。
约束(不可协商)
- 检查者永远不是执行者。 编写代码的代理不能声明其代码正确。
- 停止条件是可验证的,而非凭感觉。 “看起来完成了”不是停止条件。退出码为 0 的命令才是。
- 每个周期都写入状态。 如果循环忘记了它尝试过什么,它就会重复自己。模型会忘记;文件不会。
- 任何不可逆操作都必须有人工门禁。 发布、部署、删除、花钱。循环起草,人工确认。无人值守的循环会犯无人值守的错误。
- 阻塞优于猜测。 当循环无法验证或无法继续时,它将写入
## Blocked并停止处理该项目。它不会交付一个猜测。 - 长时间运行的循环必须受到监视和限制。 任何无人值守的循环都配有监视器和边界。如果它偏离目标或超出边界,监视器将停止它并上报。循环永远不能朝错误方向无限运行。
循环设置完成后的目录结构
your-project/
├── LOOP.md # 目标、停止条件、边界、规则、Open/Done/Blocked
├── .claude/
│ └── agents/
│ ├── loop-maker.md # 执行一个工作单元
│ ├── loop-checker.md # 独立验证工作
│ └── loop-monitor.md # 监控整个循环,防止偏离和失控
└── (触发器: /goal, /loop, 计划任务, 或 GitHub Action)
反模式:切勿交付这些
- 没有停止条件的循环(永远运行,消耗令牌)。
- 由同一个代理编写并评价自己的作业。
- 没有状态文件的循环(重新推导一切,重复工作,忘记失败原因)。
- 没有监视器或边界的无人值守循环(偏离目标并运行数小时才被发现)。
- 无人值守的发布,且没有针对不可逆操作的人工门禁。
- 一个循环承载许多不相关的工作。一个循环,一个目标,一个停止条件。其余的分拆成各自的循环。
此技能包含的文件
templates/LOOP.md:要复制到目标仓库的状态文件。templates/loop-maker.md:执行者子代理定义。templates/loop-checker.md:检查者子代理定义。templates/loop-monitor.md:监视器子代理定义(偏离和失控防护)。examples/keep-ci-green.md:一个完整的实战循环示例,从目标到触发器。