从 Prompt 工程到 Loop 工程:让 Agent 自己推进工作的系统设计
过去我们使用 coding agent 的方式,通常还是围绕“我该怎么提示它”展开:写一条 prompt,等它执行,检查结果,再继续补一条 prompt。这个模式能提高效率,但它本质上仍然是人工驾驶。人负责启动每一步,agent 只是执行每一步。
Loop engineering 试图把这个关系反过来:人不再亲手写每一条 prompt,而是设计一个会替你写 prompt、会自己触发、会自己检查状态、会自己推进任务的系统。换句话说,人的工作从“提示 agent”变成了“设计提示 agent 的循环”。
Peter Steinberger 对这个变化的表达很直接:不要再一直 prompt coding agent,而应该设计能 prompt agent 的 loop。Boris Cherny 也提到过类似观点:他不再手动 prompt Claude,而是让 loop 运行起来,由 loop 去 prompt Claude 并判断下一步该做什么。
这背后不是一个新的提示词技巧,而是一种新的工程组织方式。
先看人机协作的三个阶段
在进入 loop 之前,可以先把 coding agent 的使用方式分成三个阶段。
第一阶段是逐行驾驶。开发者手写代码,agent 或自动补全工具只是在旁边补几行、改几行。模型更像是一个逐行听指挥的工具,人仍然掌控所有上下文、节奏和判断。
第二阶段是并行手动。开发者同时开多个 agent 会话,让它们分别处理不同问题。这个阶段已经开始出现并行化,但每个会话仍然要由人发起、解释、追问和验收。你可能同时开 5 到 10 个会话,但它们仍然依赖你不断投喂 prompt。
第三阶段才是自主 loop。系统自己读取仓库、issue、CI、日志或状态文件,自己判断接下来该 prompt 什么,自己把任务拆给 agent,自己跑验证,最后把结果写回 PR、ticket 或状态文件。此时,开发者不再是每一步的提示者,而是 loop 的设计者和监督者。
这个阶段的本质变化是:agent 不再只是一段对话,而变成了一个有记忆、会调度、能自评的长期进程。
什么是 Loop Engineering
Loop engineering 可以用一句话概括:
你不再亲手写每一条 prompt,而是设计那个替你写 prompt 的系统。
这里的 loop 不是把一个 prompt 重复执行很多次, 更像一个工程化的闭环:有触发条件,有任务来源,有上下文读取,有执行者,有验证方式,有状态记录,也有下一次运行时能接上的记忆。
一个成熟的 loop 至少要回答几个问题:
- 它什么时候启动?
- 它从哪里知道该做什么?
- 它如何把问题拆开?
- 它如何避免多个 agent 互相踩文件?
- 它如何验证结果是好的?
- 它如何把当前状态留给下一轮?
- 它什么时候该停下来,交给人处理?
如果这些问题没有被设计清楚,就只是“自动化地发 prompt”。如果这些问题被系统性解决,才是 loop engineering。
Loop 的由来
严格说,loop 不是 2026 年才出现的新概念。更早的 agent 论文和工程实践里,已经有“一个模型生成、另一个模型评估、反复优化”的 evaluator-optimizer 模式,也有“一个模型调度多个 worker”的 orchestrator-workers 模式。它们本质上都在描述同一类结构:模型不是孤立地回答一次,而是在工具反馈和环境反馈中反复行动。
真正变化的是门槛。过去要搭一个 loop,往往要自己写一堆脚本、cron、队列、状态文件和集成代码。现在,自动化、worktree、skill、connector、sub-agent、MCP 这类能力开始被直接放进 Codex、Claude Code 等产品里。于是 loop engineering 不再只是少数团队的内部脚手架,而变成了普通开发者也能尝试的工作方式。
这也解释了为什么它突然被讨论起来:不是因为“循环调用模型”这件事刚刚被发明,而是因为相关能力从自制系统变成了产品能力。工程师需要思考的重点,也从“怎么把这些零件拼起来”变成了“什么任务值得进入这个循环,以及循环里应该放什么约束”。
一个 Loop 由什么搭起来
有几个关键部分:自动触发、Worktree、Skill、连接器、子 agent 和记忆。它们共同解决的是同一个问题:让 agent 不依赖人的即时输入,也能持续推进工作。
自动触发:让系统自己开始跑
loop 需要一个心跳。它可以是定时任务,也可以是 CI 失败后的触发,也可以是 issue 进入某个状态后的触发。
关键点是:不需要人每天打开对话框说“帮我看看今天要做什么”。系统应该能在合适的时间自己启动,自己检查是否有新任务,自己决定是否值得进入下一步。
这一步把“人发起对话”变成了“系统发现任务”。
Worktree:让多个 agent 互不干扰
当多个 agent 并行处理问题时,隔离非常重要。Worktree 的价值在于让每个 agent 在独立的分支或目录里工作,避免互相覆盖文件、污染上下文或制造难以合并的修改。
没有隔离,多 agent 很快会变成混乱的并发编辑。有了 worktree,每个问题都可以被放进自己的工作空间,最后再通过 PR、patch 或合并流程进入主线。
这一步把“并行会话”变成了“可管理的并行工程流”。
Skill:把意图写下来,而不是每次重新解释
Skill 的作用是把稳定的做事方式写进文档,例如 SKILL.md。它可以规定代码风格、提交方式、测试要求、领域约束、排查步骤,以及 agent 每次开始前必须读取的背景。
这件事看似简单,实际是在偿还“意图债”。很多团队的上下文只存在于人的脑子里或某次对话里,agent 一旦换会话就会忘。Skill 把这些隐含规则外部化,让每次运行都有一致的行为基础。
这一步把“临时解释”变成了“可复用的操作规范”。
连接器:把 loop 接到真实世界
loop 如果只能读本地仓库,能力会很有限。连接器,尤其是 MCP 这类机制,可以让 agent 接入 issue、数据库、Slack、PR、ticket、CI 日志等外部系统。
这意味着 loop 不只是在代码里空转,而是能理解真实工作流:哪个 issue 需要处理,哪个 PR 需要更新,哪个测试失败,哪个 ticket 需要回复。
这一步把“代码生成”变成了“工作流执行”。
子 Agent:把写和审拆开
一个有效的 loop 不应该只让同一个 agent 一路写到底。更可靠的方式是做角色拆分,例如一个子 agent 负责实现,另一个子 agent 负责审查,必要时再有第三个 agent 负责整理说明或更新文档。
这种拆分的意义不是形式上的“多 agent”,而是制造独立视角。写代码的 agent 很容易为自己的结果找理由,审查 agent 则应该站在测试、边界条件和维护成本的角度挑问题。
这一步把“单次生成”变成了“内部评审流程”。
记忆:把状态放在对话之外
agent 会忘,但文件不会忘。loop 需要把状态写在对话之外,例如 Markdown 文件、Linear ticket、issue 评论、PR 描述或专门的状态文件。
状态文件要记录当前做到了哪里、遇到了什么阻塞、下一轮应该从哪里继续、哪些判断已经做过。这样下一次 loop 启动时,不需要重新理解一切,也不容易重复走弯路。
这一步把“一次性会话”变成了“可连续运行的进程”。
规格和计划:让 loop 不只是继续跑
记忆并不只是一份流水账。真正有用的长期 loop,通常还需要两类文档:规格文件和计划文件。
规格文件描述“我们到底要造什么”,例如 specs/、VISION.md 或 AGENTS.md。它不是让 agent 立刻写代码,而是在项目早期通过充分讨论,把需求、约束、边界和设计目标拆成可反复读取的文件。这样每一次 loop 都不会只依赖当前上下文里的零散片段。
计划文件描述“下一步怎么推进”,例如 fix_plan.md。它要记录未完成项、已验证项、已发现但暂时不处理的问题,以及优先级。loop 每次启动时先读计划,再决定这一轮只处理哪一项。这样系统既能长期推进,又不至于每次重新规划一遍。
Ralph 的实践里还有一个重要细节:AGENT.md 可以成为 loop 的操作手册。它记录如何编译、如何运行测试、哪些命令曾经踩坑、哪些发现应该沉淀下来。如果 agent 在运行中学到新的项目知识,就应该把它简短写回这些文档。这样 loop 不只是消耗上下文,也在逐步改进自己的工作条件。
一圈 Loop 可以怎样跑完
把上面的构件拼起来,一个早晨自动运行的 loop 可以长这样:
- 定时任务到点触发,loop 自己启动。
- loop 读取诊断 skill,检查 CI 失败、最近提交和待处理 issue。
- loop 为每个问题开一个独立 worktree。
- 实现 agent 在各自 worktree 中修复问题。
- 审查 agent 对修改进行复查,要求补测试、改边界条件或回滚不合格方案。
- 验证通过后,连接器负责开 PR、更新 ticket 或写入评论。
- loop 把本轮状态写进状态文件,记录明天继续要看什么。
这套流程里,人只在一开始设计过 loop。中间每一步都不需要人手写 prompt。人真正需要介入的地方,是制定边界、审查关键结果、处理无法自动判断的产品或架构问题。
这就是 loop 的核心价值:不是让 agent 少问你一句,而是让一整段重复性的工程流程自己跑完。
最小可行 Loop:先别急着造“蜂群”
很多人一听 loop,就会想到大量 agent 并行、自动开 PR、自动修 CI、自动发布。但更稳妥的做法是先搭一个最小可行 loop。
一个最小可行 loop 只需要四个东西。
第一,一个自动触发器。它可以是定时任务,也可以是手动触发的 /loop 或 /goal。关键是它有明确的开始条件和停止条件。
第二,一个 skill 或项目说明文件。它保存项目上下文、运行命令、代码规范、测试要求和边界约束,让 agent 不必每次从零猜测。
第三,一个状态文件。它记录本轮做了什么、下轮接着做什么、哪些问题已经放弃或移交给人。
第四,一个硬门禁。它可以是测试、类型检查、lint、构建、静态分析、安全扫描,或者某种能明确失败的验证。没有门禁,loop 只是在让模型反复说服自己。
顺序也很重要:先让一次手动运行可靠,再把经验写进 skill,然后包成 loop,最后再设为定时执行。不要一开始就追求复杂编排。复杂度应该来自已经被证明有效的流程,而不是来自对自动化的想象。
Backpressure:Loop 里最重要的是“会拒绝”
生成代码已经越来越便宜,真正难的是让系统知道什么结果不能接受。Ralph 的实践把这件事称为 backpressure:在 loop 的每一轮里放入能拒绝坏结果的压力。
backpressure 可以来自很多地方:编译器、类型系统、单元测试、端到端测试、静态分析、安全扫描、性能基准、格式检查。核心不是工具名字,而是它必须能把错误结果挡下来。
一个没有 backpressure 的 loop,很容易变成“生成 -> 自我解释 -> 继续生成”的闭环。它看起来很忙,但没有真实反馈。一个有 backpressure 的 loop,则会被外部事实约束:编译不过就是不过,测试失败就是失败,安全扫描不通过就是不通过。
这里还有一个速度问题。门禁越强,正确性越高;但门禁太慢,loop 的迭代速度会被拖垮。工程上需要在正确性和反馈速度之间取平衡。比如每轮先跑本次改动相关的局部测试,阶段性再跑完整测试;搜索和分析可以多 agent 并行,但构建和测试这种重资源操作要限制并发,避免把机器资源打满。
一次只做一件事
Ralph 的另一个经验是:每个 loop 尽量只处理一个 item。上下文窗口不是无限的,任务越散,agent 越容易把多个问题混在一起,最后产出一堆看似相关、实际难以验收的修改。
“一次只做一件事”并不是低效,而是在保护 loop 的可验证性。一个 item 对应一个规格、一个改动范围、一组测试和一个明确的完成条件。这样失败时容易回滚,成功时容易合并,下一轮也知道从哪里继续。
如果项目已经非常稳定,可以逐步放宽限制,让 loop 一次处理更多同类任务。但当它开始跑偏、重复实现、误删代码或产生大量占位实现时,就应该重新收窄到单一 item。
并不是所有事情都值得做成 Loop
有一个很重要的提醒:多数人其实还不需要 loop。
loop 有搭建成本,也会消耗 token、计算资源和维护精力。它适合的是那些重复发生、验证明确、工具链成熟的任务,而不是一次性的临时需求。
判断一件事是否适合做 loop,可以看四个条件。
第一,它是否每周以上重复发生。一次性的事情不值得搭 loop,重复出现的问题才值得沉淀成系统。
第二,它是否能自动验证。测试、类型检查、lint、构建、回归脚本都能让 loop 自己判断结果。如果结果只能靠人主观判断,loop 很容易跑偏。
第三,预算是否扛得住浪费。loop 会反复读取、重试、回滚、探索,这些都会消耗 token 和时间。如果成本比人工处理还高,就没有必要强行自动化。
第四,agent 是否有足够深的工具。它需要能看日志、复现环境、运行测试、调用自己写的代码,也需要能接触真实任务来源。工具不够深,loop 就只能停留在表面文本处理。
四条都满足,loop 值得搭。缺一条,往往只是在自动化一个还没有准备好被自动化的流程。
更具体地说,适合作为第一批 loop 的任务通常包括:CI 失败归因、依赖升级 PR 草稿、lint 自动修复、flaky test 复现、强测试覆盖代码上的 issue-to-PR 草稿。
不适合作为第一批 loop 的任务包括:架构重写、认证和支付等高风险代码、生产发布、模糊的产品决策、以及任何“完成”主要依赖主观判断的工作。
在真正启动之前,还应该加上三个护栏:限制 token、限制迭代次数、限制运行时间。并且在合并、部署、权限变更、依赖升级这类动作前保留人工审查。loop 可以自动化打字和尝试,但不应该自动化最终责任。
真正的瓶颈会转移到 Review
loop 会提高产出速度,但它不会自动提高团队吸收变化的能力。很多时候,代码生成不是瓶颈,review 才是瓶颈。
当 loop 能快速制造 PR、修复建议和变更集时,团队很容易从“没人有时间写”变成“没人有时间看”。如果 review 能力没有同步提升,loop 只会把等待队列变长。
这也是子 agent 评审为什么重要。它能过滤一部分低级问题,把“明显不该交给人看的东西”挡在前面。但子 agent 评审不能替代最终工程判断。它更像预检,不是批准。
衡量 loop 的效果,也不应该只看它消耗了多少 token、跑了多少轮、生成了多少代码,而应该看“每个被接受变更的成本”。如果 loop 跑了很多、提交很多,但最后能合并的很少,它只是把成本换了一种形式。
最大风险:理解债
loop 越快交付你没有亲手写的代码,仓库里的东西和你脑子里真正理解的东西之间,差距就越大。这个差距可以叫理解债。
理解债不是 agent 独有的问题,但 loop 会放大它。因为 loop 的目标就是减少人的逐步参与,让系统自己推进。推进越顺,人越容易只看结果,不看过程。短期看速度变快了,长期看可能出现一个危险局面:代码在增长,负责人对代码的真实掌控却在下降。
所以要去搭 loop,但要像一个打算继续当工程师的人那样搭它,而不是像一个只会按启动键的人那样搭它。
这意味着 loop 必须有边界、有审查、有记录、有停止条件。人不能把理解责任完全外包给 agent。真正有价值的 loop,是把重复劳动交给系统,把判断责任留给工程师。
理解债还有一个更隐蔽的来源:测试本身也会失去语境。agent 可能会写出一个能通过当前场景的测试,但下一轮 agent 并不知道这个测试为什么重要。比较好的做法是让测试、规格或文档记录“为什么存在”,而不只是记录“测了什么”。这样未来的 loop 在面对失败测试时,更不容易直接删掉它或改弱它。
Ralph 案例给出的落地经验
Geoffrey Huntley 的 Ralph 实践比较极端:他把 loop 用在构建编程语言和编译器这类长期任务上。这个案例不适合照搬到所有业务项目,但它提供了几个很实用的工程经验。
第一,主上下文应该像调度器,不要什么都塞进去。昂贵的搜索、总结、验证可以交给子 agent,主线程负责决定下一步和汇总状态。
第二,不要默认“代码里没有实现”。agent 依赖搜索工具,而搜索结果可能不完整或被误读。修改前应该要求它多路径搜索、并行检查,再决定是否新增实现。否则很容易出现重复实现。
第三,要持续捕获发现。发现 bug 就修,暂时不能修就写进 fix_plan.md;发现新的运行方式,就更新 AGENT.md;发现规格缺口,就补规格。长期 loop 的资产不是某一次输出,而是这些会被下一轮读取的外部记忆。
第四,要接受 loop 会把仓库弄坏。越自主的 loop,越需要恢复策略:什么时候回滚,什么时候让另一个 agent 制定修复计划,什么时候停止自动化交给人。这不是失败,而是长期自动化的正常工程成本。
Ralph 的价值不在于告诉我们“所有项目都该这样跑”,而在于提醒我们:loop engineering 不是一句口号,它需要任务切分、上下文预算、验证门禁、计划文件、状态回写和人工判断共同存在。
从 Prompt 到 Loop,人的角色变了
Prompt engineering 关注的是“这句话怎么写,模型才会给我好结果”。Loop engineering 关注的是“这个系统怎么设计,agent 才能持续、可靠、可追踪地推进工作”。
前者的单位是一条指令,后者的单位是一段流程。前者优化对话,后者优化工程系统。前者把人放在每一步中间,后者把人放在系统设计、边界设定和结果验收的位置。
这不是说 prompt 不重要了。恰恰相反,prompt 仍然重要,只是它不再主要由人手写,而是由系统根据状态、上下文、任务来源和历史记忆动态生成。人的责任变成了设计这个生成 prompt 的环境。
未来更有价值的能力,可能不是写出某条神奇 prompt,而是能搭出一个稳定的工作回路:它知道什么时候开始,知道该读什么,知道该派谁去做,知道怎么验证,也知道什么时候该停下来问人。
这就是 loop engineering 的真正含义:把 agent 从一次性工具,变成可以被工程化管理的长期协作者。