循环工程正在取代你亲手为编程代理编写提示的角色。你来设计一个系统替你做这件事。这里的“循环”可以看作一个递归目标——你定义一个目的,AI 会不断迭代,直到完成。它大致包含五个构建块,Claude Code 和 Codex 现在都已具备全部五块。
我相信这可能是我们未来与编程代理协同工作的方式。不过,目前为时尚早,我仍持怀疑态度,而且你必须留意 token 开销——使用模式可能因 token 消耗的高低而剧烈波动。你还需要某种方法来确保质量不会下降,对“渣作”的担忧也并非多虑。话虽如此,让我们一探究竟。
Peter Steinberger 最近说过:“你不应再亲自为编程代理编写提示了。你应该设计能自动提示代理的循环。” Anthropic 旗下 Claude Code 负责人 Boris Cherny 也说:“我不再给 Claude 写提示了,我让循环运行着去提示 Claude 并弄清该做什么。我的工作是编写循环。”
好吧,这到底是什么意思?
过去大约两年里,从编程代理那里获得产出,靠的是你写一个出色的提示,并分享足够的上下文。你输入一个东西,阅读返回结果,再输入下一个东西。代理是一个工具,你全程握着它,一回合接一回合。这种模式差不多结束了,至少有些人认为行将就木。
现在,你构建一个小型系统来发现工作、分派任务、检查结果、记录已完成事项,然后决定下一步做什么,并让这个系统去驱动代理,而不是你亲自操刀。我之前写过与其类似的“环境即托架”,即把环境变成一个仅供单个代理运行的场所,托架就是构建软件的系统。而循环工程的位置比托架高一层。它像一个加装了定时器的托架,会不断衍生出小帮手,并自行补给。
令我惊讶的是,这已不再仅仅是工具问题。一年前,如果你想要一个循环,你就得写一堆 bash 脚本,并永远自己维护,它独属于你。现在,这些构件直接内置在了 产品 中。Steinberger 列举的功能几乎都能对接到 Codex 应用中,然后再几乎以同样方式对接到 Claude Code 上。一旦你注意到它们的形态是相同的,就不会再纠结用哪个工具,你只需设计一个无论身处哪款工具中都能工作的循环。
五大组件,及附注
一个循环需要五样东西,再加上一个记忆库。先列出来,再一一对照。
- 按计划自动触发,自行执行发现与分诊的自动化。
- 工作树,让两个并行工作的代理互不干扰。
- 技能,用以记录项目知识,避免代理无端猜测。
- 插件与连接器,将代理接入你已有的工具链。
- 子代理,一个负责出主意,另一个负责审查方案。
然后是第六样东西——记忆。它可以是个 Markdown 文件,或者一个 Linear 看板,总之是存在于单次对话之外、记录已完成和待办事项的东西。听起来简单得不像话,但它正是每个长运行代理所依赖的诀窍,我在《文件夹即代理》一文中阐述过:模型在每次运行之间会遗忘一切,因此记忆必须留在磁盘上,而不能仅靠上下文。代理会遗忘,代码仓库不会。
如今,两款产品都已具备这全部五种能力。
名称虽略有差异,但能力如出一辙。我们逐项深入,因为说实话,一个循环是坚挺不破,还是处处渗漏,正取决于这些细节。
自动化:循环的心跳
自动化是让循环成其为循环,而不只是一次性运行的关键。在 Codex 应用中,你可以在“自动任务”选项卡下创建一个,然后选定项目、要运行的提示、运行频率,以及是跑在本地检出上还是后台工作树上。有所发现的运行结果会进入分诊收件箱,而一无所获的运行则会自动归档,这点挺不错。OpenAI 内部就用它们处理日常的琐碎任务,比如每日 issue 分诊、汇总 CI 失败信息、撰写提交简报、追查上周引入的 bug。自动化还可以调用技能,这样你就能让重复性任务保持可维护性——只需触发一个技能,而不用把一大坨指令粘贴到一个永远不会有人更新的调度里。
Claude Code 殊途同归,只是通过调度和钩子来实现。你可以用 /loop 按间隔运行一个提示或命令,可以安排一个 cron 任务,可以用钩子在代理生命周期的特定节点触发 shell 命令,或者把整套东西推送到 GitHub Actions,以确保合上笔记本后它仍继续运行。思路完全相同:你定义一个自主任务,设定节奏,结果便会主动送到你面前,省得你四处检查。
还有一个值得了解的会话内原语,它更接近本文的主题。/loop 是按节奏重复运行。/goal 则会持续运行,直到你编写的条件确实成立,并且每一回合结束后,会有一个独立的小模型来检查是否已完成,这样编写代码的代理就不再是自己批改试卷的角色。你给它一个类似“test/auth 下的所有测试通过且 lint 无警告”的条件,然后就可以走开了。Codex 也有同名的 /goal,它会跨回合持续工作,直到一个可验证的终止条件满足,并支持暂停、恢复与清除。同样的原语,两款工具都在用,这差不多算是贯穿全文的模式了。
至此,这部分负责让工作浮现出来。循环的其余部分则负责对工作执行操作。
工作树:避免并行沦为混乱
一旦你运行多个代理,文件冲突便会接踵而至,这往往是失败的根源。两个代理修改同一个文件,就如同两位工程师往相同的代码行提交改动,事先却没沟通一样令人头疼。git worktree 能解决这个问题,它在一个独立的分支上创建一个单独的工作目录,共享同一份仓库历史,这样一来一个代理的编辑完全无法触及另一个代理的检出副本。
Codex 直接内置了 worktree 支持,允许多个线程同时访问同一个仓库而不会相互冲撞。Claude Code 则通过 git worktree 提供了同样的隔离:通过 --worktree 标志在其独立的检出副本中打开会话,并可为子代理设置 isolation: worktree,使每个助手获得一个新鲜的检出副本,并在事后自动清理。我曾在《胶囊:AI 代理的隔离环境》中探讨了其中的人类因素:工作树消除了物理上的冲突,但最终的瓶颈依然是你,你的代码审查带宽决定了能真正并行运行多少个,而非工具本身。
技能:告别每次重复解释项目
技能让你不再像金鱼一样,在每个会话里都重新解释一遍项目背景。两款工具采用相同的格式:一个文件夹,内含 SKILL.md,存放指令和元数据,并可附带脚本、参考资料、资产文件。在 Codex 中,你可以用 $ 或 /skills 调用技能,或者当你的任务匹配到技能描述时自动触发,这也正是严谨而刻板的描述胜过花哨描述的原因。Claude Code 的做法如出一辙,我在《文件夹即代理》中已详细记录过这一模式。
技能也是避免意图反复耗费你的地方。我在《从单例到系统级架构》中论述过:代理每次会话都是冷启动,它会用自信的猜测来填补你意图中的任何空白。而技能就是将那份意图以外部化形式固定下来:约定、构建步骤、“那次事故以后我们就不再这么做了”之类的经验,一次性写成,代理每次运行时都能读到。没有技能,循环在每轮迭代中都要从零开始重新推导你的整个项目;有了技能,知识便能沉淀叠加。
有一点需要明确:技能是编写格式,插件是分发方式。当你想跨仓库共享一个技能,或把几个技能打包到一起时,就把它们封装成插件。这在 Codex 和 Claude Code 中都是如此。
插件与连接器:让循环触达你的真实工具
一个只能看见文件系统的循环,格局十分有限。基于 MCP 构建的连接器,能让代理读取你的 issue 追踪器、查询数据库、请求 staging 环境的 API、以及在 Slack 中发送消息。Codex 与 Claude Code 都支持 MCP,因此你为其中一方编写的连接器通常能在另一方直接使用。而插件可将连接器和技能打包在一起,以便团队成员一键安装你的整套配置,无需凭记忆重建一切。
这就是一个只会说“这是修复方法”的代理,与一个能自行打开 PR、关联 Linear 工单、并在 CI 通过后 ping 相关 频道 的循环之间的差别。连接器正是循环能在你的真实环境中执行操作,而不仅仅是空谈“假如我能做就会如何”的原因所在。
子代理:让构建者远离检查者
循环中最有用的结构性设计,无疑是分离编写者与检查者。编写代码的模型在给自己的作业打分时,总是过于宽容。使用不同指令(有时甚至是不同模型)的第二个代理,会捕捉到第一个代理自我说服时忽略的问题。
Codex 只会在你要求时生成子代理,并行运行它们,然后将结果汇总到一个回答中。你可以在 .codex/agents/ 中用 TOML 文件定义自己的代理,每个文件包含名称、描述、指令以及可选的模型和推理强度。这样,你的安全审查代理可以是一个高推理强度下的强模型,而你的探索代理可以是一个只读的快速代理。Claude Code 同样通过 .claude/agents/ 中的子代理以及在代理间传递工作的代理团队来做到这一点。两者的常见分工是:一个代理探索,一个代理实现,另一个代理按照规格进行验证。
一次循环的样貌
将所有部分组合到一起,一条线程就变成了一个小型控制面板。以下是我反复使用的一种形态。
每天早晨,一个自动化任务在仓库上运行。它的提示会调用一个分诊技能,读取前一天的 CI 失败记录、待解决问题和最近的提交,并将结果写入一个 Markdown 文件或 Linear 面板。对于每一项值得处理的发现,线程会打开一个隔离工作树,并派遣一个子代理起草修复方案,再派遣第二个子代理根据项目技能和现有测试审查该草案。
连接器让循环能够创建 PR 并更新工单。循环无法处理的内容会落入我的分诊收件箱。状态文件是整个流程的脊柱,它会记住哪些尝试了、哪些通过了、哪些仍然未关闭,这样明天早上的运行就能从今天中断的地方继续。
请注意你实际做了些什么。你只做了一次设计,没有为任何步骤编写提示。这就是 Steinberger 观点的完整体现,而且无论用 Codex 还是 Claude Code,流程都是相同的,因为这些组件是通用的。
在云栈社区,我们经常探讨如何从工具使用者转变为系统设计者,这正是循环工程所倡导的思维跃迁。
循环仍不能替你做的事
循环能改变你的工作,但并不能将你从中移除。而且,随着循环变得更好,三个问题只会愈加尖锐,而非更容易。
验证依然落在你身上。无人值守的循环同样也是无人监督地犯错的循环。你拆分验证子代理与构建者代理的全部原因,就是要让循环的“已完成”变得有意义。即便如此,“已完成”依然只是一种声明,而非证明。我一直挂在嘴边的一句话来自于《线束决定一切》:你的工作是交付你确认过能正常运行的代码。
如果你放任不管,你的理解力仍会腐化。循环以越来越快的速度交付你未亲自编写的代码,这会使实际存在的东西与你真正理解的东西之间的鸿沟越来越大。这就是《框架之死,线束之崛起》,一个顺畅的循环只会让鸿沟扩张得更快,除非你去阅读循环所创造的内容。
没错,舒适的状态很可能也是最危险的。当循环自行运转时,放弃自己的判断、直接接受它给的任何成果是非常诱人的。我在《Anthropic 刚刚从零重建了代理架构》中提到过这一点。当你带着判断力去设计循环时,设计本身就是解药;当你为了逃避思考而设计时,它就成了加速器。同样的行为,相反的结果。
构建循环,永葆工程师本色
这就是为什么循环设计比提示工程更难,而非更简单。Cherny 的观点并不是工作变轻松了,而是杠杆点转移了。
引用链接
- https://x.com/addyosmani/article/2064127981161959567/media/2064126331147948033