Loop Engineering 完整导读:从提示 Agent 到设计循环

原文:Loop Engineering
作者:Addy Osmani
发布时间:2026-06-07
说明:本文是基于原文公开内容整理的中文导读、摘译和延伸理解,不是逐字全文翻译。文章尽量覆盖原文结构、论点、例子和实践含义;完整表达和上下文请阅读原文。
过去两年,AI 编程的核心能力很大程度上取决于一个人会不会写 prompt。
你把需求讲清楚,补充上下文,等 Agent 返回结果,再继续追问、修正、补充。这个模式本质上还是“人牵着 Agent 走”:人负责发现任务、拆解任务、发起下一步、判断是否完成。
Addy Osmani 在《Loop Engineering》里讨论的是另一种变化:以后真正重要的可能不再是你亲自提示 Agent,而是你设计一个系统,让这个系统持续提示 Agent。
这就是 Loop Engineering。
它不是简单的自动化脚本,也不是把 prompt 放进 cron。更准确地说,它是一套围绕 AI 编程 Agent 的工作循环:
- 自动发现和整理任务;
- 在隔离环境里分发工作;
- 读取项目知识和团队规则;
- 接入真实工具链;
- 让不同 Agent 分别执行和验证;
- 把进度和状态写到会话外部。
换句话说,人不再只是在对话框里写下一条 prompt,而是在设计一个可以持续运转的“工程控制系统”。
Addy 在原文里引用了两个很有代表性的判断。Peter Steinberger 的意思是,开发者不应该再只是在提示 coding agent,而应该设计会提示 agent 的循环。Anthropic Claude Code 负责人 Boris Cherny 也表达过类似观点:他的工作重点已经从直接 prompt Claude,转向编写会自己提示 Claude、自己判断下一步的 loop。
这两个判断背后有一个共同变化:AI 编程的杠杆点正在上移。
过去的杠杆点在 prompt。谁能写清楚需求、补足上下文、反复追问,谁就能从 Agent 里拿到更好的结果。现在的杠杆点开始变成系统设计:谁能让任务自动浮现、让执行和验证分离、让状态跨会话保留、让 Agent 接入真实工具链,谁就能把 AI 编程从“单次对话”推进到“持续流程”。
这也是 Loop Engineering 和 Agent Harness Engineering 的区别。Harness 更像是为单个 Agent 设计运行环境:它能访问什么文件、能调用什么工具、怎样测试、怎样提交结果。Loop 则站在更高一层:它让 harness 周期性启动,能创建多个 helper,能把结果写回状态系统,再根据状态决定下一步。
可以把它理解成:Harness 是一个 Agent 的工作台,Loop 是多个工作台持续运转的调度系统。
一、Loop Engineering 解决的是什么问题
单次对话里的 Agent 很强,但它有几个天然限制。
第一,它容易只看到当前会话。今天修了什么、昨天失败了什么、哪些问题已经尝试过,如果没有外部记录,下一次运行就可能重新摸索。
第二,它很依赖人类推动。你不发下一条指令,它就不会继续发现任务、拆分任务、验证结果。
第三,多 Agent 并行时很容易混乱。两个 Agent 同时改同一批文件,最后冲突的不是模型,而是工作区。
第四,Agent 往往会高估自己的完成度。写代码的 Agent 也负责判断自己是否完成,这在工程上不是一个可靠结构。
Loop Engineering 的目标,就是把这些脆弱点系统化处理:让任务发现、执行、验证、记忆和交接都变成循环的一部分,而不是每次都靠人临场补救。
二、一个循环需要哪些组件
Addy 把这套循环拆成五个核心组件,再加一个外部记忆层。
用更工程化的方式看,这六个东西分别回答六个问题:
| 组件 | 回答的问题 |
|---|---|
| Automations | 任务什么时候自动出现? |
| Worktrees | 多个 Agent 如何并行而不互相覆盖? |
| Skills | 项目知识如何稳定传给每次运行? |
| Plugins / Connectors | Agent 如何接入真实工作系统? |
| Sub-agents | 谁负责执行,谁负责验证? |
| State / Memory | 单次会话之外,进度记在哪里? |
原文还强调一点:这些能力已经不再只属于某个自制脚本。Addy 认为,现在 Codex 和 Claude Code 里都已经具备这些构件,只是名字和入口略有不同。因此真正值得思考的不是“押注哪个工具”,而是设计一套不依赖单一工具形态的循环。
1. 自动化:循环的心跳
自动化让循环从“一次运行”变成“持续运行”。
比如每天早上自动扫描:
- 最近失败的 CI;
- 新增 issue;
- 昨天合入的代码;
- 测试覆盖率变化;
- 用户反馈和告警。
如果没有发现问题,自动归档;如果发现值得处理的问题,就进入 triage 队列,等待人确认或直接进入下一步。
这类自动化不只是定时任务。关键在于它能调用项目里的 skill、连接外部系统、生成结构化结果,并把结果写到一个后续 Agent 能继续读取的位置。
在 Codex App 里,这对应 Automations:你可以选择项目、prompt、执行频率、运行环境;如果自动化发现了值得处理的事情,结果会进入 triage inbox;如果没有发现问题,就自动归档。
在 Claude Code 里,类似能力更多由 scheduled tasks、cron、hooks、GitHub Actions、/loop 和 /goal 组合出来。/loop 偏向按固定节奏重复运行;/goal 偏向持续工作,直到某个明确条件成立。
这里最关键的是停止条件。比如不要只写“修好 auth 测试”,而要写成“test/auth 下所有测试通过,并且 lint clean”。这样循环不是凭感觉结束,而是根据可验证结果结束。
原文特别提到,/goal 这类机制通常会把“是否完成”的判断交给另一个模型或检查器,而不是让刚写完代码的 Agent 自己裁决。这一点非常重要,因为它把 maker 和 checker 的分离推进到了循环终止条件本身。
2. Worktree:让并行不互相踩脚
一旦你同时运行多个 Agent,文件冲突就会变成真实问题。
Git worktree 的价值在这里非常直接:每个 Agent 在自己的独立工作区和分支里修改代码,共享同一个仓库历史,但不会直接覆盖另一个 Agent 的文件。
这并不会消除所有协作成本。最后仍然需要人审查、合并、处理冲突、判断方向。但它至少把“多个 Agent 同时写同一份文件”的机械混乱隔离开了。
对个人开发者来说,worktree 可能是从“一个 Agent 帮我写代码”升级到“多个 Agent 并行工作”的第一道门槛。
Codex 的做法是把每个线程放在独立 worktree 中,让多个线程可以同时处理同一个仓库。Claude Code 则可以通过 git worktree、--worktree 或 sub-agent 的 worktree 隔离配置实现类似效果。
不过 worktree 只解决机械冲突,不解决判断冲突。它能避免两个 Agent 覆盖同一个工作区,却不能替你判断哪条实现路线更好、哪个 PR 应该合并、哪次重构其实引入了理解成本。
所以 Addy 提到一个现实限制:并行能力的上限不是工具,而是人的 review bandwidth。你可以同时启动十个 Agent,但你未必能认真审查十份结果。Loop Engineering 不是无限并发,而是受控并发。
3. Skills:把项目知识写到系统外面
每次新会话都重新解释项目背景,是 AI 编程里非常高的隐性成本。
Skill 的作用,就是把这些重复解释的内容沉淀下来:
- 项目的目录结构;
- 常用命令;
- 测试和发布方式;
- 代码风格;
- 设计系统;
- 已知坑位;
- 团队不希望采用的方案;
- 某些历史决策背后的原因。
这样 Agent 不需要每次从零猜项目。循环每跑一次,都可以先读取这些稳定规则,再决定怎么执行。
这也是为什么 skill 的描述要清楚、朴素、可触发。它不是写给人炫技的文档,而是写给未来每一次 Agent 运行的操作说明。
原文里有一个很重要的区分:skill 是知识和能力的作者格式,plugin 是分发方式。
也就是说,你可以先在一个仓库里写一个 SKILL.md,告诉 Agent 这个项目怎么构建、怎么测试、哪些文件不能碰、遇到某类任务应该先读哪些文档。等这套能力稳定之后,再把一个或多个 skills 打包成 plugin,在多个项目或团队之间复用。
这解决的是“意图债”的问题。Agent 每次进入新会话时都是冷启动,如果你没有把意图写下来,它会用自信的猜测填补空白。循环跑得越频繁,这种猜测的累计代价越高。Skill 的价值就是把人的意图放到上下文之外,让每次运行都能继承。
4. 插件和连接器:让循环碰到真实世界
如果 Agent 只能读写本地文件,它能做的事有限。
真正有用的循环,通常要连接到真实工作系统:
- GitHub;
- Linear 或 Jira;
- Slack;
- Gmail;
- 数据库;
- 内部 API;
- 监控和日志平台;
- 文档系统。
有了连接器,循环就不只是“建议你修复这个问题”,而是可以读取 issue、创建分支、提交 PR、更新工单、等待 CI、通知相关人。
这也是 AI Agent 从“代码助手”走向“工程流程参与者”的关键。
原文把 connectors 看成循环接触真实环境的桥。它们通常基于 MCP,让 Agent 可以读取 issue tracker、查询数据库、访问 staging API、给 Slack 发消息、更新 Linear ticket。
这会带来一个质变:没有连接器时,Agent 最多说“你应该创建一个 PR、关联某个工单、通知某个频道”。有连接器时,循环可以真的创建 PR、关联工单、等待 CI、再在通过后通知团队。
也正因为如此,连接器必须被当成权限边界来设计。能读什么、能写什么、能不能发消息、能不能改生产数据,都应该明确。Loop 越自动,权限越要保守。
5. Sub-agents:把执行者和验证者分开
原文里最值得重视的一点,是不要让写代码的 Agent 同时担任最终裁判。
写代码的 Agent 很容易相信自己的实现已经完成。它可能跑了部分测试,看到结果不错,就认为任务结束。但真实工程里,“看起来完成”和“可以交付”之间还有一段距离。
更可靠的结构是:
- 一个 Agent 负责探索;
- 一个 Agent 负责实现;
- 一个 Agent 负责审查和验证;
- 必要时再由人做最终判断。
验证 Agent 最好有不同的提示词、不同的检查清单,甚至不同的模型。它不需要认同实现 Agent 的路径,它只需要回答:这个结果是否真的满足目标?
在无人值守的循环里,这个结构尤其重要。因为循环跑得越自动,错误也越可能自动放大。
Codex 和 Claude Code 都支持类似的 sub-agent 模式。你可以定义专门的 explorer、implementer、reviewer、security reviewer、test fixer。不同 sub-agent 可以有不同的指令、不同模型、不同推理强度和不同权限。
原文的建议不是“所有事情都开一堆 sub-agent”,而是在值得付出 token 成本的地方使用第二意见。比如安全审查、迁移脚本、认证逻辑、支付流程、数据删除、生产配置,这些场景里 checker 的价值很高。
一个常见分工是:
| 角色 | 主要职责 |
|---|---|
| Explorer | 读代码、找模式、判断影响范围 |
| Implementer | 根据计划修改代码 |
| Verifier | 根据验收标准跑测试和审查结果 |
| Reviewer | 从可维护性、安全性、产品行为上提出反对意见 |
这种结构不是为了显得复杂,而是为了避免“写代码的人也给自己打分”。
三、外部记忆是循环的骨架
除了五个组件,Loop Engineering 还需要一个会话外的状态层。
它可以是一个 Markdown 文件,也可以是 Linear board、issue 列表、数据库表或任何稳定的记录系统。重点不是形式,而是它必须活在单次对话之外。
一个好的状态文件至少应该记录:
- 当前目标;
- 已经完成的任务;
- 正在处理的任务;
- 失败过的路径;
- 验证结果;
- 下一步建议;
- 人类已经做过的判断。
这件事看起来很朴素,但它决定了循环能不能跨天、跨会话、跨 Agent 延续。
没有外部记忆,Agent 每次都会重新开始。
有了外部记忆,循环才可能累积进度。
原文把这个点讲得很直接:模型会忘,仓库不会忘。
这句话非常适合拿来理解长时间运行 Agent。上下文窗口再大,也不是可靠的项目记忆。真正可靠的是落到磁盘、工单、数据库或版本历史里的状态。
对一个工程 loop 来说,状态文件不应该只写“完成了什么”,还应该写“为什么没做什么”。比如:
- 某个方案因为兼容性问题被放弃;
- 某个测试失败不是本次修改导致;
- 某个依赖升级会触发 breaking change;
- 某个需求需要产品确认;
- 某个 PR 只能人工 review 后合并。
这些信息如果不写下来,明天的 Agent 很可能重新踩一遍。
四、一个可落地的循环长什么样
结合原文思路,一个日常可用的 AI 编程循环可以这样设计:
每天早上,自动化任务启动,读取过去 24 小时的 CI、issue、提交记录和线上告警。它调用一个 triage skill,把发现的问题整理成结构化清单,并写入 agent-progress.md 或项目管理工具。
对于可自动处理的问题,循环为每个任务创建独立 worktree。实现 Agent 在隔离环境中修改代码,验证 Agent 根据项目 skill、测试结果和验收标准进行审查。
如果验证通过,连接器创建 PR、关联 issue,并在 CI 通过后更新状态。如果验证失败,失败原因被写回状态文件,下一轮不会重复走同一条路。
如果任务涉及产品判断、架构方向或风险较高的修改,循环把它放进人工 triage 队列,而不是硬着头皮自动完成。
这套流程里,人真正做的不是反复输入 prompt,而是设计边界:
- 哪些任务可以自动做;
- 哪些任务必须人工确认;
- 验证标准是什么;
- 状态写在哪里;
- 失败后如何恢复;
- 哪些工具可以被调用;
- 什么时候停止。
Loop Engineering 的难点就在这里。它不是让人从工程里消失,而是让人从“每一步都亲自推动”转向“设计系统如何推进”。
把这套流程写成更接近真实工作的版本,大概是这样:
- 早上 9 点,automation 启动。
- 它调用
$triageskill,读取昨天的 CI、issue、commit、错误日志。 - 它把发现的问题分成三类:可自动处理、需要人工确认、暂不处理。
- 对可自动处理的问题,每个任务开一个 worktree。
- Explorer sub-agent 先读代码和历史上下文。
- Implementer sub-agent 修改代码并跑局部测试。
- Verifier sub-agent 根据验收标准审查结果。
- 通过后,connector 创建 PR、更新 ticket、写回状态文件。
- 未通过时,失败原因写回状态文件,任务回到 triage。
- 高风险任务只生成建议,不直接动代码。
这个 loop 看起来像自动化,但它真正设计的是一套工程判断边界。哪些事情可以自动,哪些事情必须暂停,哪些失败要重试,哪些失败要上报,这些都需要人提前定义。
五、它不会替你承担工程责任
原文最后提醒得很克制:循环会改变工作方式,但不会取消人的责任。
我觉得这里至少有三个风险。
1. 自动化会放大错误
手动 prompt 出错,通常只影响一次回复。循环出错,可能每天重复执行,甚至在多个任务上重复执行。
所以越是自动化,越需要清晰的停止条件、验证机制和人工介入点。
尤其要小心“看似成功”的自动化。比如测试通过了,但测试覆盖不到真实用户路径;PR 创建了,但代码风格和架构方向都不对;issue 被关闭了,但问题只是被绕开。Loop 的输出必须被审查,不能只看状态变绿。
2. 理解债会增长得更快
如果循环不断提交你没有读过、没有理解过的代码,你和系统之间的距离会迅速拉大。
短期看,这是效率提升。长期看,这是理解债。等问题爆发时,你可能已经不再知道系统为什么变成今天这样。
这也是为什么 Addy 在结尾强调,他仍然会自己 review 代码。如果完全依赖自动化 loop 修复产品,质量很可能下降,甚至进入越修越乱的下行循环。
3. 最危险的是放弃判断
Loop Engineering 最有价值的地方,是把人的判断前置到系统设计里。
最危险的地方,是让人误以为自己可以不再判断。
同样一套循环,在不同人手里会产生完全不同的结果。理解业务、理解代码、理解风险的人,会用循环放大自己的能力;不愿理解系统的人,只会用循环更快地制造债务。
这也是 Loop Engineering 比 prompt engineering 更难的地方。Prompt engineering 的难点是“怎么问”。Loop Engineering 的难点是“什么应该被自动化、什么不应该、错了如何停下来、谁负责最终质量”。
所以 Addy 最后给出的立场不是“停止 prompt,完全交给 loop”,而是找到平衡:直接提示 Agent 仍然有效,loop 只是把某些重复、明确、可验证的工作提升到系统层。
六、给独立开发者的实践建议
如果你现在还没有自己的 AI 编程循环,不需要一开始就搭很复杂的系统。
可以从三个文件开始:
AGENTS.md
记录项目约定、常用命令、代码风格、测试方式、发布方式和禁用方案。它是 Agent 每次进入项目时的说明书。
agent-progress.md
记录 Agent 做过什么、失败过什么、当前卡在哪里、下一步是什么。它是跨会话的工作记忆。
triage.md
记录每天或每周自动发现的问题,包括 bug、测试失败、性能隐患、文档缺口和可以自动修复的小任务。
然后再逐步加入:
- 定时扫描;
- worktree 并行;
- 专门的验证 Agent;
- GitHub 或 Linear 连接器;
- 自动 PR;
- 更严格的完成条件。
不要一上来追求“全自动工程师”。更现实的目标是:先让 Agent 稳定承担低风险、可验证、可回滚的任务。
结语
Prompt engineering 关注的是“这一轮怎么问”。
Loop Engineering 关注的是“这个系统如何持续推进工作”。
这背后的变化很大。
当 Agent 只能完成单次任务时,人的主要能力是表达需求和修正输出。
当 Agent 可以长期运行、并行运行、连接真实工具时,人的主要能力会变成设计循环、定义边界、建立验证、管理状态。
但这不意味着工程师会被循环替代。
恰恰相反,越自动化的系统,越需要真正懂工程的人设计它。循环能帮你跑得更快,但它不知道你是在积累能力,还是在逃避理解。
真正重要的不是“让 Agent 自己跑起来”,而是:设计一个你愿意负责的循环。