返回列表
🧠 阿头学 · 💬 讨论题

循环工程范式转移

循环工程是将工程师从提示撰写者升级为系统设计者的必然趋势,但盲目自动化会导致认知债务比代码债务更致命。
打开原文 ↗

2026-06-09 原文链接 ↗
阅读简报
双语对照
完整翻译
原文
讨论归档

核心观点

  • 范式转移 循环工程的核心是将一次性提示替换为具备自动化、工作树、技能、插件和子代理的五件套系统。
  • 状态持久化 代理本质无状态,必须将记忆持久化到磁盘或外部系统才能支撑长周期运行。
  • 对抗性审查 执行者与验证者必须分离,模型自我打分是无效的,必须引入对抗性审查子代理。
  • 认知风险 自动化效率越高,人类对系统的理解债务积累越快,认知投降比 Token 成本更危险。
  • 工具趋同 目前 Claude Code 和 Codex 已内置该范式所需构件,工具之争已让位于系统设计能力之争。

跟我们的关联

  • 对 ATou 意味着工作重心从写 Prompt 转向设计 Agent 架构,下一步应尝试构建包含验证子代理的自动化脚本。
  • 对 Neta 意味着需警惕理解债务,下一步必须在循环中强制加入人工审查节点而非全盘接受输出。
  • 对 Uota 意味着工具链需支持 MCP 连接器,下一步应评估现有工具是否具备工作树隔离能力以避免并行冲突。

讨论引子

  • 当循环能自动修复 Bug 时,工程师如何证明自己仍掌握系统逻辑而非仅仅按下开始按钮?
  • 子代理验证带来的 Token 成本激增,在什么 ROI 阈值下才值得引入对抗性审查机制?
  • 如果工具厂商更改 API 导致循环失效,这种高度绑定的方法论是否构成了新的技术债务?

循环工程,就是把你自己从那个给代理写提示的人,替换成设计提示系统的人。你不再亲自去提示代理,而是去设计那个替你完成这件事的系统。 这里说的循环,可以理解成一种递归式目标。你先定义目的,然后让 AI 持续迭代,直到完成。大致上,它由五个构件组成,而 Claude Code 和 Codex 现在都已经具备这五个构件了。

我认为,这可能会成为未来我们与编码代理协作的方式。不过现在还早,我仍然持怀疑态度,而且你绝对必须小心 token 成本。如果你手头 token 宽裕或紧张,使用模式可能会差得非常夸张。你依然需要某种办法确保质量不会下滑,大家对 slop 的担心也完全合理。话虽如此,还是来看看这件事到底在讲什么。

@steipete 最近说过一句话。你不该再亲自给编码代理写提示了。你应该去设计那些能替你给代理写提示的循环。类似地,Anthropic 的 Claude Code 负责人 @bcherny 也说过,我已经不再亲自给 Claude 写提示了。我让循环去提示 Claude,再由它判断该做什么。我的工作是写循环。

好,所以这些话到底是什么意思。

差不多两年来,想从编码代理那里拿到结果,你的办法一直是写一个好提示,再给足够的上下文。你输入一句,它回一段,你再输入下一句。代理是个工具,而你始终握着这个工具,一轮接一轮。这个阶段差不多结束了,或者至少,有些人认为它快结束了。

现在的做法是,你搭一个小系统,让它自己去找工作,自己分发工作,自己检查,自己记录哪些做完了,然后自己决定下一步做什么。于是,变成这个系统去戳代理,而不是你亲自动手。我之前写过它的近亲,agent harness engineering,也就是给单个代理搭建运行环境,以及 factory model,也就是构建软件的系统。循环工程则在 harness 之上再高一层。还是那个 harness,只不过它按时运行,会生成小帮手,还能自己给自己喂任务。

最让我意外的是,这件事现在已经不太算是工具之争了。一年前,如果你想做一个循环,通常得自己写一大堆 bash,然后永远维护那堆脚本,而且那是你的私产,只属于你。现在,这些部件直接就内置在产品里了。Steinberger 列出的那套东西,几乎和 Codex app 一一对应,然后和 Claude Code 也几乎一一对应。一旦你看出它们形状相同,你就不会再纠结到底选哪个工具了。你只会去设计一个不管自己正坐在哪个工具里都能跑通的循环。

五个部件,再加一些说明

一个循环需要五样东西,再加一个存放记忆的地方。先把它们列出来,再一一对应。

  1. 自动化,按计划触发,自己做发现和分诊。

  2. 工作树,让两个并行工作的代理不会互相踩脚。

  3. 技能,把项目知识写下来,避免代理只能靠猜。

  4. 插件和连接器,把代理接到你已经在用的工具上。

  5. 子代理,让一个负责提出方案,另一个负责检查。

然后第六样,是记忆。可以是一个 markdown 文件,也可以是一个 Linear 面板,任何能活在单次对话之外、能记录什么做完了和下一步是什么的东西都行。听起来笨得不值一提,但所有长时间运行的代理,本质上都靠这招。我在 long-running agents 里写过,模型每次运行之间都会把一切忘掉,所以记忆必须落在磁盘上,而不能只放在上下文里。代理会忘,仓库不会。

现在两个产品都已经有这五样了。

https://addyosmani.com/blog/long-running-agents/

不同地方名字略有差异,但能力本身是同一回事。还是一个个讲,因为说实话,细节才是一个循环到底能不能稳住,还是会悄悄到处漏水的关键。

自动化,这是心跳

自动化让循环真的成为循环,而不是你只跑过一次的一次性任务。在 Codex app 里,你可以在 Automations 标签页里创建自动化,选择项目、要运行的提示、运行频率,以及是在你的本地 checkout 上运行,还是在后台 worktree 里运行。那些发现了问题的运行结果会进入 Triage 收件箱,什么都没发现的运行则会自动归档,这点挺好。OpenAI 内部就拿它做很多枯燥事,比如每天做 issue 分诊,总结 CI 失败,写提交简报,追查上周有人引入的 bug。而且自动化还能调用技能,所以这种重复性事务能保持可维护。你只需要触发 $skill-name,不用把一大墙永远没人更新的指令直接贴进调度任务里。

Claude Code 也能到同一个位置,只不过是通过调度和 hooks。你可以用 /loop 按间隔运行一个提示或命令,可以调度一个 cron 任务,可以在代理生命周期的某些节点用 hooks 触发 shell 命令,或者如果你想让它在你合上笔记本之后还继续运行,也可以把整个东西交给 GitHub Actions。本质完全一样,你定义一个自治任务,给它一个节奏,让发现结果主动回来找你,而不是你到处去检查。

还有第二个值得知道的会话内原语,它和这整篇文章讨论的东西更接近。/loop 会按节奏反复运行。/goal 则会一直持续,直到你写下的某个条件真的成立,而且每一轮结束后,都会由另一个更小的模型来判断你是否完成,所以写代码的那个代理并不是给自己打分的那个。你可以给它一句类似 所有 test/auth 里的测试都通过,而且 lint 干净,然后直接走开。Codex 也有同样的东西,也叫 /goal,它会跨多轮继续工作,直到一个可验证的停止条件成立,还支持暂停、恢复和清除。相同的原语,两个工具都有,这几乎就是整篇文章的模式。

所以,这一部分负责把工作浮出来。循环的其余部分则负责对它采取动作。

工作树,让并行不至于变成混乱

一旦你同时跑不止一个代理,文件就会开始互相冲突,这会变成主要故障。两个代理改同一个文件,和两个工程师同时提交到同几行代码、事先却没打招呼,本质上是一样的头疼。git worktree 能解决这个问题。它是在同一份仓库历史上共享记录、但位于独立分支上的单独工作目录,所以一个代理的修改,从物理上就不可能碰到另一个代理的 checkout。

Codex 直接内建了 worktree 支持,所以多个线程可以同时打到同一个仓库,而不会彼此撞车。Claude Code 也通过 git worktree 提供同样的隔离,你可以用 --worktree 标志把会话开在独立 checkout 里,还可以给子代理加上 isolation: worktree 设置,让每个帮手都拿到一个新的 checkout,做完后再自行清理。我在 orchestration tax 里写过这里面人的那一层问题,worktree 解决的是机械上的碰撞,但真正的上限依然是 YOU。你能实际同时跑多少,不取决于工具,而取决于你的 review 带宽。

技能,让你别再每次都把项目重新解释一遍

技能的作用,是让你别再像金鱼一样,每次开新会话都把同样的项目上下文重新讲一遍。两个工具用的是同一种格式,一个文件夹,里面放一个 SKILL.md,记录说明和元数据,再加上一些可选的脚本、参考资料、资源。Codex 会在你用 $ 或 /skills 调用它时运行技能,或者在任务与技能描述匹配时自行触发,所以那种紧凑、无聊、准确的描述,比聪明花哨的描述更有用。Claude Code 也是同一套方式,我在 agent skills 里专门写过这个模式。

技能也是让意图不再反复烧钱的地方。我在 intent debt 里提过,代理每次开局都是冷启动,而你意图里只要有空洞,它就会用自信满满的猜测把空洞填上。技能,就是把这些意图写在外面。项目约定、构建步骤、我们不这么做是因为那次事故,全都写下来,写一次,以后每次运行代理都会读到。没有技能,循环每一轮都得从零重新推导整个项目。有了技能,它就会开始积累。

有一点要分清。技能是创作格式,插件则是分发方式。当你想跨仓库共享一个技能,或者把几个技能打包在一起时,你会把它们做成插件。Codex 是这样,Claude Code 也是这样。

插件和连接器,让循环碰到你真实在用的工具

一个只能看见文件系统的循环,是个很小的循环。连接器建立在 MCP 之上,它让代理可以读取你的 issue 跟踪系统、查询数据库、访问 staging api、往 Slack 里发消息。Codex 和 Claude Code 都支持 MCP,所以你给一个工具写的连接器,通常在另一个工具里也能直接用。而插件则会把连接器和技能一起打包,这样你的队友一次安装就能把整套配置装好,不用靠记忆把整个东西重建一遍。

这就是一个只会说 这是修复方案 的代理,和一个能自己开 PR、自动关联 Linear ticket、等 CI 绿了再去频道里提醒一声的循环之间的差别。连接器的意义就在于,它让循环能在你的真实环境里采取行动,而不是只告诉你,如果它有权限的话,它本来会怎么做。

子代理,让执行者远离检查者

在一个循环里,最有用的结构设计,毫无疑问就是把负责写的人和负责查的人分开。写代码的那个模型,在给自己作业打分这件事上实在太好说话了。第二个代理,如果指令不同,甚至模型也不同,就能抓住第一个代理自己把自己说服过去的那些问题。

Codex 只有在你要求时才会生成子代理,它们会并行运行,然后把结果合并回一个答案里。你可以把自己的代理定义成放在 .codex/agents/ 里的 TOML 文件,每个代理有名字、描述、指令,以及可选的模型和 reasoning effort,于是你的安全审查员可以是一个高 effort 的强模型,而你的探索器则可以只是个快速的只读工具。Claude Code 也一样,它用 .claude/agents/ 里的子代理和 agent team 在不同代理之间传递工作。两个工具里最常见的分工通常都是,一个代理探索,一个实现,一个对照规格做验证。

这个观点我已经讲过两次了,一次在 code agent orchestra 里,一次在 adversarial code review 里。它之所以在循环里尤其重要,是因为循环会在你不盯着的时候自己跑,所以,只有当你真的信得过那个验证者时,你才有资格走开。子代理确实会烧更多 token,因为每个子代理都会各自做一遍模型调用和工具调用,所以只在那些第二意见确实值得花钱的地方用它们。这其实也基本就是 Claude Code 的 /goal 在底层做的事。由一个新的模型判断循环是否结束,而不是由实际干活的那个来判断。也就是把执行者和检查者的分离,直接应用到了停止条件本身。

一个循环长什么样

把这些拼在一起,单一线程就会变成一个小控制台。下面是我反复在用的一种形状。

每天早上,一个自动化在仓库上运行。它的提示会调用一个分诊技能,读取昨天的 CI 失败、未关闭 issue、最近的提交,然后把发现写进一个 markdown 文件,或者一个 Linear 面板里。对于每个值得处理的发现,这个线程会打开一个隔离的 worktree,派一个子代理去起草修复方案,再派第二个子代理按照项目技能和现有测试去审查这份草案。

连接器让循环自己去开 PR、更新 ticket。凡是循环处理不了的东西,就会落进 Triage 收件箱等我来接。状态文件是整个系统的脊梁,它记得哪些尝试做过、哪些通过了、哪些还开着,所以明天早上的运行会从今天停下的地方继续。

而且你回头看看,自己到底做了什么。你只设计了一次。那些步骤没有任何一步是你亲自写提示去驱动的。这就是 Steinberger 的核心意思变成现实后的样子,而且不管是在 Codex 里还是在 Claude Code 里,这都是同一个循环,因为这些部件本来就是同一批部件。

循环仍然不能替你做的事

循环会改变工作的形态,但它不会把你从工作里删掉。而且有三个问题,随着循环变强,只会变得更尖锐,不会变得更轻松。

验证依然是你的责任。一个无人看管的循环,也同样是一个会在无人看管时犯错的循环。之所以要把验证子代理和执行子代理分开,就是为了让循环嘴里的 已完成 真的有点分量。可就算这样,已完成 也只是一种声称,不是证明。我在 code review in the age of AI 里反复说过同一句话,你的工作,是交付那些你亲自确认过能工作的代码。

如果你放任不管,你的理解依然会腐烂。循环交付代码越快,而那些代码又不是你亲手写的,那么已经存在的东西和你真正理解的东西之间的裂缝就会越大。这就是 comprehension debt。一个顺滑的循环,只会让它长得更快,除非你真的去读循环产出的东西。

而且,说实话,那种舒服的姿态大概才是更危险的。当循环能自己跑起来时,人太容易不再持有判断,只把它吐回来的东西全盘接受。我把这叫做 cognitive surrender。设计循环,如果你是带着判断力在做,它会是解药。如果你是为了逃避思考才去做,它就会变成催化剂。动作一样,结果相反。

搭起循环。继续当工程师。

我觉得,这很像我们未来工作方式会如何演变的一次预演。不过,话说回来,如果不是我自己在看代码,或者如果我完全依赖自动化循环去修代码,那我的产品质量一定会下滑。最后很可能会掉进一个向下螺旋,持续把自己越挖越深。

即便如此,循环还是值得搭,但别忘了,直接给代理写提示依然有效。关键在于找到合适的平衡。

循环带来的结果,也会因为人不同而不同。两个人可以搭出完全一样的循环,最后却得到截然相反的结果。一个人用它加速自己本就理解很深的工作。另一个人用它来逃避理解工作本身。循环看不出差别。你看得出。

这正是为什么循环设计比提示工程更难,而不是更简单。Cherny 的意思不是工作变轻松了,而是杠杆点变了。

搭起循环。但要像一个打算继续当工程师的人那样去搭,而不是像一个只负责按下开始按钮的人。

Loop engineering is replacing yourself as the person who prompts the agent. You design the system that does it instead. A loop here can be thought of a recursive goal where you define a purpose and the AI iterates until complete. It's roughly five building blocks and Claude Code and Codex both have all five now.

循环工程,就是把你自己从那个给代理写提示的人,替换成设计提示系统的人。你不再亲自去提示代理,而是去设计那个替你完成这件事的系统。 这里说的循环,可以理解成一种递归式目标。你先定义目的,然后让 AI 持续迭代,直到完成。大致上,它由五个构件组成,而 Claude Code 和 Codex 现在都已经具备这五个构件了。

I believe this may be the future of how we work with coding agents. However, its still early, I'm skeptical and you absolutely have to be careful about token costs (usage patterns can vary wildly if you are token rich or poor). You also still need some way to ensure quality doesn't drop and concerns re: slop are valid. That said, let's explore what this is all about.

我认为,这可能会成为未来我们与编码代理协作的方式。不过现在还早,我仍然持怀疑态度,而且你绝对必须小心 token 成本。如果你手头 token 宽裕或紧张,使用模式可能会差得非常夸张。你依然需要某种办法确保质量不会下滑,大家对 slop 的担心也完全合理。话虽如此,还是来看看这件事到底在讲什么。

@steipete recently said: “You shouldn't be prompting coding agents anymore. You should be designing loops that prompt your agents.” Similarly, @bcherny, head of Claude Code at Anthropic, said “I don't prompt Claude anymore. I have loops running that prompt Claude and figuring out what to do. My job is to write loops”.

@steipete 最近说过一句话。你不该再亲自给编码代理写提示了。你应该去设计那些能替你给代理写提示的循环。类似地,Anthropic 的 Claude Code 负责人 @bcherny 也说过,我已经不再亲自给 Claude 写提示了。我让循环去提示 Claude,再由它判断该做什么。我的工作是写循环。

Okay, so what does any of that mean?

好,所以这些话到底是什么意思。

For like two years the way you got something out of a coding agent was you wrote a good prompt and shared enough context. You type a thing, you read what came back, you type the next thing. The agent is a tool and you are holding it the entire time, one turn after the other. That part is kind of over, or at least some think it's going to be.

差不多两年来,想从编码代理那里拿到结果,你的办法一直是写一个好提示,再给足够的上下文。你输入一句,它回一段,你再输入下一句。代理是个工具,而你始终握着这个工具,一轮接一轮。这个阶段差不多结束了,或者至少,有些人认为它快结束了。

Now you build a small system that finds the work, hands it out, checks it, writes down what is done and then decides the next thing, and you let that system poke the agents instead of you. I wrote before about the cousin of this, agent harness engineering, which is making the environment one single agent runs inside and the factory model - the system that builds the software. Loop engineering sits one floor above the harness. The harness but it runs on a timer, it spawns little helpers, and it feeds itself.

现在的做法是,你搭一个小系统,让它自己去找工作,自己分发工作,自己检查,自己记录哪些做完了,然后自己决定下一步做什么。于是,变成这个系统去戳代理,而不是你亲自动手。我之前写过它的近亲,agent harness engineering,也就是给单个代理搭建运行环境,以及 factory model,也就是构建软件的系统。循环工程则在 harness 之上再高一层。还是那个 harness,只不过它按时运行,会生成小帮手,还能自己给自己喂任务。

The thing that surprised me is this is not really a tool thing anymore. A year ago if you wanted a loop you wrote a pile of bash and you maintained that pile forever and it was yours and only yours. Now the pieces just ship inside the products. Steinberger's list maps almost exactly onto the Codex app, and then almost the same onto Claude Code. And once you notice the shape is the same you stop arguing about which tool, you just design a loop that still works no matter which one you happen to be sitting in.

最让我意外的是,这件事现在已经不太算是工具之争了。一年前,如果你想做一个循环,通常得自己写一大堆 bash,然后永远维护那堆脚本,而且那是你的私产,只属于你。现在,这些部件直接就内置在产品里了。Steinberger 列出的那套东西,几乎和 Codex app 一一对应,然后和 Claude Code 也几乎一一对应。一旦你看出它们形状相同,你就不会再纠结到底选哪个工具了。你只会去设计一个不管自己正坐在哪个工具里都能跑通的循环。

The five pieces, and then notes

五个部件,再加一些说明

A loop needs five things and then one place to remember stuff. Let me list it first and then map it.

一个循环需要五样东西,再加一个存放记忆的地方。先把它们列出来,再一一对应。

  1. Automations that go off on a schedule and do discovery and triage by themselves.
  1. 自动化,按计划触发,自己做发现和分诊。
  1. Worktrees so two agents working in parallel dont step on each other.
  1. 工作树,让两个并行工作的代理不会互相踩脚。
  1. Skills to write down the project knowledge the agent would otherwise just guess.
  1. 技能,把项目知识写下来,避免代理只能靠猜。
  1. Plugins and connectors to plug the agent into the tools you already use.
  1. 插件和连接器,把代理接到你已经在用的工具上。
  1. Sub-agents so one of them has the idea and a different one checks it.
  1. 子代理,让一个负责提出方案,另一个负责检查。

Then the sixth thing, the memory. A markdown file, or a Linear board, anything that lives outside the single conversation and holds what's done and what is next. Sounds too dumb to matter. But it's the same trick every long running agent depends on and I went into it in long-running agents, the model forgets everything between runs so the memory has to be on disk and not in the context. The agent forgets, the repo doesnt.

然后第六样,是记忆。可以是一个 markdown 文件,也可以是一个 Linear 面板,任何能活在单次对话之外、能记录什么做完了和下一步是什么的东西都行。听起来笨得不值一提,但所有长时间运行的代理,本质上都靠这招。我在 long-running agents 里写过,模型每次运行之间都会把一切忘掉,所以记忆必须落在磁盘上,而不能只放在上下文里。代理会忘,仓库不会。

Both products have all five now.

现在两个产品都已经有这五样了。

The names are a bit different here and there but the capability is the same thing. Let me go one by one because honestly the details are where a loop either holds together or quietly leaks everywhere.

不同地方名字略有差异,但能力本身是同一回事。还是一个个讲,因为说实话,细节才是一个循环到底能不能稳住,还是会悄悄到处漏水的关键。

Automations, this is the heartbeat

自动化,这是心跳

Automations are what make a loop an actual loop and not just one run you did once. In the Codex app you make one in the Automations tab and you pick the project, the prompt it will run, how often, and if it runs on your local checkout or on a background worktree. The runs that find something go to a Triage inbox, and the runs that find nothing just archive themselves which is nice. OpenAI uses them internally for boring stuff like daily issue triage, summarizing CI failures, writing commit briefings, hunting bugs somebody added last week. And an automation can call a skill, so you keep the recurring thing maintainable, you fire $skill-name instead of pasting a giant wall of instructions into a schedule that nobody will ever update.

自动化让循环真的成为循环,而不是你只跑过一次的一次性任务。在 Codex app 里,你可以在 Automations 标签页里创建自动化,选择项目、要运行的提示、运行频率,以及是在你的本地 checkout 上运行,还是在后台 worktree 里运行。那些发现了问题的运行结果会进入 Triage 收件箱,什么都没发现的运行则会自动归档,这点挺好。OpenAI 内部就拿它做很多枯燥事,比如每天做 issue 分诊,总结 CI 失败,写提交简报,追查上周有人引入的 bug。而且自动化还能调用技能,所以这种重复性事务能保持可维护。你只需要触发 $skill-name,不用把一大墙永远没人更新的指令直接贴进调度任务里。

Claude Code gets to the same place but through scheduling and hooks. You can run a prompt or a command on a interval with /loop, you can schedule a cron task, you can fire shell commands at certain points in the agent lifecycle with hooks, or you push the whole thing to GitHub Actions if you want it to keep running after you close the laptop. Same idea exactly, you define an autonomous task, you give it a cadence, and the findings come to you so you are not the one going around checking.

Claude Code 也能到同一个位置,只不过是通过调度和 hooks。你可以用 /loop 按间隔运行一个提示或命令,可以调度一个 cron 任务,可以在代理生命周期的某些节点用 hooks 触发 shell 命令,或者如果你想让它在你合上笔记本之后还继续运行,也可以把整个东西交给 GitHub Actions。本质完全一样,你定义一个自治任务,给它一个节奏,让发现结果主动回来找你,而不是你到处去检查。

There is a second in-session primitive worth knowing, and it's the one closer to what this whole post is about. /loop re-runs on a cadence. /goal keeps going until a condition you wrote is actually true, and after every turn a separate small model checks whether you are done, so the agent that wrote the code isnt the one grading it. You give it something like "all tests in test/auth pass and lint is clean" and walk away. Codex has the same thing, also called /goal, it keeps working across turns until a verifiable stopping condition holds, with pause and resume and clear. Same primitive, both tools, wich is kind of the pattern for this whole article.

还有第二个值得知道的会话内原语,它和这整篇文章讨论的东西更接近。/loop 会按节奏反复运行。/goal 则会一直持续,直到你写下的某个条件真的成立,而且每一轮结束后,都会由另一个更小的模型来判断你是否完成,所以写代码的那个代理并不是给自己打分的那个。你可以给它一句类似 所有 test/auth 里的测试都通过,而且 lint 干净,然后直接走开。Codex 也有同样的东西,也叫 /goal,它会跨多轮继续工作,直到一个可验证的停止条件成立,还支持暂停、恢复和清除。相同的原语,两个工具都有,这几乎就是整篇文章的模式。

So this is the part that surfaces the work. The rest of the loop is what acts on it.

所以,这一部分负责把工作浮出来。循环的其余部分则负责对它采取动作。

Worktrees so parallel doesn't turn into chaos

工作树,让并行不至于变成混乱

The second you run more than one agent the files start colliding, that becomes the failure. Two agents writing the same file is the exact same headache as two engineers committing to the same lines and nobody talked to each other first. A git worktree fixes it, its a separate working directory on its own branch sharing the same repo history, so one agent's edits literally can not touch the other one's checkout.

一旦你同时跑不止一个代理,文件就会开始互相冲突,这会变成主要故障。两个代理改同一个文件,和两个工程师同时提交到同几行代码、事先却没打招呼,本质上是一样的头疼。git worktree 能解决这个问题。它是在同一份仓库历史上共享记录、但位于独立分支上的单独工作目录,所以一个代理的修改,从物理上就不可能碰到另一个代理的 checkout。

Codex builds the worktree support right in so several threads hit the same repo at once and dont bump into each other. Claude Code gives you the same isolation with git worktree, a --worktree flag to open a session in its own checkout, and a isolation: worktree setting you stick on a subagent so each helper gets a fresh checkout that cleans itself up after. I wrote about the human side of all this in the orchestration tax, the worktrees take away the mechanical collision but YOU are still the ceiling, your review bandwith decides how many you can actually run, not the tool.

Codex 直接内建了 worktree 支持,所以多个线程可以同时打到同一个仓库,而不会彼此撞车。Claude Code 也通过 git worktree 提供同样的隔离,你可以用 --worktree 标志把会话开在独立 checkout 里,还可以给子代理加上 isolation: worktree 设置,让每个帮手都拿到一个新的 checkout,做完后再自行清理。我在 orchestration tax 里写过这里面人的那一层问题,worktree 解决的是机械上的碰撞,但真正的上限依然是 YOU。你能实际同时跑多少,不取决于工具,而取决于你的 review 带宽。

Skills, so you stop explaining your project every single time

技能,让你别再每次都把项目重新解释一遍

A skill is how you stop re-explaining the same project context every session like a goldfish. Both tools use the same format, a folder with a SKILL.md inside holding instructions and metadata, and then optional scripts, references, assets. Codex runs a skill when you call it with $ or /skills, or by itself when your task matches the skill description, which is the reason a tight boring description beats a clever one. Claude Code does it the same way and I wrote the pattern up in agent skills.

技能的作用,是让你别再像金鱼一样,每次开新会话都把同样的项目上下文重新讲一遍。两个工具用的是同一种格式,一个文件夹,里面放一个 SKILL.md,记录说明和元数据,再加上一些可选的脚本、参考资料、资源。Codex 会在你用 $ 或 /skills 调用它时运行技能,或者在任务与技能描述匹配时自行触发,所以那种紧凑、无聊、准确的描述,比聪明花哨的描述更有用。Claude Code 也是同一套方式,我在 agent skills 里专门写过这个模式。

Skills are also where intent stops costing you over and over. I argued in the intent debt that an agent starts every session cold and it will fill any hole in your intent with a confident guess. A skill is that intent written down on the outside, the conventions, the build steps, the “we dont do it like this because of that one incident”, written one time where the agent reads it every run. Without skills the loop re-derives your whole project from zero every cycle, with skills it kind of compounds.

技能也是让意图不再反复烧钱的地方。我在 intent debt 里提过,代理每次开局都是冷启动,而你意图里只要有空洞,它就会用自信满满的猜测把空洞填上。技能,就是把这些意图写在外面。项目约定、构建步骤、我们不这么做是因为那次事故,全都写下来,写一次,以后每次运行代理都会读到。没有技能,循环每一轮都得从零重新推导整个项目。有了技能,它就会开始积累。

One thing to keep straight, the skill is the authoring format and a plugin is how you ship it. When you want to share a skill across repos or bundle a few together you package them as a plugin. True in Codex, true in Claude Code.

有一点要分清。技能是创作格式,插件则是分发方式。当你想跨仓库共享一个技能,或者把几个技能打包在一起时,你会把它们做成插件。Codex 是这样,Claude Code 也是这样。

Plugins and connectors, the loop touches your real tools

插件和连接器,让循环碰到你真实在用的工具

A loop that can only see the filesystem is a tiny loop. Connectors, which are built on MCP, let the agent read your issue tracker, query a database, hit a staging api, drop a message in Slack. Codex and Claude Code both speak MCP so the connector you wrote for one usually just works in the other. And plugins bundle connectors and skills together so your teammate installs your setup in one go instead of rebuilding the whole thing from memory.

一个只能看见文件系统的循环,是个很小的循环。连接器建立在 MCP 之上,它让代理可以读取你的 issue 跟踪系统、查询数据库、访问 staging api、往 Slack 里发消息。Codex 和 Claude Code 都支持 MCP,所以你给一个工具写的连接器,通常在另一个工具里也能直接用。而插件则会把连接器和技能一起打包,这样你的队友一次安装就能把整套配置装好,不用靠记忆把整个东西重建一遍。

This is the difference between an agent that says “here is the fix” and a loop that opens the PR, links the Linear ticket and pings the channel once CI is green by itself. The connectors are the reason the loop can act inside your actual environment instead of just telling you what it would do if it could.

这就是一个只会说 这是修复方案 的代理,和一个能自己开 PR、自动关联 Linear ticket、等 CI 绿了再去频道里提醒一声的循环之间的差别。连接器的意义就在于,它让循环能在你的真实环境里采取行动,而不是只告诉你,如果它有权限的话,它本来会怎么做。

Sub-agents, keep the maker away from the checker

子代理,让执行者远离检查者

The most useful structural thing in a loop, by far, is splitting the one who writes from the one who checks. The model that wrote the code is way too nice grading its own homework. A second agent with different instructions and sometimes a different model catches the stuff the first one talked itself into.

在一个循环里,最有用的结构设计,毫无疑问就是把负责写的人和负责查的人分开。写代码的那个模型,在给自己作业打分这件事上实在太好说话了。第二个代理,如果指令不同,甚至模型也不同,就能抓住第一个代理自己把自己说服过去的那些问题。

Codex only spawns subagents when you ask, runs them at the same time and then folds the results back into one answer. You define your own agents as TOML files in .codex/agents/, each with a name, a description, instructions and optional model and reasoning effort, so your security reviewer can be a strong model on high effort while your explorer is some fast read-only thing. Claude Code does the same with subagents in .claude/agents/ and agent teams that pass work between them. The usual split in both is one agent explores, one implements, one verifies against the spec.

Codex 只有在你要求时才会生成子代理,它们会并行运行,然后把结果合并回一个答案里。你可以把自己的代理定义成放在 .codex/agents/ 里的 TOML 文件,每个代理有名字、描述、指令,以及可选的模型和 reasoning effort,于是你的安全审查员可以是一个高 effort 的强模型,而你的探索器则可以只是个快速的只读工具。Claude Code 也一样,它用 .claude/agents/ 里的子代理和 agent team 在不同代理之间传递工作。两个工具里最常见的分工通常都是,一个代理探索,一个实现,一个对照规格做验证。

I made this case twice already, once as the code agent orchestra and once as adversarial code review. The reason it matters specifically inside a loop is the loop runs while you are not watching, so a verifier you actually trust is the only reason you can walk away. Subagents do burn more tokens since each one does its own model and tool work, so spend them where a second opinion is worth paying for. This is also basically what Claude Code's /goal does under the hood, a fresh model decides if the loop is done instead of the one that did the work, the maker and checker split applied to the stop condition itself.

这个观点我已经讲过两次了,一次在 code agent orchestra 里,一次在 adversarial code review 里。它之所以在循环里尤其重要,是因为循环会在你不盯着的时候自己跑,所以,只有当你真的信得过那个验证者时,你才有资格走开。子代理确实会烧更多 token,因为每个子代理都会各自做一遍模型调用和工具调用,所以只在那些第二意见确实值得花钱的地方用它们。这其实也基本就是 Claude Code 的 /goal 在底层做的事。由一个新的模型判断循环是否结束,而不是由实际干活的那个来判断。也就是把执行者和检查者的分离,直接应用到了停止条件本身。

What one loop looks like

一个循环长什么样

Stick it together and a single thread turns into a little control panel. Here is one shape I keep using.

把这些拼在一起,单一线程就会变成一个小控制台。下面是我反复在用的一种形状。

An automation runs every morning on the repo. Its prompt calls a triage skill that reads yesterdays CI failures, the open issues, the recent commits, and writes the findings into a markdown file or a Linear board. For each finding that is worth doing the thread opens an isolated worktree and sends a sub-agent to draft the fix, and a second sub-agent reviews that draft against the project skills and the existing tests.

每天早上,一个自动化在仓库上运行。它的提示会调用一个分诊技能,读取昨天的 CI 失败、未关闭 issue、最近的提交,然后把发现写进一个 markdown 文件,或者一个 Linear 面板里。对于每个值得处理的发现,这个线程会打开一个隔离的 worktree,派一个子代理去起草修复方案,再派第二个子代理按照项目技能和现有测试去审查这份草案。

Connectors let the loop open the PR and update the ticket. Anything the loop can not handle lands in the triage inbox for me. The state file is the spine of the whole thing, it remembers what got tried, what passed, what is still open, so tomorrow morning the run picks up where today stopped.

连接器让循环自己去开 PR、更新 ticket。凡是循环处理不了的东西,就会落进 Triage 收件箱等我来接。状态文件是整个系统的脊梁,它记得哪些尝试做过、哪些通过了、哪些还开着,所以明天早上的运行会从今天停下的地方继续。

And look at what you actually did there. You designed it one time. You did not prompt any of those steps. Thats Steinberger's whole point made real, and its the same loop in Codex or in Claude Code because the pieces are the same pieces.

而且你回头看看,自己到底做了什么。你只设计了一次。那些步骤没有任何一步是你亲自写提示去驱动的。这就是 Steinberger 的核心意思变成现实后的样子,而且不管是在 Codex 里还是在 Claude Code 里,这都是同一个循环,因为这些部件本来就是同一批部件。

What the loop still does not do for you

循环仍然不能替你做的事

The loop changes the work, it does not delete you from it. And three problems actually get sharper as the loop gets better, not easier.

循环会改变工作的形态,但它不会把你从工作里删掉。而且有三个问题,随着循环变强,只会变得更尖锐,不会变得更轻松。

Verification is still on you. A loop running unattended is also a loop making mistakes unattended. The whole reason you split the verifier sub-agent from the maker is to make the loop's “its done” mean something, and even then “done” is a claim and not a proof. I keep saying the same line from code review in the age of AI, your job is to ship code you confirmed works.

验证依然是你的责任。一个无人看管的循环,也同样是一个会在无人看管时犯错的循环。之所以要把验证子代理和执行子代理分开,就是为了让循环嘴里的 已完成 真的有点分量。可就算这样,已完成 也只是一种声称,不是证明。我在 code review in the age of AI 里反复说过同一句话,你的工作,是交付那些你亲自确认过能工作的代码。

Your understanding still rots if you allow it. The faster the loop ships code you did not write, the bigger the gap between what exists and what you actually get. Thats comprehension debt and a smooth loop just makes it grow faster unless you read what the loop made.

如果你放任不管,你的理解依然会腐烂。循环交付代码越快,而那些代码又不是你亲手写的,那么已经存在的东西和你真正理解的东西之间的裂缝就会越大。这就是 comprehension debt。一个顺滑的循环,只会让它长得更快,除非你真的去读循环产出的东西。

And yeah, the comfortable posture is probably the risky one. When the loop runs itself its very tempting to stop having an opinion and just take whatever it gives back. I called that cognitive surrender. Designing the loop is the cure when you do it with judgement and the accelerant when you do it to avoid thinking, same action, opposite result.

而且,说实话,那种舒服的姿态大概才是更危险的。当循环能自己跑起来时,人太容易不再持有判断,只把它吐回来的东西全盘接受。我把这叫做 cognitive surrender。设计循环,如果你是带着判断力在做,它会是解药。如果你是为了逃避思考才去做,它就会变成催化剂。动作一样,结果相反。

Build the loop. Stay the engineer.

搭起循环。继续当工程师。

I think this is a preview of how our work is going to evolve. That said, If I weren't reviewing the code myself or if I relied entirely on automated loops to fix it my product’s quality would suffer. I'd likely end up stuck in a downward spiral, continuously digging myself into a deeper hole.

我觉得,这很像我们未来工作方式会如何演变的一次预演。不过,话说回来,如果不是我自己在看代码,或者如果我完全依赖自动化循环去修代码,那我的产品质量一定会下滑。最后很可能会掉进一个向下螺旋,持续把自己越挖越深。

That said, go ahead and set up your loops, but don't forget that prompting your agents directly is still effective. It's all about finding the right balance.

即便如此,循环还是值得搭,但别忘了,直接给代理写提示依然有效。关键在于找到合适的平衡。

Loops can also result in different outcomes depending on you. Two people can build the exact same loop and get completely opposite results. One uses it to move faster on work they understand deeply. The other uses it to avoid understanding the work at all. The loop doesn't know the difference. You do.

循环带来的结果,也会因为人不同而不同。两个人可以搭出完全一样的循环,最后却得到截然相反的结果。一个人用它加速自己本就理解很深的工作。另一个人用它来逃避理解工作本身。循环看不出差别。你看得出。

That's what makes loop design harder than prompt engineering, not easier. Cherny's point isn’t that the work got easier. It's that the leverage point moved.

这正是为什么循环设计比提示工程更难,而不是更简单。Cherny 的意思不是工作变轻松了,而是杠杆点变了。

Build the loop. But build it like someone who intends to stay the engineer, not just the person who presses go.

搭起循环。但要像一个打算继续当工程师的人那样去搭,而不是像一个只负责按下开始按钮的人。

Loop engineering is replacing yourself as the person who prompts the agent. You design the system that does it instead. A loop here can be thought of a recursive goal where you define a purpose and the AI iterates until complete. It's roughly five building blocks and Claude Code and Codex both have all five now.

I believe this may be the future of how we work with coding agents. However, its still early, I'm skeptical and you absolutely have to be careful about token costs (usage patterns can vary wildly if you are token rich or poor). You also still need some way to ensure quality doesn't drop and concerns re: slop are valid. That said, let's explore what this is all about.

@steipete recently said: “You shouldn't be prompting coding agents anymore. You should be designing loops that prompt your agents.” Similarly, @bcherny, head of Claude Code at Anthropic, said “I don't prompt Claude anymore. I have loops running that prompt Claude and figuring out what to do. My job is to write loops”.

Okay, so what does any of that mean?

For like two years the way you got something out of a coding agent was you wrote a good prompt and shared enough context. You type a thing, you read what came back, you type the next thing. The agent is a tool and you are holding it the entire time, one turn after the other. That part is kind of over, or at least some think it's going to be.

Now you build a small system that finds the work, hands it out, checks it, writes down what is done and then decides the next thing, and you let that system poke the agents instead of you. I wrote before about the cousin of this, agent harness engineering, which is making the environment one single agent runs inside and the factory model - the system that builds the software. Loop engineering sits one floor above the harness. The harness but it runs on a timer, it spawns little helpers, and it feeds itself.

The thing that surprised me is this is not really a tool thing anymore. A year ago if you wanted a loop you wrote a pile of bash and you maintained that pile forever and it was yours and only yours. Now the pieces just ship inside the products. Steinberger's list maps almost exactly onto the Codex app, and then almost the same onto Claude Code. And once you notice the shape is the same you stop arguing about which tool, you just design a loop that still works no matter which one you happen to be sitting in.

The five pieces, and then notes

A loop needs five things and then one place to remember stuff. Let me list it first and then map it.

  1. Automations that go off on a schedule and do discovery and triage by themselves.

  2. Worktrees so two agents working in parallel dont step on each other.

  3. Skills to write down the project knowledge the agent would otherwise just guess.

  4. Plugins and connectors to plug the agent into the tools you already use.

  5. Sub-agents so one of them has the idea and a different one checks it.

Then the sixth thing, the memory. A markdown file, or a Linear board, anything that lives outside the single conversation and holds what's done and what is next. Sounds too dumb to matter. But it's the same trick every long running agent depends on and I went into it in long-running agents, the model forgets everything between runs so the memory has to be on disk and not in the context. The agent forgets, the repo doesnt.

Both products have all five now.

https://addyosmani.com/blog/long-running-agents/

The names are a bit different here and there but the capability is the same thing. Let me go one by one because honestly the details are where a loop either holds together or quietly leaks everywhere.

Automations, this is the heartbeat

Automations are what make a loop an actual loop and not just one run you did once. In the Codex app you make one in the Automations tab and you pick the project, the prompt it will run, how often, and if it runs on your local checkout or on a background worktree. The runs that find something go to a Triage inbox, and the runs that find nothing just archive themselves which is nice. OpenAI uses them internally for boring stuff like daily issue triage, summarizing CI failures, writing commit briefings, hunting bugs somebody added last week. And an automation can call a skill, so you keep the recurring thing maintainable, you fire $skill-name instead of pasting a giant wall of instructions into a schedule that nobody will ever update.

Claude Code gets to the same place but through scheduling and hooks. You can run a prompt or a command on a interval with /loop, you can schedule a cron task, you can fire shell commands at certain points in the agent lifecycle with hooks, or you push the whole thing to GitHub Actions if you want it to keep running after you close the laptop. Same idea exactly, you define an autonomous task, you give it a cadence, and the findings come to you so you are not the one going around checking.

There is a second in-session primitive worth knowing, and it's the one closer to what this whole post is about. /loop re-runs on a cadence. /goal keeps going until a condition you wrote is actually true, and after every turn a separate small model checks whether you are done, so the agent that wrote the code isnt the one grading it. You give it something like "all tests in test/auth pass and lint is clean" and walk away. Codex has the same thing, also called /goal, it keeps working across turns until a verifiable stopping condition holds, with pause and resume and clear. Same primitive, both tools, wich is kind of the pattern for this whole article.

So this is the part that surfaces the work. The rest of the loop is what acts on it.

Worktrees so parallel doesn't turn into chaos

The second you run more than one agent the files start colliding, that becomes the failure. Two agents writing the same file is the exact same headache as two engineers committing to the same lines and nobody talked to each other first. A git worktree fixes it, its a separate working directory on its own branch sharing the same repo history, so one agent's edits literally can not touch the other one's checkout.

Codex builds the worktree support right in so several threads hit the same repo at once and dont bump into each other. Claude Code gives you the same isolation with git worktree, a --worktree flag to open a session in its own checkout, and a isolation: worktree setting you stick on a subagent so each helper gets a fresh checkout that cleans itself up after. I wrote about the human side of all this in the orchestration tax, the worktrees take away the mechanical collision but YOU are still the ceiling, your review bandwith decides how many you can actually run, not the tool.

Skills, so you stop explaining your project every single time

A skill is how you stop re-explaining the same project context every session like a goldfish. Both tools use the same format, a folder with a SKILL.md inside holding instructions and metadata, and then optional scripts, references, assets. Codex runs a skill when you call it with $ or /skills, or by itself when your task matches the skill description, which is the reason a tight boring description beats a clever one. Claude Code does it the same way and I wrote the pattern up in agent skills.

Skills are also where intent stops costing you over and over. I argued in the intent debt that an agent starts every session cold and it will fill any hole in your intent with a confident guess. A skill is that intent written down on the outside, the conventions, the build steps, the “we dont do it like this because of that one incident”, written one time where the agent reads it every run. Without skills the loop re-derives your whole project from zero every cycle, with skills it kind of compounds.

One thing to keep straight, the skill is the authoring format and a plugin is how you ship it. When you want to share a skill across repos or bundle a few together you package them as a plugin. True in Codex, true in Claude Code.

Plugins and connectors, the loop touches your real tools

A loop that can only see the filesystem is a tiny loop. Connectors, which are built on MCP, let the agent read your issue tracker, query a database, hit a staging api, drop a message in Slack. Codex and Claude Code both speak MCP so the connector you wrote for one usually just works in the other. And plugins bundle connectors and skills together so your teammate installs your setup in one go instead of rebuilding the whole thing from memory.

This is the difference between an agent that says “here is the fix” and a loop that opens the PR, links the Linear ticket and pings the channel once CI is green by itself. The connectors are the reason the loop can act inside your actual environment instead of just telling you what it would do if it could.

Sub-agents, keep the maker away from the checker

The most useful structural thing in a loop, by far, is splitting the one who writes from the one who checks. The model that wrote the code is way too nice grading its own homework. A second agent with different instructions and sometimes a different model catches the stuff the first one talked itself into.

Codex only spawns subagents when you ask, runs them at the same time and then folds the results back into one answer. You define your own agents as TOML files in .codex/agents/, each with a name, a description, instructions and optional model and reasoning effort, so your security reviewer can be a strong model on high effort while your explorer is some fast read-only thing. Claude Code does the same with subagents in .claude/agents/ and agent teams that pass work between them. The usual split in both is one agent explores, one implements, one verifies against the spec.

I made this case twice already, once as the code agent orchestra and once as adversarial code review. The reason it matters specifically inside a loop is the loop runs while you are not watching, so a verifier you actually trust is the only reason you can walk away. Subagents do burn more tokens since each one does its own model and tool work, so spend them where a second opinion is worth paying for. This is also basically what Claude Code's /goal does under the hood, a fresh model decides if the loop is done instead of the one that did the work, the maker and checker split applied to the stop condition itself.

What one loop looks like

Stick it together and a single thread turns into a little control panel. Here is one shape I keep using.

An automation runs every morning on the repo. Its prompt calls a triage skill that reads yesterdays CI failures, the open issues, the recent commits, and writes the findings into a markdown file or a Linear board. For each finding that is worth doing the thread opens an isolated worktree and sends a sub-agent to draft the fix, and a second sub-agent reviews that draft against the project skills and the existing tests.

Connectors let the loop open the PR and update the ticket. Anything the loop can not handle lands in the triage inbox for me. The state file is the spine of the whole thing, it remembers what got tried, what passed, what is still open, so tomorrow morning the run picks up where today stopped.

And look at what you actually did there. You designed it one time. You did not prompt any of those steps. Thats Steinberger's whole point made real, and its the same loop in Codex or in Claude Code because the pieces are the same pieces.

What the loop still does not do for you

The loop changes the work, it does not delete you from it. And three problems actually get sharper as the loop gets better, not easier.

Verification is still on you. A loop running unattended is also a loop making mistakes unattended. The whole reason you split the verifier sub-agent from the maker is to make the loop's “its done” mean something, and even then “done” is a claim and not a proof. I keep saying the same line from code review in the age of AI, your job is to ship code you confirmed works.

Your understanding still rots if you allow it. The faster the loop ships code you did not write, the bigger the gap between what exists and what you actually get. Thats comprehension debt and a smooth loop just makes it grow faster unless you read what the loop made.

And yeah, the comfortable posture is probably the risky one. When the loop runs itself its very tempting to stop having an opinion and just take whatever it gives back. I called that cognitive surrender. Designing the loop is the cure when you do it with judgement and the accelerant when you do it to avoid thinking, same action, opposite result.

Build the loop. Stay the engineer.

I think this is a preview of how our work is going to evolve. That said, If I weren't reviewing the code myself or if I relied entirely on automated loops to fix it my product’s quality would suffer. I'd likely end up stuck in a downward spiral, continuously digging myself into a deeper hole.

That said, go ahead and set up your loops, but don't forget that prompting your agents directly is still effective. It's all about finding the right balance.

Loops can also result in different outcomes depending on you. Two people can build the exact same loop and get completely opposite results. One uses it to move faster on work they understand deeply. The other uses it to avoid understanding the work at all. The loop doesn't know the difference. You do.

That's what makes loop design harder than prompt engineering, not easier. Cherny's point isn’t that the work got easier. It's that the leverage point moved.

Build the loop. But build it like someone who intends to stay the engineer, not just the person who presses go.

📋 讨论归档

讨论进行中…