造一个真的循环:选题、从零搭起来
第一个循环该小到不像个系统。但六个要素里,前两个决定它能不能转,后四个决定它转起来之后会不会闯祸——而新手通常只装前两个。
前三篇是原理。这一篇动手。
先说一句最重要的:Stripe 那套每周合并一千三百个 PR 的流水线,是终点不是起点。 第一个循环应该小到几乎不像个系统 —— 一个按时去看一眼某样东西的小玩意儿。
选题:为什么是这两个
两个特别适合入门的题:客服 agent 和 bug 分诊循环。
它们有一个共同点,而这个共同点正是选题的判据:输入是天然流进来的,而且有现成的判据说对不对。
| 输入从哪来 | 怎么知道做对了 | |
|---|---|---|
| bug 分诊 | CI 失败、新开的 issue、刚合的提交 | 测试能不能跑绿 |
| 客服 | 工单队列、聊天记录 | 问题解没解决、要不要转人工 |
对照着看,不适合当第一个循环的题长什么样:
- 没有稳定输入源的 —— 你还得每天早上告诉它干什么,那就只自动化了「做」,没自动化「找」。而选择做什么,往往才是贵的那部分。
- 没有便宜判据的 —— 比如「优化文案风格」。没有验证器,循环转得越勤,坏东西堆得越多。
- 不可逆动作多的 —— 比如直接改生产数据。第一个循环不该有这种权限。
选题的核心是选一个「有现成 oracle」的领域。 这也是为什么早期成功案例集中在编码、测试、分诊 —— 不是因为它们更重要,是因为它们能被便宜地判对错。验证器决定上限这条规律,在选题这一步就开始起作用了。
从零搭:五步
用 bug 分诊做例子,一步一步加。每一步都能独立跑,不留半成品。
第一步:先让它重复跑
最小的循环就是「按间隔重跑同一件事」。
/loop 5m check the deploy # 固定每 5 分钟/loop check the deploy # 让 agent 自己掌握节奏/loop # 跑 .claude/loop.md 里写的东西这一步之后你有的是「重复」,还不是循环。因为它每次都从同一个地方开始,而且是你告诉它干什么。
第二步:让它自己找活
重跑一行命令不算循环。给它三样东西去看,让它自己列出值得处理的。
关键是:发现逻辑要写成 skill,不要写进定时任务里。
NAME: morning-triageWHEN: 每天早上由自动化触发READ: - 昨天以来失败的 CI 运行 - 24 小时内新开的 issue - 上次运行以来合并的提交JUDGE: 逐条判断值不值得处理,噪音跳过,只留可行动的OUTPUT: 把发现和状态写进 ./state/triage.md(一条一行)为什么必须是 skill 而不是塞进 cron 的一大段指令?因为塞进定时任务里的那堆字,没有人会再去更新它。skill 是能被复用、被维护的一个文件;一大段提示词不是。
定时 + 自己找活,是循环的入门线。
第三步:加状态文件
不要把结果留在对话窗口里。
# ./state/triage.md(循环的记忆)| 发现 | 来源 | 状态 ||--------------|-----------|--------|| auth 测试不稳 | CI #4821 | 修复中 || 空指针 | issue 92 | PR 已开 || 依赖过期 | commit a3 | 待人看 |agent 会忘,仓库不会。 上下文一清空,agent 什么都不记得;而这个文件让明天的那一轮知道今天做到哪儿了。
这一条也是「记忆」和「上下文」的区别:上下文是它这一轮看见的东西,刷新就没;记忆跨轮跨天存在。
第四步:加评估器(最关键,最容易跳过)
前三步做完,你有一个会自己转、有记忆的循环 —— 而它到现在为止,从没说过一次「不行」。
评估器要满足三个条件:
- 是另一个 agent,带完全不同的指令,最好换个模型
- 默认怀疑:一开口就是「我假设这段代码是坏的,除非你证明给我看」
- 要动手,不能只读:真的去点按钮、真的截图、真的看页面变了没有
ROLE: 对抗式代码审查者ASSUME: 这段代码是坏的,直到被证明不是DO NOT: 夸奖
按顺序检查:1. 它能跑吗?(执行,不是阅读)2. 测试:真跑一遍,把真实输出贴出来3. 作者跳过的边界情况4. 行为和工单描述对得上吗
结论:每一条都成立才算 PASS,否则 REJECT 并逐条列出理由停止条件交给一个新的模型判:
/goal all tests in test/auth pass and the lint step is clean为什么必须换一个 agent? 因为写代码的那个,脑子里装的是「我为什么这么写」的一整套理由 —— 它看到的不是结果,是那串说服自己的过程。让作者自我批评很难,让一个外人挑刺很容易。
第五步:并行时加隔离
多个 agent 同时改同一个工作目录,冲突会乱成一团。git worktree 让每个任务有自己的目录。
claude --worktree fix/auth-test "起草修复"claude --worktree fix/null-deref "起草修复"这个问题只在并行时才现形 —— 单 agent 跑得好好的,五个一起上的第一天就炸。
六个要素:前两个让它转,后四个防它闯祸
搭完之后对着这张表检查一遍:
| 要素 | 问自己 |
|---|---|
| 发现来源 | 它定时去读什么?(CI / issue / 提交 / 收件箱) |
| 调度 | 什么东西触发它?不依赖你记得按启动 |
| 状态文件 | 哪个磁盘文件存跨轮记忆? |
| 评估器 | 有没有一个能说「不行」的独立检查? |
| 隔离 | 每个并行 agent 有自己的 worktree 吗? |
| 人工检查点 | 哪一步会停下来等你看,而不是一路自动到底? |
| 预算上限 | 设了花费天花板吗?它跑飞了谁来停? |
前两个决定循环能不能转,后面几个决定它转起来之后会不会闯祸。
而新手最常见的做法是只装前两个就上线 —— 因为那两个能产出看得见的结果。结果是一个没人看着、没人能停、还一直对自己点头的循环。
边界与代价
第一个循环宁可太小。 小到「就检查一件事」都行 —— 但那个能说「不行」的检查和人工检查点,一开始就要装齐。先小后大可以,先没有检查后补很难,因为那时候你已经习惯了它一路绿灯。
skill 有维护成本。 把发现逻辑写成文件,意味着它会过期 —— 项目结构变了、CI 换了,那个文件不会自己更新。它比塞在 cron 里的提示词好,但不是免维护。
worktree 也不是万能的。 它成立的前提是任务能被切成互不重叠的文件级改动。需要细粒度协商的任务,文件级隔离就不够了。
我自己没跑过完整的循环。 我那套东西有 harness、有状态文件、有恢复,但没有定时器 —— 每次还是我去按启动。按这个清单,我装的是「状态文件 + 隔离 + 预算上限」,缺的恰恰是调度和能说不行的评估器。这两格一个让它成为循环,一个让它不闯祸。
下一篇
循环搭起来了,现在它会在你睡觉的时候跑。
最后一篇讲怎么让它安全地跑:错误怎么在轮次之间复利、读进来的材料里藏着指令怎么办、预算和沙箱该怎么设,以及往下走还有什么。