
Google 工程师 Addy Osmani 前几天发布了一篇博文:Loop Engineering,文章讨论的是 coding agent 使用方式的一次变化:当 Claude Code、Codex 已经具备 automations、worktrees、skills、connectors、sub-agents 和外部记忆,人类需要设计能持续运行的闭环,让系统自己发现任务、分发任务、验证结果,再把需要人处理的问题交回来,以下是全文翻译。

Loop Engineering 正在取代你亲自给 Agent 写提示词这件事。你设计一个系统,让这个系统替你去提示 Agent。这里的 loop 可以理解为一种递归目标:你定义一个目的,AI 持续迭代,直到任务完成。我认为,这可能是我们未来与 coding agents 协作的方式。
不过,现在还很早。我依然保持怀疑,而且你绝对需要小心 token 成本,因为不同使用模式下的成本差异可能非常大。所以我想展开讲讲,它到底是什么,以及它意味着什么。
Peter Steinberger 最近说:“你不应该再继续提示 coding agents 了。你应该设计 loops,让 loops 去提示你的 agents。”

类似地,Anthropic 的 Claude Code 负责人 Boris Cherny 也说过:“我现在不再提示 Claude 了。我有一些 loops 在运行,它们会提示 Claude,并判断接下来该做什么。我的工作是写 loops。”
好,那这些话到底是什么意思?
过去大概两年里,如果你想从 coding agent 那里得到结果,通常就是写一个好的 prompt,再提供足够上下文。你输入一句话,读它返回的内容,然后再输入下一句。Agent 是一个工具,而你一直握着这个工具,一轮接一轮地驱动它。这个阶段基本快结束了,至少有些人认为它快结束了。
现在,你会搭一个小系统。这个系统会发现工作、分发工作、检查工作、记录已经完成的事,然后决定下一步;你让这个系统去“戳” agents,而不是你自己去戳。我之前写过一个与它相近的概念:agent harness engineering,也就是为单个 agent 运行所设计的环境;还写过 factory model,也就是构建软件的系统。Loop engineering 位于 harness 之上。
它像是一个 harness,但它会按定时器运行,会生成小助手,还会自己把自己喂起来。
让我意外的是,这件事已经不再只是工具问题。一年前,如果你想要一个 loop,你需要写一堆 bash,然后永远维护那堆东西;它是你的,也只属于你。现在,这些组件已经开始内置在产品里。Steinberger 列出来的东西,几乎可以一一映射到 Codex app;再看 Claude Code,也差不多能对应上。
一旦你意识到它们的形状是一样的,你就会停止争论到底该用哪个工具,而是去设计一个 loop,让它无论落在哪个工具里都能工作。
五个组件,以及一些说明
一个 loop 需要五样东西,然后还需要一个地方来记住事情。先列出来,再逐项对应。

- Automations:按计划自动触发,自己做发现和分诊。
- Worktrees:让两个并行工作的 agents 不会互相踩到。
- Skills:写下项目知识,否则 agent 只能自己猜。
- Plugins 和 connectors:把 agent 接到你已经在用的工具里。
- Sub-agents:让其中一个负责提出想法,另一个负责检查。
然后是第六样东西:memory。它可以是一个 Markdown 文件,也可以是 Linear board,或者任何存在于单次对话之外、用来保存“已经做了什么”和“下一步是什么”的东西。听起来简单到有点傻,但这是所有长期运行 agent 都依赖的同一个技巧。我在 long-running agents 里也写过:模型在不同运行之间会忘掉一切,所以 memory 必须在磁盘上,而不是在上下文里。Agent 会忘,repo 不会。
现在,这两款产品都已经具备这五个组件。
| 基础组件 | loop 中的作用 | Codex app | Claude Code |
|---|---|---|---|
| Automations | 按计划做发现和分诊 | Automations tab:选择项目、prompt、节奏和环境;结果进入 Triage inbox;/goal 用于“运行直到完成” | Scheduled tasks 和 cron、/loop、/goal、hooks、GitHub Actions |
| Worktrees | 隔离并行功能开发 | 每个 thread 内置 worktree | git worktree、--worktree、subagent 上的 isolation: worktree |
| Skills | 固化项目知识 | Agent Skills(SKILL.md),可用 $name 调用,也可隐式调用 | Agent Skills(SKILL.md) |
| Plugins / connectors | 连接你的工具 | Connectors(MCP)加上用于分发的 plugins | MCP servers 加 plugins |
| Sub-agents | 负责构思和验证 | 在 .codex/agents/ 里定义为 TOML 的 Subagents | .claude/agents/ 里的 Task subagents、agent teams |
| State | 跟踪已经完成的事 | 通过 connector 写入 Markdown 或 Linear | Markdown(AGENTS.md、progress files)或通过 MCP 写入 Linear |
名字在不同地方略有差别,但能力本质上是一回事。下面我逐项说,因为坦白讲,细节决定一个 loop 是真正站得住,还是悄悄到处漏水。
Automations,这是心跳
Automations 让一个 loop 成为真正的 loop,而不是你曾经手动跑过的一次任务。在 Codex app 里,你可以在 Automations tab 里创建一个 automation,选择项目、要运行的 prompt、运行频率,以及它是在本地 checkout 里跑,还是在后台 worktree 里跑。能发现问题的运行会进入 Triage inbox;没有发现问题的运行会自己归档,这一点挺好。
OpenAI 内部会用它做一些无聊但有用的事,比如每日 issue 分诊、总结 CI 失败、写 commit briefing、寻找上周某人引入的 bug。automation 还可以调用 skill,所以你可以让 recurring task 保持可维护:触发 $skill-name,而不是把一大墙说明粘进一个以后没人会更新的定时任务里。
Claude Code 通过 scheduling 和 hooks 到达同一个地方。你可以用 /loop 按间隔运行一个 prompt 或 command,可以安排 cron task,可以在 agent 生命周期的某些点用 hooks 触发 shell commands,也可以把整件事推到 GitHub Actions 上,这样即使你合上电脑,它也能继续跑。思路完全一样:定义一个自主任务,给它一个节奏,然后让发现结果来到你这里,而不是由你到处检查。
还有一个值得知道的 in-session primitive,它更接近这篇文章要讲的重点。/loop 会按节奏重新运行。/goal 会持续工作,直到你写下的条件真正成立;每一轮之后,一个独立的小模型会检查任务是否完成,所以写代码的 agent 不是给自己打分的人。你可以给它类似“test/auth 里的所有测试通过,并且 lint 干净”这样的条件,然后走开。
Codex 也有同样的东西,也叫 /goal。它会跨多轮持续工作,直到一个可验证的停止条件成立,并支持 pause、resume 和 clear。同一个 primitive,两款工具都有。这基本也是整篇文章的模式。
所以,这一层负责把工作浮出水面。loop 的其他部分负责真正采取行动。
Worktrees,让并行不会变成混乱
当你运行不止一个 agent 时,文件很快就会开始冲突,失败点也会变成这里。两个 agents 同时写同一个文件,和两个工程师没沟通过就提交同几行代码一样麻烦。git worktree 可以解决这个问题:它是一个独立工作目录,拥有自己的分支,同时共享同一个 repo history,所以一个 agent 的编辑不会碰到另一个 agent 的 checkout。
Codex 把 worktree support 直接内置进去,所以多个 threads 可以同时处理同一个 repo,又不会互相撞到。Claude Code 用 git worktree、--worktree flag 以及 subagent 上的 isolation: worktree 设置提供同样的隔离;这样每个 helper 都可以拿到一个 fresh checkout,用完之后自己清理。
我在 the orchestration tax 里写过这件事的人类侧:worktrees 消除了机械层面的冲突,但你仍然是天花板。你的 review bandwidth 决定了你真正能同时跑多少,而不是工具决定。
Skills,让你不用每次都重新解释项目
skill 是一种方式,用来停止每个 session 都像金鱼一样重新解释同一份项目上下文。两款工具都使用同一种格式:一个文件夹,里面有一个 SKILL.md,保存说明和 metadata,然后可以有可选的 scripts、references 和 assets。Codex 可以在你用 $ 或 /skills 调用时运行一个 skill,也可以在任务匹配 skill description 时自动调用;这就是为什么一个紧凑、朴素的 description 往往比一个聪明的 description 更好。Claude Code 也是同样的做法,我在 agent skills 里写过这个模式。
skills 也是 intent 不再反复付费的地方。我在 the intent debt 里说过,agent 每个 session 都是冷启动,它会用自信的猜测填补你意图里的任何空洞。skill 就是把 intent 写在外部:约定、构建步骤、“我们不这么做,因为曾经出过那次事故”。它只写一次,agent 每次运行时都读它。没有 skills,loop 每一轮都会从零重新推导你的整个项目;有了 skills,它会有点像复利一样积累。
有一点需要分清楚:skill 是 authoring format,plugin 是分发方式。当你想跨 repos 共享一个 skill,或者把几个东西打包在一起,就把它们封装成 plugin。Codex 如此,Claude Code 也是如此。
Plugins 和 connectors,让 loop 触碰真实工具
一个只能看到文件系统的 loop 是一个很小的 loop。connectors 基于 MCP 构建,可以让 agent 读取 issue tracker、查询数据库、调用 staging API、在 Slack 里发消息。Codex 和 Claude Code 都支持 MCP,所以你为其中一个写的 connector,通常也可以在另一个里工作。plugins 则可以把 connectors 和 skills 打包在一起,让你的队友一次安装好你的配置,而不是凭记忆重新搭一遍。
这就是“一个 agent 说‘这里是修复方案’”和“一个 loop 自己打开 PR、关联 Linear ticket,并在 CI 绿了之后 ping 频道”之间的区别。connectors 让 loop 能够在你的真实环境里行动,而不是只告诉你如果它能做的话它会怎么做。
Sub-agents,让制作者远离检查者
在 loop 里,最有用的结构性设计,可能就是把写的人和检查的人拆开。写代码的模型给自己作业打分时通常太宽容。第二个 agent 带着不同指令,有时候甚至用不同模型,可以抓到第一个 agent 说服自己相信的那些问题。
Codex 只会在你要求时生成 subagents,它们会同时运行,然后把结果折回到一个答案里。你可以在 .codex/agents/ 里用 TOML 文件定义自己的 agents,每个 agent 有 name、description、instructions,以及可选的 model 和 reasoning effort。所以你的 security reviewer 可以用强模型和 high effort,而 explorer 可以是某个快速的 read-only agent。Claude Code 也用 .claude/agents/ 里的 subagents 和可以传递工作的 agent teams 做同样的事情。
两者中常见的拆分方式都是:一个 agent 探索,一个 agent 实现,一个 agent 根据 spec 验证。
我已经两次讲过这个观点,一次是在 the code agent orchestra,另一次是在 adversarial code review。它在 loop 里特别重要,是因为 loop 会在你没盯着的时候运行,所以一个你真正信任的 verifier,是你能够走开的唯一理由。subagents 确实会消耗更多 token,因为每个 subagent 都有自己的模型和工具工作,所以应该把它们用在第二意见值得付费的地方。
这基本也是 Claude Code 的 /goal 在底层做的事:由一个 fresh model 判断 loop 是否完成,而不是由完成工作的那个模型来判断。maker 和 checker 的拆分,被应用到了停止条件本身。
一个 loop 长什么样
把这些东西拼在一起,一个单独 thread 就会变成一个小型控制面板。下面是我经常使用的一种形态。
每天早上,一个 automation 在 repo 上运行。它的 prompt 会调用一个 triage skill,这个 skill 会读取昨天的 CI 失败、open issues、recent commits,然后把发现写进一个 Markdown 文件或 Linear board。对于每一个值得处理的发现,这个 thread 会打开一个隔离 worktree,并派一个 sub-agent 起草修复;再由第二个 sub-agent 根据项目 skills 和现有测试审查这份草稿。
connectors 让 loop 能打开 PR 并更新 ticket。loop 处理不了的任何事情,都会落到我的 triage inbox。state file 是整件事的脊柱:它记住尝试过什么、什么通过了、还有什么未完成。这样明天早上的运行就能接着今天停止的地方继续。
看一下你实际上做了什么。你只设计了一次。你并没有提示其中任何一步。这就是 Steinberger 的观点落到现实里的样子;而且无论在 Codex 还是 Claude Code 中,它都是同一个 loop,因为组件是同一组组件。
loop 仍然不会替你做什么
loop 改变了工作,但它不会把你从工作里删除。随着 loop 变好,有三个问题实际上会变得更尖锐,而不是更简单。
验证仍然在你身上。无人值守运行的 loop,也是在无人值守地犯错。你把 verifier sub-agent 和 maker 分开,就是为了让 loop 说“完成了”时稍微有点意义;即便如此,“完成”仍然是一个 claim,而不是 proof。我一直重复 code review in the age of AI 里的同一句话:你的工作是交付你确认过能工作的代码。
如果你允许,你自己的理解仍然会腐烂。loop 越快交付那些你没写的代码,你实际理解的东西和真实存在的东西之间的差距就越大。这就是 comprehension debt;一个顺滑的 loop 只会让它增长得更快,除非你去读 loop 做出来的东西。
舒适的姿态也是危险的姿态。当 loop 自己运行时,人很容易停止拥有自己的判断,直接接受它交回来的东西。我把这叫 cognitive surrender。当你带着判断力去设计 loop,它是解药;当你用它来逃避思考,它是加速剂。同一个动作,结果完全相反。
构建 loop。继续做工程师。
我认为这是我们工作方式将如何演进的一次预览。话虽如此,如果我自己不 review 代码,或者完全依赖自动 loops 来修复代码,我产品的质量会受损。我很可能会陷入一个向下螺旋,不断把自己挖进更深的坑里。
所以,去搭建你的 loops,但别忘了,直接提示你的 agents 仍然有效。关键是找到正确的平衡。

loops 的结果也会因人而异。两个人可以搭建完全相同的 loop,却得到完全相反的结果。一个人用它在自己深刻理解的工作上跑得更快;另一个人用它来逃避理解这份工作。loop 分不出差别。你分得出。
这就是为什么 loop design 比 prompt engineering 更难,而不是更简单。Cherny 的观点不是工作变得更容易了,而是杠杆点移动了。
构建 loop。但要像一个打算继续做工程师的人那样构建它,而不是像一个只想按下“开始”的人。
Addy Osmani 是 Google 的软件工程师,工作方向包括 Google Cloud 和 Gemini。
原文链接:https://addyosmani.com/blog/loop-engineering/