如果你关注 AI 编程领域的动态,你大概率在最近一个月里反复看到同一个词——Loop Engineering。
一切始于 Boris Cherny 的一条推文。这位 Claude Code 的创造者说:"我早就不手动给 Claude 写 prompt 了。我用 loop 来驱动 Claude,由 loop 来决定接下来做什么。我的工作就是写 loop。"紧接着,龙虾(OpenClaw)创始人 Peter Steinberger 跟了一条:"别再给编程 agent 写 prompt 了。你应该设计驱动 agent 的 loop。"两条推文加起来近千万阅读。Addy Osmani(Google Cloud AI 总监)随后发了一篇系统性的长文,正式命名了这个概念,拆解出它的六个核心组件。
整个圈子像被点了一把火——"提示词工程已死""从 Prompt Engineer 到 Meta-Prompt Engineer""Loop Engineering 是下一个必须掌握的技能"——铺天盖地。
概念很性感。但当你真正想用的时候,会发现自己面对的是一个真空——这些文章告诉你 loop engineering 是什么、为什么重要、长什么样,但你找不到一个可以拿过来就用的东西。你能找到的,是散落在 GitHub 上的实验性脚本、个人博客里的思路分享、以及各家公司的内部实践。它们像乐高零件——你知道应该能拼起来,但不知道标准接口在哪。
这篇文章,就是我的拼装尝试。我把 loop engineering 的核心概念落地成了一个可复用的 Skill。
把概念做成 Skill,第一个要面对的问题不是"要不要实现六组件",而是:谁来替你计时计数?
在传统软件工程里,编排多步骤流程需要独立的调度器——一个不受执行体影响的控制器,来计时、计数、判断是否重试。但在 LLM 的世界里,这个调度器不存在。没有 cron 守护进程替你盯着,没有健康检查替你判断,没有 scheduler 替你记次数。Skill 的执行发生在对话上下文中,所有"外部机制"最终都会被 bypass——因为用户和模型之间的交互不可截获。
所以第一个选择题的答案是:不替代模型做决定,而是要求模型在每一次决定中留下可核查的痕迹。
这套设计取向最终凝结成了 四条"防执行幻觉纪律"——它不是对模型行为的某种哲学反思,而是直接写在执行流程里的元认知要求:
这四条纪律贯穿整条流水线的全部生命周期,任何一条被违反,执行报告的可靠性就归零。
这和 Addy Osmani 提出的"Maker-Checker Separation(制作者与检验者分离)"原则一脉相承——写代码的 agent 绝不能给自己打分。但我的处理方式走得更远:不是换一个 sub-agent 来检查就算完,而是在每一层执行中都要求"你既是执行者也是记录者",把自我监督从外部规范变成内部纪律。
整个 Skill 围绕三个核心概念展开:Phase(阶段)、Gate(门禁)、Loop(循环)。它们组合成一个完整的执行闭环:
回到 Addy Osmani 的六组件框架——这个 Skill 与它的对应关系如下:
| 六组件 | Skill 中的落地 | 说明 |
|---|---|---|
| Automations 调度与触发 |
Loop 配置 (from / back_to / trigger / break) |
YAML 中的 loop 字段完整定义了"什么条件下触发→回到哪个阶段→如何跳出" |
| Worktrees 工作隔离 |
未内置,外部接入 | Skill 不强制绑定——由调用方在使用时按需接入 git worktree 或隔离目录 |
| Skills 知识封装 |
type: skill + SKILL.md |
每个 phase 可以声明调用哪个 skill,指令和避坑分离写入 instructions / notes |
| Plugins 工具连接 |
未内置,外部接入 | Skill 依赖对话上下文中已有的 MCP 连接或工具权限,不自行管理插件生命周期 |
| Sub-agents 制作者与检验者分离 |
Gate 的独立 subagent 校验 | Maker-Checker 分离的最严格执行——gate 不得由主流程自判,double_check 防噪声 |
| Memory 状态持久化 |
审计日志 + JSON 文件传递 | audit_log.md 记录执行轨迹,JSON 文件在 phase 之间传递数据,best_of 保留各轮记录 |
六个组件中,四个(Automations / Skills / Sub-agents / Memory)直接落地,两个(Worktrees / Plugins)作为外部基础设施留给了调用方。这不是能力不足,是设计选择——不应该把隔离策略和工具连接绑死在框架里。这个 Skill 不试图完美实现每一个组件,而是做一个最小可用的、完整闭环的框架。
串行适合有明显依赖链路的场景,并行适合多维度独立分析,混合则是现实世界最常见的形态——第一步并行采集多源数据,第二步串行做依赖分析。三种模式通过一个 YAML 字段切换,底层共用同一套 gate + loop 机制。
有一个设计细节在 loop engineering 的讨论中很少被提及,但在实践里非常关键:在混合模式下,如果外循环回到的是一个并行组内的某个 phase,整个并行组都会被重跑。这不是设计失误——并行组内的各 phase 共享下游依赖,只重跑其中一个会造成版本不一致,比多花一次资源更危险。这个取舍在社区讨论中几乎找不到,只有在实际拼装时才会撞上。
Loop engineering 的一个核心理念是 Maker-Checker 分离——做的人和检查的人不能是同一个人。这个理念在这个 Skill 中落地为 Gate 机制。也是整个框架里执行误差最大、最容易流于形式的地方。
Gate 必须以独立 subagent 执行校验,不得由主流程自判。这条规则看起来简单,但它违反直觉——你会有冲动说"我既然在执行,顺手检查一下不就行了吗?"
答案是:不行。同一个推理链条中的自判存在系统性偏差。模型完成一项任务后,紧接着在同一段推理中给它打分,它倾向于认为自己做得不错。这不是恶意,这是认知连贯性的自然结果——就像你让人写一篇文章然后自己审稿,他总能找到理由说自己写得还行。
为了把这个问题说清楚,有必要区分一下"step 内部自检"和"gate 门禁"——很多人把这两个搞混,以为 step 里加一段 self-validation 就算有了质量保障。实际上它们是完全不同的两种机制:
| 维度 | Step 内部自检 | Gate 门禁 |
|---|---|---|
| 执行者 | step 自己在执行过程中顺手检查 | 独立 subagent,与执行 step 的不是同一个体 |
| 检查时机 | step 内部,失败时触发 local_retry | step 完成后,作为独立 phase 执行 |
| 失败后果 | 原地重试(local_retry),输入不变 | 触发外循环(loop),回到前置阶段,携带反馈 |
| 检查范围 | 格式校验、字段完整性等 self-validation | 按 check_list 逐项验真——数据是否准确、逻辑是否自洽、结论是否合理 |
| 独立性 | ❌ 同一推理链条 | ✅ Maker-Checker 分离 |
两者在流水线中各司其职:step 内部自检负责"这件事我做完了没有",gate 负责"这件事做得对不对"——前者是执行完备性的检查,后者是交付质量的裁判。step 自检的结果只影响自己要不要重试一次,而 gate 的判断会决定整条流水线要不要回退重来。
但即使做到了独立 subagent,还有一个更隐蔽的坑——它只防噪声,不防偏差。这是我在文档中反复强调的一点:
这个认知在社区讨论中几乎不存在。大部分人看到"double check"就天然觉得更可信了——但在我这套框架里,double_check 只防随机噪声,不防系统性偏差。你真正需要的是不同 check skill 之间的交叉验证,而不是同一个 check 的多次重复。
Loop engineering 讨论最混乱的地方就是循环本身——while 还是 for?无限迭代还是设上限?每次重试时输入变不变?这些不是概念问题,是设计决策。我的答案是明确的。
很多人第一次接触这个 Skill 时,会把 loop 理解成"失败了就重来一次"。这是误解。重试(retry)是输入不变再试一次,只应对临时问题。但 loop 是带着上一轮的失败反馈回去重新执行。输入变了——因为你知道上次哪里没做好。这个区别至关重要。没有反馈的循环只是在消耗预算,不是在收敛。
这也是为什么 loop 配置中强制要求 strategy 字段必须写明"携带上一轮的未通过项证据和已尝试的修正方式"——这不是一个建议,是一个约束。
同时,循环的终止策略也有一条容易被忽略的设计:不默认"最后一轮最好"。实际执行中,第三轮的结果可能比第二轮差——模型越迭代越疲劳、上下文越长注意力越分散。所以引入了 best-so-far 指针:每轮完成后与历史最优比较,更优才更新指针。循环强制终止时,交付的永远是最优的那一轮,而不是最后一轮。
这正好回应了 loop engineering 社区中的"while loops vs for loops"争论——我的答案是:设上限、加门禁、维护最优指针。让循环收敛,而不是让它跑死。loop 不等于无限循环,这个 Skill 里的每一个 loop 都有明确的终止优先级:目标达成 > 次数耗尽 > 超时 > 成本耗尽 > 用户打断。
这个 Skill 在文档中列出了 7 条已知局限,这里说最关键的几条:
这些局限不是 bug。它们是 Prompt 模板的宿命,也是它诚实的地方——它不假装自己做不到的事情。
在收尾之前,还有一个细节值得单独拿出来说——虽然它在整个框架里最不起眼,但实际影响出乎意料的大。
在这个 Skill 的 YAML schema 中,每一个阶段都有两个文本字段:instructions 和 notes。分工很明确:instructions 答"做什么",notes 答"做的时候要避免什么"。
这个分工最初看起来像是文档洁癖,但实际使用中,它被证明是关键设计。原因是模型读 instructions 时的心态是"我要按步骤来",读 notes 时的心态是"有什么坑需要注意"——同一个问题在两个字段中触发的是不同的认知处理模式。
我把 notes 分为三个层级:Pipeline 级的 notes 管全局约束,Phase 级的 notes 管这一步专属的避坑,Gate 级的 notes 管 check_list 之外的隐性标准。简单来说:instructions 回答"怎么做好",notes 回答"怎么做坏"。
这个设计在 loop engineering 的社区讨论中几乎从没被提过。六组件框架里有 Skills(知识封装),但没有深入到"Skills 内部的 instructions 和 notes 怎么分工"这个粒度。这是我拼装过程中自己发现的重要细节。
回头看第二节那张对应表就知道了——四个组件直接落地,两个留作外部。这个 Skill 的选择一直很明确:不试图完美实现每一个组件,而是做一个最小可用的、完整闭环的拼装版本。
所以它不是一个开箱即用的产品,它是一份模板——你拿走它,根据自己的场景去填充、去扩展、去改造。你可以给它加上工作树隔离,你可以给它接上 Slack 通知,你可以把它的 gate 从单次 subagent 升级为双 Agent 对抗验证。框架不限制你,它只确保你在这个框架里做的每一件事都是可追溯的。
如果你也想试试这套框架,它在 GitHub 上开源了。它不会让你的模型变聪明,但它会让聪明的模型不再做出不可追溯的蠢事。