循环工程(loop engineering) -- from 谷歌云AI总监Addy Osmani

循环工程正在取代那些需要人工提示智能体的人员。现在,系统可以自行完成这些任务。可以将循环视为一种递归式的目标,即定义出一个目的,然后让人工智能不断迭代直到完成。大致来说,有五个基本组成部分,而 Claude、Code 以及 Codex 都已经具备了这五个组成部分。

我认为这可能会成为我们处理编码代理的方式的未来。不过,现在还处于早期阶段,我对此持怀疑态度。同时,你也必须小心处理代币成本的问题------如果你拥有大量代币,那么使用模式可能会有很大差异。此外,你还需要找到一种方法来确保质量不会下降,而且关于效率的问题也是需要解决的。不过,让我们来探讨一下这一切到底意味着什么吧。

@steipete 最近说道:"你不再需要提示编程助手了。你应该自己设计那些能够引导助手完成任务的循环结构。"同样,Anthropic 公司的 Claude Code 负责人@bcherny 也表示:"我不再主动提示 Claude 了。我现在让 Claude 去执行循环任务,然后自己决定接下来该做什么。我的职责就是编写这些循环结构。"

那么,这一切到底意味着什么呢?

在大约两年的时间里,人们获取编程帮助的方式是:编写出有效的提示信息,并提供足够的上下文。用户输入一个指令,然后等待反馈,接着再输入下一个指令。编程助手只是一个工具而已,而用户则一直控制着它,一步步地执行指令。这种模式已经逐渐过时了,或者至少有些人认为它即将被取代。

现在,你们需要构建一个小型系统,该系统能够找到工作机会,分配任务,检查任务完成情况,并记录下所完成的工作内容,然后决定下一步的行动。让这个系统自行处理代理任务,而不是由你们亲自操作。我之前写过关于类似系统的内容,那就是"代理框架工程"------它将环境塑造成一个由单个代理所运行的系统,而"工厂模型"则指的是用于构建软件的系统。而"循环工程"则位于"框架工程"之上一层。框架工程依靠计时器来运行,它会生成一些小型辅助程序,并自行供给所需资源。

让我惊讶的是,现在这种工具已经不再像以前那样是独立存在的了。一年前,如果你想创建一个循环,你需要编写一堆 bash 脚本,然后一直维护着这些脚本,它们就只属于你一个人。而现在,这些组件直接被集成到了产品中。施泰因贝格的列表几乎与 Codex 应用程序完全对应,而 Claude Code 也是如此。一旦你注意到这些组件的结构是相同的,你就不再争论应该使用哪种工具了,而是直接设计出一个无论身处哪种环境中都能正常工作的循环。

五件物品,还有一些注释。

一个循环需要五样东西,还需要一个地方来记住这些东西。让我先列出它们,然后再进行说明。

  1. 这些自动化流程会根据预定时间表进行运行,能够自动进行发现和分类处理。
  2. 让两个同时工作的代理不会互相踩到对方。
  3. 需要掌握的能力,就是能够把代理人可能只能凭猜测来掌握的项目知识记录下来。
  4. 这些插件和连接器可以將该代理程序连接到您已经使用的各种工具中。
  5. 副代理人们这样分工:有一个人提出想法,另一个人负责验证其可行性。

然后是第六个要素------记忆。无论是 markdown 文件还是线性记录,任何能够存储多个对话中的信息、并记录下当前操作及后续步骤的东西都算作记忆。听起来可能没什么了不起。但实际上,这是所有长期运行的代理程序所依赖的同一机制。在长时间运行的程序中,模型会在运行之间忘记一切,因此记忆必须存储在磁盘上,而不是在上下文之中。代理程序会忘记,但仓库不会。

这两种产品现在都拥有全部五项功能了。

这些名称在这里和那里有些不同,但功能都是一样的。让我逐一说明吧,因为说实话,细节之处正是循环结构能够紧密结合或悄悄泄露的地方。

自动化系统,这就是生命的节奏

自动化功能使得循环操作真正成为了可重复执行的任务,而不仅仅只是一次性的操作。在 Codex 应用程序中,你可以在"自动化"选项卡中创建自动化任务。你可以指定要执行的项目、提示语、执行频率,以及是在本地环境中还是后台工作树中执行。那些用于查找事物的操作会被发送到分类邮箱,而那些没有找到任何东西的操作则会被直接归档,这非常不错。OpenAI 内部也使用自动化来处理一些繁琐的任务,比如日常问题分类、构建集成测试报告、编写提交说明,或者寻找上周有人添加的错误。此外,自动化任务还可以调用特定技能,这样就能让重复性的操作保持可维护性。你只需调用"$skill-name"即可,而无需将一大堆指令粘贴到调度表中,因为没人会去更新这些指令。

Claude 代码也实现了同样的功能,不过是通过调度和钩子机制来实现的。你可以使用/loop 定期执行提示或命令;也可以安排定时任务;还可以在代理生命周期中的特定时刻执行 shell 命令。如果你希望即使在关闭笔记本电脑后,程序仍能持续运行,还可以将整个系统部署到 GitHub Actions 中。原理完全相同:定义一个自主任务,为其设定周期,然后通知会定期收到相关通知,这样就不需要你亲自去检查了。

有一个在会话期间使用的特殊指令值得了解,它正是本文所讨论的核心内容。/loop 按照特定的节奏重复执行。/goal 会持续运行,直到你设定的条件成立为止;每次循环结束后,都会有一个独立的小型模型来检查是否已完成任务,这样编写代码的智能体就不会成为最终评判者。你可以提供类似"所有测试都通过,代码也没有错误"这样的信息,然后就可以离开。Codex 也有类似的机制,同样被称为/goal,它会持续运行,直到有可验证的停止条件成立为止,同时还可以暂停、恢复或清除状态。这两种工具都使用了同样的机制,而这正是本文的核心模式。

这就是该工作的核心部分。环形的其余部分则对其产生作用。

那些平行排列的树木并不会导致混乱。

一旦使用多个代理来操作文件,这些文件就会开始相互冲突,这就是所谓的"故障"。两个代理同时修改同一个文件,简直就是一场麻烦------就像两个工程师同时修改同一行代码,而他们之前没有任何沟通。使用 Git 的工作树可以解决这个问题:它提供了一个独立的工作目录,该目录位于同一个分支上,但共享相同的仓库历史。这样一来,一个代理的修改就不会影响到另一个代理的版本。

Codex 在多个线程同时访问同一仓库时,能够很好地处理工作树的构建问题,从而避免相互干扰。Claude Code 提供了与 Git 工作树相同的隔离功能:通过--worktree 参数可以开启一个独立的工作环境;而"隔离:工作树"设置则让每个辅助工具都拥有自己的独立环境,这样每个工具都可以独立运行,并自行清理工作区域。我在《协调成本》一文中详细讨论了这些方面的复杂性------工作树确实避免了机械性的冲突,但实际上,你能同时运行多少个工具还是由你来决定,而不是由工具本身来决定。

技能吧,所以下次就不用每次都解释你的项目了。

"技能"指的是一种方式,可以让你在每次会话中都不需要重复解释同一个项目内容,就像一条金鱼一样。这两种工具都使用相同的格式:一个包含"SKILL.md"文件的文件夹,其中存放着相关说明和元数据;此外,还可以添加可选的脚本、引用文件以及资源文件。当你使用"$"或"/skills"命令调用某个技能时,或者当你的任务符合该技能的描述时,代码就会执行这个技能。这就是为什么冗长而枯燥的描述不如巧妙的描述有效的原因。Claude Code 也是以同样的方式实现这一功能,而我也将这一模式编写在了代理技能中。

技能也是让意图不再因错误而付出代价的关键所在。我在关于"意图债务"的讨论中提到,每次会话开始时,代理人都会从零开始,用自信的猜测来填补你意图中的空白。而技能则是将这种意图外在化,体现在各种惯例、操作步骤中,比如"因为那次事件,我们不会按照原来的方式来做"。这些技能在每次会话中都会被重复阅读。没有技能的话,每次循环都会从头开始重新构建整个项目;而有了技能之后,这种重复过程就会逐渐累积起来。

需要注意的一点是,所谓的"技能"实际上指的是创作格式;而插件则是用来实现这种格式传输的工具。当你想要在多个仓库之间共享某个技能,或者将多个技能组合在一起使用时,就会将它们打包成插件的形式。在 Codex 和 Claude Code 中,这一概念都是如此应用的。

插件和连接器,这些组件与你的实际工具相连接。

只能访问文件系统的循环其实是非常有限的。而基于 MCP 构建的连接器则可以让代理读取你的问题跟踪数据、查询数据库、调用 staging 接口,甚至可以在 Slack 中发送消息。无论是 Codex 还是 Claude Code,都支持与 MCP 的连接,因此你为其中一个系统编写的连接器通常也适用于另一个系统。此外,插件还可以将连接器和技能整合在一起,这样你的团队成员就可以一次性安装你的配置,而无需重新从内存中重建整个系统。

这就是那种声称"这里有解决方案"的代理程序,与那些会打开 PR、链接线性工单,并在 CI 自行变为绿色后通知通道的循环程序之间的区别。这些连接器正是让循环程序能够在实际环境中发挥作用的原因,而不是仅仅描述一下如果它能够执行哪些操作的话。

副代理人们,请让制造者远离检查员吧。

在循环中,最实用的结构就是让编写代码的人和验证代码的人分开工作。让编写代码的人来负责自我评估,这个模型相当不错。另一个具有不同指令的代理,有时甚至使用不同的模型来检测第一个人所编写的代码,从而发现其中的漏洞。

"Codex"仅在您请求时才会生成子代理程序。它会同时运行这些子代理,然后将结果合并成一个答案。您可以将自己的代理程序定义为 TOML 文件,存放在".codex/agents/"目录下。每个文件都包含名称、描述、指令以及可选的模型和推理工作量等信息。这样,您的安全审查者就可以使用高效的模型进行推理,而您的执行器则可以是某种速度快且只进行只读操作的工具。Claude Code 也类似地处理".claude/agents/"目录中的子代理程序,以及负责分配任务的代理团队。通常情况下,系统会分配一个代理负责探索,另一个负责实施,还有一个负责根据规范进行验证。

一个循环的样子是什么样子的?

坚持下去吧,一条线就能变成一个小控制面板。这是我一直在使用的一种形状。

每天早晨,仓库都会运行一次自动化流程。该流程会调用一个分类技能,用于分析上周的 CI 测试缺陷、未解决的问题以及最近的提交内容,并将分析结果记录到一个 Markdown 文件中或写入 Linear 板中。对于那些值得处理的缺陷,流程会打开一个独立的工作树,并派遣一个子代理来起草修复方案;另一个子代理则会根据项目需求以及现有的测试情况来审核该方案。

这些连接器使得循环能够打开待处理事项并更新工单状态。任何循环无法处理的事情都会被放入我的分类邮箱中。状态文件是整个系统的核心,它记录了哪些任务已经尝试过、哪些任务已经成功解决、哪些任务仍然在等待处理。所以,明天早上时,这些任务会继续从今天开始的处理流程。

看看你们实际上做了什么吧。你们只设计了一遍,并没有实际执行那些步骤。这正是斯坦伯格的观点得到了验证------在《Codex》或《Claude Code》中,这些步骤都是相同的。因为各个部分都是一样的。

而这个循环仍然没有为你做些什么......

这个循环会改变工作内容,但它并不会将你从其中移除。实际上,随着循环变得越来越好,这三个问题反而会变得更加严重,而不是更轻松一些。

没错,那种随遇而动的舒适态度或许是一种冒险的选择。当循环机制自行运转时,人们很容易放弃自己的意见,接受系统给出的任何结果。我将其称为"认知上的屈服"。如果你以评判的态度来使用这个循环机制,那它就是"治疗";而如果你为了避免思考而使用它,那它就变成了"毁灭"。同样的行动,却产生相反的结果。

构建这个循环。保持工程师的专注。

我认为这是我们的工作将如何发展的预兆。不过,如果我不亲自审查代码,或者完全依赖自动化流程来修复问题,那么我的产品的质量就会受到影响。我可能会陷入一个恶性循环,不断把自己推入更深的困境之中。

不过,还是去设置你的循环吧。不过要记住,直接提示你的代理仍然是有效的手段。关键在于找到合适的平衡点。

这些循环的结果也可能因不同的方式而有所差异。两个人可以构建完全相同的循环,但最终得到的结果却截然不同。一个人利用这个循环来更快地完成他们熟悉的工作;而另一个人则完全避免去理解那些工作内容。这个循环并不知道这两者之间的区别------只有你才能明白其中的差异。

这正是使得循环设计比提示工程更困难的原因,而不是更简单的理由。Cherny 的观点并非认为这项工作变得简单了。而是说,其中的控制点已经发生了改变。

构建这个循环。但是,这种构建方式应该像那些真正想要成为工程师的人所采用的那样,而不只是像那些只是按下启动按钮的人所采用的那样。

相关推荐
Mr.朱鹏1 小时前
【FastAPI 全栈实战 | 第2篇】Pydantic 数据校验与响应模型 —— 让 Bug 死在请求进来的那一刻
人工智能·python·fastapi
小林ixn1 小时前
远程 MCP 实战:让 AI 无缝调用地图、浏览器与文件系统
人工智能·agent·mcp
weixin_422329312 小时前
AgentScope Java2.0 版本Builder 本地启动指南
人工智能
studyrunner2 小时前
GPT-5.5 对比 GPT-5.6 Sol、Terra、Luna:官方性能数据与选型分析
大数据·人工智能·gpt
OpenMiniServer2 小时前
大统一逻辑链3.0(GULP3.0):绝对悖论、逻辑链与宇宙演化动力学
人工智能
Asize2 小时前
Agent 入门:从 LLM 与 Agent 的区别到 Function Calling
javascript·人工智能
小林ixn2 小时前
AI Agent的“万能工具箱”:MCP协议实战,让工具调用不再受语言和进程束缚
人工智能·agent·mcp
武子康2 小时前
🔥 GPT-5.6 有限预览全拆解:Sol/Terra/Luna 三档定价 + max/ultra 双推理 + 缓存 1.00×/1.25×/0.10× 三倍
人工智能·chatgpt·openai
CTA终结者2 小时前
近期AI量化工具推荐,围绕最难推进的环节选择
人工智能·python