很多人第一次用 Coding Agent 时,关注点都放在 prompt 上:怎样把需求说清楚,怎样提供上下文,怎样让模型一次性写出更接近预期的代码。这当然重要,但它更像第一阶段的能力。真正的变化在于:我们不再只是在每个回合里提示 Agent,而是在设计一个能持续提示 Agent 的系统。
这就是我理解的 Loop Engineering。
它不是一个新工具,也不是一个更玄的提示词技巧。它是一种工作方式的迁移:从“我盯着 Agent 做下一步”,迁移到“我设计一个循环,让它知道什么时候发现问题、什么时候分配任务、什么时候验证结果、什么时候记录状态,以及什么时候停下来等人判断”。
Prompt 是一次动作,Loop 是工作系统
Prompt 解决的是一次交互:我现在要什么,你现在怎么做。
Loop 解决的是一类工作:什么事情值得做,谁来做,做完怎么验,失败怎么重试,明天怎么接着跑。
这两个层级的差别很大。一个写得很好的 prompt,可以让 Agent 在单次任务里表现更好;一个设计得好的 loop,则可以把很多原本依赖人工巡检、人工分发、人工复盘的流程串起来。
比如日常开发里有很多工作并不复杂,但很消耗注意力:
- 每天看一遍失败的 CI,判断是环境问题还是代码问题。
- 扫描最近的 issue,找出可以快速修复的小缺陷。
- 检查某个模块近期改动后有没有文档滞后。
- 对已经生成的代码再做一次安全、性能或边界条件审查。
- 把处理结果写进任务板、PR 描述或项目日志里。
这些任务的共同点是:它们不是一次性的。它们需要被周期性触发,需要保存上下文,需要在多个工具之间流动,也需要一个明确的停止条件。只靠 prompt,人会一直站在循环中间;做 Loop Engineering,人开始设计循环本身。
一个可用的 Loop 需要什么
我会把一个工程 loop 拆成六个部分。
第一是触发器。它决定循环什么时候开始。可以是每天早上的定时任务,可以是 CI 失败后的 webhook,可以是有人创建 issue,也可以是你手动启动一次专项巡检。没有触发器,loop 只是一次普通运行。
第二是隔离环境。只要多个 Agent 或多个任务并行,就需要隔离。最常见的方式是 git worktree:每个任务在自己的分支和目录里工作,互不覆盖。否则 Agent 写得越快,冲突和脏工作区就越难收拾。
第三是项目知识。Agent 每次都从零开始理解项目,会反复犯同样的错。Skills、AGENTS.md、项目规范、检查清单,本质上都是把上下文放到循环外面,让它每次运行都能复用。真正有价值的不是“让模型记住”,而是让项目把规则写下来。
第四是工具连接。一个 loop 如果只能读写文件,它能做的事情有限。连接到 GitHub、Linear、Slack、数据库、部署平台之后,它才有能力完成真实工作流:开 PR、更新任务、通知相关人、读取线上信号。
第五是验证者。写代码的 Agent 不应该独自宣布“我完成了”。更稳的结构是 maker 和 checker 分离:一个 Agent 负责实现,另一个 Agent 按测试、规范和风险清单审查。验证者可以是测试命令,也可以是另一个模型,也可以是人工审批。
第六是状态。状态是 loop 的脊柱。它记录已经尝试过什么、哪些失败过、哪些已经合并、下一步该做什么。这个状态可以是 Markdown 文件,可以是任务看板,也可以是数据库记录。关键是它必须存在于单次对话之外,否则每一轮都会失忆。
最小可落地的 Loop
一个很小但有用的 loop 可以这样设计:
每天早上自动运行一次项目巡检。它先读取昨天的 CI 结果、最近合并的 commit 和打开中的 issue,然后把值得处理的发现写到一个 triage 文件里。对于简单问题,它创建独立 worktree,让一个 Agent 起草修复;另一个 Agent 根据测试和项目规范做审查。通过验证后,它打开 PR,并把处理状态写回 triage 文件。
这个 loop 不需要一次做得很复杂。它只需要满足几个条件:
- 触发条件明确。
- 输入范围可控。
- 输出位置固定。
- 验证标准可执行。
- 失败时能留下足够信息。
- 人可以随时接管。
如果这些条件不成立,loop 越自动,风险越大。它可能每天都在制造你没有看过、没有理解、也没有真正验证过的变化。
