Addy Osmani深度解析- Loop Engineering
公众号名称:奇点先锋
作者名称:扶苏
发布时间:2026-06-22 08:00
今天聊聊一个可能会改变你工作方式的东西——Loop Engineering。
Addy Osmani(对,就是那个写了一堆性能优化圣经的大佬)最近写了篇文章,说我们现在应该从”亲自 Prompt AI”升级到”设计让 AI 自己 Prompt 自己的系统”。
听起来很唬人对吧?但他说得有道理。
TL;DR(太长不看):
-
别再一个 turn 一个 turn 地手动引导 AI 了,设计个循环让它自己跑
-
5 个核心组件:定时任务、Worktree 隔离、Skills 技能、MCP 连接器、Sub-agents 子代理
-
但别忘了:你是工程师,不是监工,代码质量还是得你自己把关
Loop Engineering:让 AI 自己给自己打工
Loop Engineering 的核心思想就一句话:别再亲自 Prompt Agent 了,设计一个系统让它自己 Prompt 自己。
Peter Steinberger(对,那个搞 PSPDFKit 的大佬)最近说了句话特别扎心:
“你不应该再亲自 Prompt Coding Agent 了。你应该设计循环(Loop)来 Prompt 你的 Agent。”
Boris Cherny(Anthropic 的 Claude Code 负责人)也说了类似的话:
“我现在都不亲自 Prompt Claude 了。我有循环在跑,它们会 Prompt Claude 并决定下一步做什么。我的工作就是写循环。”
等等,这是不是在说我们要失业了?
别急,往下看。
以前是怎么玩的?
过去两年,我们怎么让 AI 写代码?
-
写个 Prompt
-
给够 Context
-
看 AI 返回啥
-
再写下一个 Prompt
-
重复上述步骤,直到搞定
你就是那个一直拿着工具的人,一个 turn 接一个 turn 地引导 AI。
但这套玩法,可能快过时了。
现在怎么玩?
现在你要做的,是设计一个小系统:
-
自动发现任务
-
把任务分配出去
-
检查完成质量
-
记录哪些做完了
-
决定下一步干啥
然后让这个系统去 Prompt Agent,而不是你亲自上。
我之前写过一篇文章讲”Agent Harness Engineering”(Agent 运行时工程),说的是怎么给单个 Agent 搭建运行环境。再往上是”Factory Model”(工厂模式),说的是怎么搭建一个生产软件的系统。
Loop Engineering 就坐在 Harness 上面那一层。
Harness 是”Agent 跑起来的环境”,Loop 是”让 Harness 自己跑起来,还能定时触发、自动派生小助手、自己喂自己”。
这玩意儿不是早就有了吗?
让我惊讶的是,这其实已经不是什么”工具层面的创新”了。
一年前你想搞个循环,得写一堆 Bash 脚本,然后维护那堆脚本到天荒地老,而且只有你自己能看懂。
现在这些功能直接内置到产品里了。
Steinberger 列出的那些组件,几乎能一一对应到 Codex App 和 Claude Code 上。
一旦你发现两者的结构是一样的,你就不再纠结”哪个工具更好”了,而是开始设计”无论在哪个工具里都能跑”的循环。
五个核心组件,外加一个”记忆”
一个完整的 Loop 需要 5 个东西,再加上一个”记东西的地方”。
先列出来,再一个个讲:
-
Automations(定时任务):按计划自动运行,自动发现和分类任务
-
Worktrees(工作树):让两个 Agent 并行干活时不会互相踩脚
-
Skills(技能):把项目知识写下来,不然 Agent 只能靠猜
-
Plugins / Connectors(插件和连接器):让 Agent 能调用你已经在用的工具
-
Sub-agents(子代理):一个负责想点子,另一个负责检查
-
State(状态):Markdown 文件、Linear Board,或者任何能记住”做了啥、下一步干啥”的东西
[此处插入原图:Addy Osmani 个人照片](AddyOsmani.com - Loop Engineering_files/addy_2022.jpg)
第六个东西听起来很土对吧? 但这就是每个长期运行的 Agent 都需要的把戏——模型每次跑完都会忘光,所以记忆必须存在磁盘上,而不是 Context 里。
Agent 会忘,Repo 不会。
这两个产品现在都有这 6 个东西了。
| 组件 | 在循环中的作用 | Codex App | Claude Code |
|---|---|---|---|
| Automations | 定时发现 + 分类任务 | Automations Tab:选项目、Prompt、频率、环境;结果进 Triage 收件箱;/goal 跑到完成为止 | 定时任务和 Cron、/loop、/goal、Hooks、GitHub Actions |
| Worktrees | 隔离并行任务 | 每个线程内置 Worktree | git worktree、--worktree、子代理的 isolation: worktree |
| Skills | 把项目知识写成文档 | Agent Skills(SKILL.md),通过 $name 或隐式调用 | Agent Skills(SKILL.md) |
| Plugins / Connectors | 连接你的工具 | Connectors(MCP)+ 插件分发 | MCP Servers + 插件 |
| Sub-agents | 想点子 + 验证 | .codex/agents/里的 TOML 定义的子代理 | .claude/agents/里的任务子代理、Agent Teams |
| State | 记录完成了啥 | Markdown 或通过 Connector 连 Linear | Markdown(CLAUDE.md、进度文件)或通过 MCP 连 Linear |
名字可能有点不一样,但能力是一回事。
让我一个个讲,因为细节才是决定循环是稳稳运行还是到处漏水的关键。
🕐 Automations:这是循环的心跳
Automations 是让循环真正”循环”起来的关键,而不是你跑了一次就忘掉的脚本。
在 Codex App 里怎么玩?
在 Automations Tab 里创建一个:
-
选项目
-
写 Prompt
-
设频率
-
选是在本地 Checkout 跑还是后台 Worktree 跑
有发现的跑进 Triage 收件箱,没发现的自动归档——这个设计很贴心。
OpenAI 内部用它干一些无聊的事:
-
每天分类 Issues
-
总结 CI 失败
-
写 Commit Briefings
-
抓上周别人引入的 Bug
而且 Automation 可以调用 Skill,所以你把重复性的东西写成 Skill,Automation 里直接 $skill-name 调用,而不是贴一大坨指令到定时任务里——反正贴了也没人会更新。
在 Claude Code 里怎么玩?
Claude Code 通过 调度(Scheduling)和 Hooks 实现同样的功能:
-
/loop:按固定频率重复运行 Prompt -
Cron 任务:定时跑
-
Hooks:在 Agent 生命周期的某个节点触发 Shell 命令
-
GitHub Actions:合上笔记本后还想继续跑就扔上去
完全一样的思路:定义一个自主任务 → 给它一个节奏 → 发现结果会送到你面前,而不是你到处去查。
还有一个值得知道的”会话内”玩法
/loop 是按节奏重复跑。
/goal 是一直跑直到你写的条件为真,而且每一轮都有一个单独的小模型检查是否完成——写代码的 Agent 不是打分的那个。
你可以这样写:
"test/auth 里的所有测试都通过,并且 Lint 是干净的"
然后走人。
Codex 也有同样的东西,也叫 /goal,它会跨多个 Turn 一直工作,直到一个可验证的停止条件成立,还能暂停、恢复、清除。
同一个玩法,两个工具都有——这也是整篇文章要说的模式。
所以这部分是”把工作找出来”,剩下的 Loop 是”对它采取行动”。
🌳 Worktrees:别让并行变成灾难
当你跑多个 Agent 的那一刻,文件冲突就成了头号问题。
两个 Agent 写同一个文件,和两个工程师提交同一行代码没区别——只要没沟通,就是灾难。
Git Worktree 就是来救火的。
它是一个独立的工作目录,在自己的分支上,但共享同一个 Repo 的历史——所以一个 Agent 的修改物理上就不可能碰到另一个 Agent 的 Checkout。
Codex App
Codex 把 Worktree 支持直接内置了,所以多个线程可以同时搞同一个 Repo 而不会互相撞车。
Claude Code
Claude Code 给你三种方式:
-
git worktree:手动创建 -
--worktree:启动会话时直接开一个独立 Checkout -
isolation: worktree:贴在子代理上,每个小助手都会拿到一个全新的 Checkout,跑完自动清理
我之前写过一篇文章讲”Orchestration Tax”(编排税),Worktree 解决了物理上的冲突,但你还是那个天花板——你的 Review 带宽决定了你能跑多少个,而不是工具。
📚 Skills:别再每次解释你的项目了
Skill 让你不用再每次开会都重复解释项目背景——你以为你是金鱼吗?
两个工具用的是一样的格式:
-
一个文件夹
-
里面有个
SKILL.md,写指令和元数据 -
可选的脚本、参考文档、资源
Codex App
通过 $ 或 /skills 调用一个 Skill,或者你的任务和 Skill 描述匹配时自动调用——这就是为什么一个紧凑、无聊的描述比花里胡哨的描述更好用。
Claude Code
完全一样的玩法,我之前在”Agent Skills”那篇文章里详细讲过。
Skills 是”意图不再反复付费”的关键。
我在”Intent Debt”(意图债务)那篇文章里说过:Agent 每次启动都是冷启动,它会用”自信的一猜”填补你意图里的任何空洞。
Skill 就是把意图写在外面:
-
约定俗成的规范
-
构建步骤
-
“我们之所以不这么做,是因为那次事故……”
写一次,Agent 每次跑都会读。
没有 Skills,循环每个周期都要从零推导你的整个项目。
有了 Skills,知识就能复利式积累。
⚠️ 一个要分清楚的事:Skill 是”编写格式”,Plugin 是”分发格式”。当你想跨 Repo 分享 Skill,或者把几个 Skill 打包,就打包成 Plugin。Codex 和 Claude Code 都是这样。
🔌 Plugins / Connectors:循环终于能摸到你真正的工具了
一个只能看到文件系统的循环,是个小循环。
Connectors(基于 MCP 构建)让 Agent 能:
-
读你的 Issue Tracker
-
查数据库
-
调 Staging API
-
往 Slack 发消息
Codex 和 Claude Code 都说 MCP 协议,所以你为其中一个写的 Connector,通常直接就能在另一个里跑。
Plugins 把 Connectors 和 Skills 打包在一起,你队友一键安装,而不是从零开始凭记忆重建整套东西。
这就是”Agent 只会说’这是修复方案‘“和”循环自己开 PR、关联 Linear Ticket、CI 绿了之后自动 Ping 频道”的区别。
Connectors 让循环能在你的真实环境里行动,而不是只能告诉你”如果我能做的话我会怎么做”。
👥 Sub-agents:写代码的和检查代码的必须分开
循环里最有用的结构,莫过于把”写代码的”和”检查代码的”分开。
写代码的模型给自己打分,通常都太”善良”了。
第二个 Agent,带着不同的指令,有时候用不同的模型,能抓到第一个 Agent 自己说服自己的那些东西。
Codex App
只有在你明确要求时才会派生子代理,并行运行,然后把结果合并成一个答案。
在 .codex/agents/ 里用 TOML 文件定义你自己的 Agent:
-
名字
-
描述
-
指令
-
可选的模型和推理力度
所以你的安全审查员可以用强模型 + 高推理力度,而探索型 Agent 可以是个快速的只读小东西。
Claude Code
在 .claude/agents/ 里用子代理,还有 Agent Teams 让它们之间传递任务。
两个工具里常见的分工:
-
一个 Agent 探索
-
一个 Agent 实现
-
一个 Agent 对照需求验证
我之前已经两次讲过这个观点——“Code Agent Orchestra”(代码代理交响乐团)和”Adversarial Code Review”(对抗式代码审查)。
为什么这在循环里特别重要?
因为循环是在你不看的时候跑的,一个你真正信任的验证器,是你敢走开的唯一原因。
Sub-agents 确实会烧更多 Token,因为每个都要做自己的模型调用和工具调用——所以要把 Token 花在”第二个意见真的值得付费”的地方。
这也基本就是 Claude Code 的 /goal 在底层干的事:一个全新的模型来决定循环是否完成,而不是干活的那个模型——制造者和检查者的分离,应用到了停止条件本身上。
🎯 一个完整的 Loop 长什么样?
把所有东西拼起来,一个线程就变成了一个小小的控制面板。
这是一个我一直在用的形态:
-
每天早上,一个 Automation 在 Repo 上跑
-
它的 Prompt 调用一个 Triage Skill,读取:
-
昨天的 CI 失败
-
开放的 Issues
-
最近的 Commits
-
把发现写进 Markdown 文件或 Linear Board
-
对每个值得做的发现:
-
开一个隔离的 Worktree
-
派一个 Sub-agent 起草修复
-
派第二个 Sub-agent 对照项目 Skills 和现有测试审查这个草稿
-
Connectors 让循环能开 PR、更新 Ticket
-
循环处理不了的东西,进你的 Triage 收件箱
-
State 文件是整条线的脊柱:
-
记住了什么试过
-
什么通过了
-
什么还开着
-
所以明天早上的运行会从今天停下的地方继续
看看你实际做了什么。
你设计了一次。
你没有 Prompt 任何一个步骤。
这就是 Steinberger 的整段话变成现实的样子,而且在 Codex 和 Claude Code 里是同一条循环——因为组件是一样的。
⚠️ 循环还不会替你做的事
循环改变了工作,但没有把你从工作中删除。
而且随着循环越来越强,有 3 个问题会变得更尖锐,而不是更轻松。
1. 验证还是得你来
一个无人值守的循环,也是一个无人值守犯错的循环。
你把验证 Sub-agent 和制造 Sub-agent 分开,就是为了循环的”完成了”真的有意义——
但即便如此,“完成”是一个声明,不是一个证明。
我一直在重复 AI 时代代码审查里的那句话:
你的工作,是交付你确认过能跑的代码。
2. 你的理解还是会腐烂
循环交付你没写过的代码的速度越快,存在的东西和你真正理解的东西之间的鸿沟就越大。
这就是”Comprehension Debt”(理解债务)。
一个顺滑的循环只会让它长得更快——除非你会去读循环产出的东西。
3. 舒适的姿势最危险
当循环自己跑起来,你很容易就不再有自己的观点,直接接受它给的任何东西。
我称之为 Cognitive Surrender(认知投降)。
设计循环,如果是带着判断力做的,是解药;如果是为了逃避思考做的,就是加速剂——同样的动作,相反的结果。
🔥 搭建循环,但别丢了工程师的身份
我认为这是我们工作方式演进的一个预览。
话说回来,如果我自己不 Review 代码,或者完全依赖自动循环去修复,我的产品质量会下滑。我大概率会陷入一个恶性循环,不断给自己挖更深的坑。
所以,去搭建你的循环吧,但也别忘了:直接 Prompt Agent 也是有效的。
关键是找到平衡点。
同样的循环,不同的结局
同样一条循环,两个人搭出来,结果可能完全相反。
一个人用它来加速自己深度理解的工作。
另一个人用它来逃避理解工作本身。
循环不知道区别。你知道。
这就是为什么 Loop Design 比 Prompt Engineering 更难,而不是更简单。
Cherny 的观点不是说工作变轻松了。
是杠杆点移动了。
搭建循环吧。
但要像一个”打算继续当工程师”的人那样去搭建,而不是一个”只想按开始键”的人。
内容效果不满意?点此反馈