但先把丑话说前面:这东西现在还很早期,我自己也保持怀疑。最大的坑是 token 成本,不同用法之间的消耗差距大到离谱,尤其取决于你是 token 富裕还是 token 紧张。你还得想办法保证质量别往下掉,对「AI slop」的担心一点都不多余。话虽如此,它到底是什么,值得拆开看看。

从「握着工具」到「设计系统」

过去两年,想让 coding agent 干活的方式基本没变:写个好 prompt,喂足够的上下文,输入一段,读返回结果,再输入下一段。agent 是工具,你一直握着它,一轮接一轮地操作。

最近有人说,这事该结束了——你不该再去 prompt coding agent,你应该设计 loops,让 loops 去 prompt 你的 agents。Anthropic 那边管 Claude Code 的人也是类似说法:他已经不直接 prompt Claude 了,而是跑着一套 loops,由它们去 prompt Claude、判断下一步做什么,他的工作就是写 loops。

翻译成人话:你现在构建的是一个小系统。它自己发现工作、分发工作、检查工作、记录完成情况,然后决定下一步。触发 agents 的是系统,不是你。

这跟我之前写过的 harness 概念相邻。harness 是给单个 agent 搭运行环境,也就是那个真正构建软件的系统。Loop Engineering 站在 harness 之上——它有点像 harness,但会按时间持续运行,会生成小 helper,还会自己喂养自己。

最让我意外的一点是:这已经不再是「工具问题」了。

一年前你想搭个 loop,得写一堆 bash 脚本然后长期维护,那是你自己的私货,也只有你能用。现在这些能力直接内置进产品里了。Steinberger 列出的那几样能力,几乎能一一对应到 Codex app,也几乎能对应到 Claude Code。等你看清它们形状其实一样,就不会再纠结该用哪个工具,而是开始设计一种 loop——不管你此刻坐在哪个工具里,它都照样能跑。

一个 loop 需要的五样东西,外加一个记忆

先列出来,再逐个映射:

  • Automations:按计划自动触发,自己做 discovery 和 triage。
  • Worktrees:让两个并行的 agents 不会互相踩脚。
  • Skills:把项目知识写下来,省得 agent 靠猜。
  • Plugins 和 connectors:把 agent 接进你已经在用的工具。
  • Sub-agents:一个 agent 提想法,另一个 agent 检查它。

第六件事是 memory。它可以是一个 markdown 文件、一个 Linear board,或者任何活在单次 conversation 之外、能记住「做完了什么」和「下一步做什么」的地方。

这听起来简单到不像是重点,但它恰恰是每个 long-running agent 都依赖的同一个把戏:模型在每次运行之间会忘掉一切,所以 memory 必须落在磁盘上,而不是只活在 context 里。一句话——agent 会忘,但 repo 不会。

两个产品现在都凑齐了这五项能力,名字略有出入,本质一样。下面一个个看,因为细节才决定一个 loop 是真能跑,还是悄悄到处漏水。

Automations:让 loop 真的「循环」起来

Automations 是让 loop 成为 loop、而不是一次性任务的关键。

在 Codex app 里,你在 Automations 标签页建一个 automation:选项目、选要跑的 prompt、选频率,再选它是跑在你本地 checkout 上,还是跑在 background worktree 上。发现了问题的运行进 Triage inbox;没发现问题的自动 archive——这点很贴心。OpenAI 内部就拿它处理枯燥活:每日 issue triage、总结 CI failures、写 commit briefings、揪出上周谁引入的 bug。

automation 还能调用 skill。这样重复任务才好维护——你触发的是一个 skill,而不是把一大墙再也没人会更新的指令糊进 schedule 里。

Claude Code 走的是 scheduling 和 hooks 这条路,殊途同归。你可以用 /loop 按间隔跑一个 prompt 或 command,可以安排 cron task,可以在 agent 生命周期的某些节点用 hooks 触发 shell command,甚至想在你合上笔记本之后还接着跑,就把整套推到 GitHub Actions 上。本质完全一样:定义一个 autonomous task,给它一个节奏,让发现结果自己送到你面前,而不是你到处去翻。

这里还有一个更贴近本文核心的 in-session primitive 值得知道:

  • /loop 按节奏反复跑。
  • /goal 一直跑,直到你写下的某个条件真的成立。每轮之后,一个单独的小模型来检查任务是否完成——也就是说,写代码的 agent 不是给自己打分的那个

你可以给它一个条件,比如:

all tests in test/auth pass and lint is clean

然后你就可以走开。Codex 也有同名的 /goal,跨多轮工作直到可验证的停止条件成立,支持 pause、resume、clear。同一个 primitive,两个工具都有——这基本就是整篇文章反复出现的套路。

这一部分负责把工作浮出水面,loop 的其余部分负责对这些工作动手。

Worktrees:别让两个 agent 撞同一个文件

只要你同时跑不止一个 agent,文件就会开始冲突,这就是失败点。两个 agent 同时改同一个文件,跟两个工程师事先没沟通就提交同一段代码一样麻烦。

git worktree 解决这个。它是一个独立的 working directory,待在自己的 branch 上,同时共享同一份 repo history。所以一个 agent 的改动,字面意义上不可能碰到另一个 agent 的 checkout。

Codex 直接内置 worktree 支持,多个 threads 能同时作用于一个 repo 而不撞车。Claude Code 同样靠 git worktree 提供隔离:用 --worktree flag 在独立 checkout 里开 session,或者在 subagent 上设 isolation: worktree,让每个 helper 都拿到一个新 checkout,结束后自动清理。

但工具只是消除了机械层面的冲突,你仍然是天花板。决定你能同时跑多少 agents 的,从来不是工具,而是你的 review bandwidth。

Skills:别每次 session 都像金鱼一样重新解释项目

skill 的作用,是让你不必每开一个 session 就把项目上下文从头讲一遍。

两个工具用的是同一种格式:一个含 SKILL.md 的文件夹,里面放 instructions 和 metadata,可以附带 scripts、references、assets。Codex 在你用 $/skills 调用时运行某个 skill;当你的 task 跟 skill description 匹配时,它也可能自动调用——所以一个紧凑朴素的 description,比一个聪明但含糊的 description 有用得多。Claude Code 做法一致。

Skills 也是让 intent 不再一遍遍重复付费的地方。agent 每个 session 都是冷启动的,你的 intent 里只要有空洞,它就会用一个自信的猜测把洞填上。skill 就是把这份 intent 写在外部——项目约定、构建步骤、「我们不这么干是因为以前出过事故」之类。写一次,每次运行都读。

没有 skills,loop 每个周期都要从零重新推导你整个项目;有了 skills,它才开始有一点复利。

还有一处要分清:skill 是创作格式,plugin 是分发方式。当你想跨 repo 共享一个 skill,或者把几个 skills 打包,就封装成 plugin。Codex 这样,Claude Code 也这样。

Connectors:只能看见 filesystem 的 loop 是个小 loop

Connectors 基于 MCP,让 agent 能读你的 issue tracker、查数据库、调 staging API、在 Slack 发消息。Codex 和 Claude Code 都支持 MCP,所以你为其中一个写的 connector,通常在另一个里也能直接用。

plugins 还能把 connectors 和 skills 一起打包,你的队友装上你的 setup 就行,不用凭记忆重建整套。

这就是「agent 说『这是修复方案』」和「loop 自己开 PR、链好 Linear ticket、CI 变绿后 ping 频道」之间的差别。connectors 是 loop 能在你真实环境里动手的原因,而不只是嘴上告诉你「如果我能做,我会怎么做」。

Sub-agents:把「写的人」和「检查的人」拆开

在一个 loop 里,最有用的结构性设计,远远是把写代码的和做检查的分开。写代码的模型,给自己作业打分时太宽容了。一个带不同 instructions、有时甚至用不同 model 的第二个 agent,能抓住第一个 agent 自我说服后选择性忽略的问题。

Codex 只在你要求时才生成 subagents,它们并行跑,再把结果合并成一个答案。你可以把自己的 agents 定义成 .codex/agents/ 里的 TOML 文件,每个含 name、description、instructions,以及可选的 model 和 reasoning effort。于是你的 security reviewer 可以用强模型加 high effort,explorer 可以是个快速的 read-only agent。Claude Code 用 .claude/agents/ 里的 subagents 和 agent teams 做同样的事,在不同 agents 之间传递工作。

两个工具里常见的拆法都是:一个 agent 探索,一个 agent 实现,一个 agent 按 spec 验证。

它在 loop 里尤其重要的原因是:loop 会在你没盯着的时候运行,所以一个你真信得过的 verifier,是你敢走开的唯一理由。当然 subagents 更费 tokens,每个都要跑自己的 model 和 tool work,所以把它们花在「第二意见值得付费」的地方。这也正是 Claude Code 的 /goal 底层在做的事——由一个新模型判断 loop 是否完成,而不是由干活那个模型自己说。连停止条件本身,都套用了 maker / checker 的拆分。

拼起来:一个单线程任务变成一块小控制面板

把这些粘在一起,下面是我一直在用的一种形状:

  • 每天早上,一个 automation 在 repo 上跑。
  • 它的 prompt 调用一个 triage skill,读昨天的 CI failures、open issues、recent commits,把 findings 写进一个 markdown 文件或 Linear board。
  • 对每个值得处理的 finding,这个 thread 开一个隔离的 worktree,派一个 sub-agent 去 draft fix,再派第二个 sub-agent 按项目 skills 和现有 tests 去 review 这个 draft。
  • connectors 让 loop 自己开 PR、更新 ticket。
  • 任何 loop 处理不了的事,落到我的 triage inbox。

state file 是整套东西的脊柱。它记住试过什么、什么通过了、什么还 open,所以第二天早上的运行能从今天停下的地方接着干。

回头看你到底做了什么:你只设计了一次,没亲手 prompt 其中任何一步。不管在 Codex 还是 Claude Code 里,这都是同一个 loop,因为这些 pieces 本质上是同样的 pieces。

Loop 改变工作,但删不掉你

loop 会改变工作方式,但它不会把你从工作里抹掉。而且 loop 越好,有三个问题反而越尖锐,不是越轻松。

第一,verification 仍然在你身上。 一个无人值守跑的 loop,也是在无人值守地犯错。你把 verifier 和 maker 拆开,就是为了让 loop 说出的「done」有点分量。但即便如此,「done」也只是一个声明,不是证明。说到底——你的工作,是交付你确认过能运行的代码。

第二,你不管,理解就会腐烂。 loop 越快地交付那些不是你亲手写的代码,真实系统和你以为你懂的系统之间的差距就越大。一个顺滑的 loop 只会让这道差距长得更快——除非你真的去读它产出的东西。

第三,最舒服的姿势,往往也最危险。 当 loop 开始自己跑,你很容易停止保有自己的判断,它给什么你就接什么。这是个危险状态。带着判断力去设计 loop,loop 是解药;为了逃避思考去设计 loop,它就是加速剂。同一个动作,结果完全相反。

写在最后

我认为这是工作方式即将演化的一次预览。但话也得说回来:如果我不亲自 review 代码,或者完全把修 bug 这件事甩给自动化 loops,我的产品质量一定会掉,而且很可能掉进一个越挖越深的下滑螺旋。

所以——去搭你的 loops 吧。但别忘了,直接 prompt 你的 agents 仍然有效,关键是找到平衡。

还有一点,loops 会因为用的人不同而长出完全相反的结果。两个人搭出一模一样的 loop,一个用它在自己真懂的事情上跑得更快,另一个用它来逃避去懂这件事本身。loop 分不清这两者,但你分得清。这正是为什么 loop design 比 prompt engineering 更难,而不是更简单。

杠杆点移动了,工作没变简单。去构建 loop——但要像一个仍然打算当 engineer 的人那样去构建它,而不是像一个只会按「go」按钮的人。