Agent 已经让很多软件开发任务从“人写代码”变成了“人提需求,模型执行”。但实际使用一段时间后,很容易发现一个问题:Agent 虽然能跑长任务,却仍然需要人频繁介入。
常见的交互大概是这样:
- “继续。”
- “还是报错。”
- “先别重构。”
- “你改了什么?”
- “跑一下测试。”
- “不符合预期,重新改。”
- “回滚刚才的改动。”
这些指令看起来像人在和 Agent 协作,实际上暴露了一个更深的问题:很多本该自动完成的验证、反馈和修正,仍然由人在手动驱动。
Loop Engineering 要解决的就是这件事。
它的核心不是让 Agent 多跑几轮,而是把“开发 → 测试 → 验收 → 反馈 → 修正 → 再验收”这条链路明确设计成一个闭环,让 Agent 按照预设目标自动运行,只有在确实无法判断或需要决策时才把人拉回来。
换句话说,Prompt 只是在告诉 Agent 做什么;Loop Engineering 则是在告诉 Agent 如何反复确认自己做对了没有,并在没做对时继续调整。
Agent Loop 和 Loop Engineering 不是一回事
很多人看到 Loop 会先想到 Agent 的基础运行机制。确实,Agent 本身就离不开循环。
大语言模型(LLM,Large Language Model)单独运行时,本质上是一次输入、一次输出。它不会天然连续调用工具,也不会自动把工具结果再拿回来继续推理。要让模型像 Agent 一样持续完成任务,就需要在外层包一层循环。
一个典型的 Agent Loop 是这样的:
flowchart TD
A[用户输入任务] --> B[大语言模型推理]
B --> C{输出类型}
C -->|直接回答| D[返回最终结果]
C -->|工具调用| E[执行工具或函数]
E --> F[把工具结果写回上下文]
F --> B
这套机制解决的是“模型如何连续行动”的问题。模型每次输出后,系统判断它是要直接回答,还是要调用工具。如果需要调用工具,系统执行工具,再把结果作为新的上下文交给模型。只要模型继续请求工具,循环就继续;如果模型给出最终回答,循环结束。
ReAct、函数调用、多工具 Agent、代码执行 Agent,本质上都建立在这个基础循环上。实际工程里还会加一些保护措施,例如:
| 问题 | 常见处理方式 | 目的 |
|---|---|---|
| 模型陷入死循环 | 设置最大步数 max_steps |
避免无限消耗 Token |
| 工具调用失败 | 重试或降级处理 | 提高任务完成率 |
| 模型中途跑偏 | 加入验证 Agent | 检查结果是否符合目标 |
| 输出不稳定 | 固定上下文和执行约束 | 降低随机性 |
但这还不是 Loop Engineering。
Agent Loop 是 Agent 的内部执行机制,属于“底层引擎”。Loop Engineering 讨论的是更上层的任务组织方式:人不再只写一个需求,然后等 Agent 交付结果,而是把整个任务如何验收、如何反馈、如何迭代也一起设计出来。
可以用两层循环区分它们:
flowchart TB
subgraph Outer[Loop Engineering:任务验收闭环]
R[需求与目标] --> P[开发或执行]
P --> T[测试与验证]
T --> J{是否达标}
J -->|否| I[反馈与修正]
I --> P
J -->|是| S[沉淀结果或交付]
end
subgraph Inner[Agent Loop:单次执行循环]
M[模型推理] --> C{工具调用?}
C -->|是| Tool[执行工具]
Tool --> M
C -->|否| O[输出结果]
end
P -.内部依赖.-> Inner
T -.内部依赖.-> Inner
Agent Loop 让模型可以行动;Loop Engineering 让行动可以被目标牵引、被验证约束,并持续迭代到满足条件。
从 Human-in-the-Loop 到自动化验收闭环
传统 Agent 使用方式通常是一次性的:
flowchart LR
A[人提出需求] --> B[Agent 执行]
B --> C[交付结果]
C --> D[人检查]
D --> E{是否满意}
E -->|满意| F[结束]
E -->|不满意| G[人补充反馈]
G --> B
这个流程的问题不在于 Agent 不能做事,而在于“检查”和“纠偏”一直压在人身上。任务越复杂,人需要盯得越久。
Loop Engineering 改变的是外层控制方式:
flowchart LR
A[人定义目标] --> B[人定义验收标准]
B --> C[Agent 执行任务]
C --> D[自动测试或评估]
D --> E{是否达标}
E -->|否| F[Agent 根据反馈修正]
F --> C
E -->|是| G[输出结果]
G --> H[人做最终确认]
这里的关键变化是:人不再负责每一轮纠偏,而是提前定义好目标、约束和验收标准。Agent 在这个闭环里自己完成多轮尝试,直到达到标准,或者遇到需要人判断的边界条件。
这也是从 Vibe Coding 继续往前走的一步。
- Coding:人直接写代码。
- AI Coding:人描述需求,AI 写代码。
- Vibe Coding:人用自然语言持续指挥 AI 完成开发。
- Loop Engineering:人设计闭环流程,AI 自动开发、验证和迭代。
区别不只是“提示词变长了”,而是控制重心发生了变化。以前人主要写需求,现在人还要写验收规则;以前 Agent 做完就停,现在 Agent 要根据验证结果继续调整。
一个完整 Loop 需要哪些组成部分
一个可运行、可维护的 Loop 通常不是单个 Prompt,而是一套工程化结构。可以把它拆成六个核心部分:自动化、工作树隔离、技能包、连接器、子 Agent、状态管理。
flowchart TD
A[Loop Engineering]
A --> B[Automations 自动化]
A --> C[Worktrees 工作树隔离]
A --> D[Skills 技能包]
A --> E[Connectors / Plugins 连接器]
A --> F[Sub Agents 子 Agent]
A --> G[State 状态管理]
Automations:让 Loop 自动触发
自动化解决的是“什么时候运行”的问题。没有自动化,Loop 只能由人手动启动;有了自动化,Loop 才能按条件、按时间、按事件持续运行。
常见触发方式有三类:
| 触发方式 | 适合场景 | 示例 |
|---|---|---|
| 人工触发 | 临时任务、探索任务 | 让 Agent 修复一个模块并跑通测试 |
| 定时触发 | 周期性任务 | 每天汇总失败的 CI 任务 |
| 事件触发 | 和工程流程绑定 | PR 创建后自动 Review |
例如,一个代码修复 Loop 可以这样定义:
目标:
修复 auth 模块中的测试失败问题。
验收标准:
1. test/auth 目录下所有测试通过;
2. lint 检查无错误;
3. 不修改无关模块;
4. 输出修改摘要和验证命令。
循环规则:
如果测试失败,读取失败日志并继续修复;
如果 lint 失败,修复格式或静态检查问题;
如果连续 5 轮仍无法通过,停止并说明阻塞原因。
这个定义比“帮我修一下 auth 测试”更适合 Agent 自动运行,因为它明确告诉模型什么叫完成、失败后怎么办、什么时候停止。
在 Claude Code、Codex 这类工具里,自动化可以通过命令、定时任务、Hook 或后台任务实现。具体工具能力会变化,但抽象逻辑基本一致:定义目标,设定触发条件,运行 Agent,收集结果。
Worktrees:让多个 Agent 并行但不互相污染
只要多个 Agent 同时改同一个仓库,就会遇到文件冲突。一个 Agent 正在改登录模块,另一个 Agent 正在重构权限模块,如果它们都碰到了同一个配置文件,结果很容易互相覆盖。
Git Worktree 可以解决这个问题。
Worktree 是 Git 提供的多工作目录机制。多个目录共享同一个仓库历史,但每个目录可以检出不同分支。对 Agent 来说,每个 Worktree 就像一份独立的代码现场。
flowchart TD
A[(Git 仓库历史)] --> B[worktree/auth-fix]
A --> C[worktree/ui-refactor]
A --> D[worktree/ci-debug]
B --> E[Agent A 修复认证]
C --> F[Agent B 重构界面]
D --> G[Agent C 排查 CI]
这样做有几个好处:
| 好处 | 说明 |
|---|---|
| 隔离修改 | 每个 Agent 在自己的目录里工作 |
| 降低冲突 | 并行任务不会直接覆盖彼此文件 |
| 方便回收 | 失败任务可以直接删除对应 Worktree |
| 便于对比 | 每个任务的 diff 更清晰 |
如果一个工具支持为每个 Agent 自动创建 Worktree,那么并行执行就会安全很多。否则也可以手动创建:
git worktree add ../project-auth-fix -b agent/auth-fix
git worktree add ../project-ui-refactor -b agent/ui-refactor
Worktree 不会让 Agent 变聪明,但会让 Agent 的执行环境更可控。并行任务越多,隔离越重要。
Skills:把成功经验沉淀成可复用能力
Skill 可以理解为 Agent 的可复用能力包。它通常包含说明文档、操作步骤、脚本、模板、检查清单等内容,用来告诉 Agent 遇到某类任务时应该怎么做。
例如,一个“前端组件测试修复 Skill”可以包含:
适用场景:
修复 React 组件测试失败。
执行步骤:
1. 先运行目标测试,确认失败信息;
2. 判断失败来自断言、异步等待、Mock 数据还是组件行为;
3. 优先修复产品代码,只有测试假设错误时才改测试;
4. 每次修改后重新运行目标测试;
5. 通过后运行相关目录测试,避免局部修复引入新问题。
验收标准:
- 目标测试通过;
- 相关目录测试通过;
- 不跳过测试;
- 不删除关键断言。
Loop Engineering 里的 Skill 不只是静态说明书,还可以随着循环不断沉淀经验。Agent 在多轮执行中发现某类问题的固定处理方式后,可以把它整理进 Skill,下次遇到类似任务时直接复用。
这会带来一个重要效果:Agent 不必每次都从零开始试错。
但 Skill 也要控制边界。稳定流程适合沉淀成 Skill;一次性探索、强依赖上下文的判断,不适合过早固化。否则 Skill 会把临时经验变成长期偏见,反而影响后续任务。
Connectors / Plugins:让 Agent 能访问真实系统
没有外部工具,Agent 只能在文本里推理;接入连接器和插件后,Agent 才能访问代码仓库、数据库、项目管理工具、浏览器、日志系统和内部接口。
MCP(Model Context Protocol,模型上下文协议)就是这类连接方式的代表。它把外部能力封装成模型可调用的工具,让 Agent 可以在 Loop 中执行真实操作。
flowchart LR
A[Agent] --> B[MCP / Plugin Layer]
B --> C[Git 仓库]
B --> D[CI 系统]
B --> E[Issue 系统]
B --> F[数据库]
B --> G[日志平台]
B --> H[浏览器]
连接器决定了 Loop 能做多真实的事情。比如:
| 连接对象 | Agent 可以做什么 |
|---|---|
| GitHub / GitLab | 读取 PR、提交代码、评论 Review |
| CI/CD 系统 | 查看构建失败原因、重新触发流水线 |
| Linear / Jira | 读取需求、更新任务状态 |
| 数据库 | 查询业务数据、生成报表 |
| 日志平台 | 分析错误堆栈、定位异常趋势 |
| 浏览器 | 检查页面效果、执行端到端测试 |
需要注意的是,连接器越多,权限边界越重要。能读日志不代表能删数据,能评论 PR 不代表能合并代码。Loop 自动化程度越高,越要给它最小权限。
Sub Agents:用角色隔离提升质量
复杂任务不适合让一个 Agent 从头做到尾。一个 Agent 既写代码、又验收代码、又判断自己有没有达标,很容易产生盲区。更稳妥的方式是把不同职责拆给不同的子 Agent。
flowchart TD
A[主 Agent 调度任务] --> B[实现 Agent]
A --> C[测试 Agent]
A --> D[审查 Agent]
A --> E[文档 Agent]
B --> F[提交实现方案]
C --> G[运行测试并报告失败]
D --> H[检查需求一致性和风险]
E --> I[更新说明文档]
F --> A
G --> A
H --> A
I --> A
常见拆分方式如下:
| 子 Agent | 职责 | 适合保持独立吗 |
|---|---|---|
| 实现 Agent | 写代码、改配置、补逻辑 | 可以 |
| 测试 Agent | 跑测试、复现问题、生成失败报告 | 应该独立 |
| 审查 Agent | 检查需求、风险和代码质量 | 应该独立 |
| 探索 Agent | 调研方案、阅读代码、比较路径 | 可以并行 |
| 文档 Agent | 更新使用说明和变更记录 | 可以 |
验证类 Sub Agent 尤其需要独立。让实现者自己判断实现是否合格,容易放过问题;让独立验证者按验收标准检查,才能形成有效制衡。
不过,Sub Agent 不是越多越好。拆分过细会带来协调成本,多个 Agent 各自输出一堆建议,如果没有主 Agent 统一取舍,结果会变得碎片化。比较合理的做法是:探索和验证可以拆,最终决策和整合必须回到主 Agent。
State:记录 Loop 已经做到哪里
Loop 一旦跑多轮,就必须有状态管理。否则 Agent 很容易重复做已经完成的事,或者忘记上一轮为什么失败。
状态可以放在 Markdown 文件、任务系统、数据库或 Issue 工具里。关键不是存在哪里,而是要让状态可读、可更新、可追踪。
一个简单的状态文件可以这样写:
# Auth Fix Loop State
## Goal
让 test/auth 目录下所有测试通过,并保证 lint 无错误。
## Current Status
- 第 3 轮修复中
- 当前失败测试:test/auth/session.test.ts
- 失败原因:refresh token 过期时间断言不一致
## Completed
- 修复 login.test.ts 的 Mock 数据
- 修复 auth middleware 的异常返回码
- 通过 npm run lint
## Next Action
检查 session 续期逻辑和测试断言是否一致。
## Stop Condition
连续 5 轮无法减少失败测试数量时停止。
状态管理的价值在于让 Loop 有记忆。Agent 不只知道当前任务,还知道已经尝试过什么、哪些方案无效、下一步应该做什么。
Loop Engineering 的实践例子:文本分类任务
代码审查、自动 PR、CI 失败修复都很适合 Loop Engineering。不过为了更容易理解,可以看一个更简单的任务:文本分类。
假设有一批文本,需要按 1、2、3、4、5 五个类别分类,并且已经有一组带标准答案的测试数据。
传统做法是:
- 写一个分类 Prompt;
- 让模型输出分类结果;
- 人工抽查准确率;
- 发现错误后手动补充规则;
- 再跑一轮;
- 把比较稳定的 Prompt 保存下来。
Loop Engineering 的做法是把验证和迭代直接写进流程。
flowchart TD
A[输入分类标准和训练样例] --> B[Agent 生成分类规则]
B --> C[对测试集执行分类]
C --> D[计算准确率和错误样本]
D --> E{准确率是否达标}
E -->|否| F[分析错误原因]
F --> G[修正规则或补充示例]
G --> C
E -->|是| H[沉淀为 Skill 或脚本]
可以把任务定义成这样:
任务:
为一批文本构建五分类规则,类别编号为 1/2/3/4/5。
输入:
- 分类标准说明;
- 训练样例;
- 100 条带标准答案的测试数据。
目标:
在测试数据上达到准确率 ≥ 95%。
循环规则:
1. 先基于分类标准生成初版分类规则;
2. 对测试数据执行分类;
3. 统计准确率,列出所有错误样本;
4. 分析错误来自规则缺失、边界模糊还是样例不足;
5. 修正规则后重新分类;
6. 达到准确率目标后停止;
7. 如果连续 5 轮准确率没有提升,停止并输出原因。
最终产物:
- 稳定分类规则;
- 错误样本分析;
- 可复用 Skill。
这套流程和普通 Prompt 最大的区别在于,它内置了目标和停止条件。Agent 不只是“做分类”,还要不断检查自己分类得准不准,并根据错误样本修正规则。
如果这个任务每天都要跑,还需要进一步区分两种情况:
| 任务特点 | 更适合的形式 | 原因 |
|---|---|---|
| 分类规则固定 | 脚本 | 稳定、便宜、可复现 |
| 分类规则会变化 | Skill | 保留模型判断能力,同时复用经验 |
| 每天都有新标准和新样本 | Loop | 需要动态评估和迭代 |
| 只需要批量执行已有逻辑 | 不需要 Loop | 没必要让模型重复推理 |
Loop 不是所有自动化任务的最佳形态。固定流程应该脚本化,稳定经验应该 Skill 化,只有需要模型持续判断、验证和修正的任务,才值得做成 Loop。
怎样写一个可执行的 Loop
一个可执行的 Loop 至少要包含五类信息:目标、输入、行动、验收、停止条件。
可以用这个模板组织:
目标:
明确最终要达成什么结果。
输入:
列出可用数据、文件、接口、测试集、业务规则。
行动:
说明 Agent 可以做哪些事情,不能做哪些事情。
验收:
定义可量化或可检查的通过标准。
停止条件:
说明什么时候成功停止,什么时候失败停止,什么时候需要人介入。
例如一个 PR Review Loop 可以这样写:
目标:
自动审查新提交的 PR,发现潜在缺陷、测试缺失和需求不一致问题。
输入:
- PR diff;
- 关联需求;
- 项目代码规范;
- 已有测试结果。
行动:
- 阅读 diff 和相关上下文;
- 检查边界条件、异常处理和兼容性;
- 必要时运行相关测试;
- 在 PR 下输出结构化 Review 评论。
验收:
- 每条评论必须说明问题、影响和建议修改方式;
- 不输出泛泛而谈的建议;
- 如果没有发现问题,说明已检查的范围。
停止条件:
- Review 评论发布完成;
- 无法获取必要上下文时停止并说明缺失信息;
- 测试环境不可用时停止并给出复现命令。
好的 Loop 不一定很长,但一定要具体。尤其是验收标准,越模糊越容易跑偏。
Loop Engineering 适合什么场景
Loop Engineering 最适合“目标清楚、验证明确、过程允许多轮迭代”的任务。
| 场景 | 是否适合 | 原因 |
|---|---|---|
| 修复测试失败 | 适合 | 测试结果能直接作为反馈 |
| 自动代码审查 | 适合 | 可以按规则检查 diff |
| 文本分类优化 | 适合 | 有测试集和准确率指标 |
| 定期生成周报 | 适合 | 数据源和输出格式稳定 |
| 探索新产品方向 | 不太适合 | 验收标准通常模糊 |
| 高风险线上变更 | 谨慎使用 | 自动执行需要严格权限控制 |
| 一次性简单任务 | 不必使用 | 手动 Prompt 成本更低 |
判断一个任务要不要做成 Loop,可以问三个问题:
- 有没有明确的完成标准?
- Agent 能不能自动获得反馈?
- 多轮迭代是否比人工介入更省成本?
三个答案都为“是”,Loop 通常值得设计。只要其中一个答案不确定,就应该先保留 Human-in-the-Loop,让人在关键节点做判断。
使用 Loop Engineering 时最容易踩的坑
需求模糊会被放大
普通 Agent 任务里,需求模糊还可以靠人中途纠偏。Loop 自动运行后,人不再频繁介入,开头的模糊会被一路放大。
例如“优化这个模块”就不是好目标,因为 Agent 不知道优化的是性能、可读性、架构、测试覆盖率还是用户体验。更好的写法是:
目标:
在不改变公开 API 的前提下,把订单列表接口 P95 响应时间降低到 300ms 以下。
验收:
1. 现有单元测试全部通过;
2. 新增性能测试脚本;
3. 使用相同测试数据对比优化前后的 P95;
4. 输出改动点和风险。
Loop 越自动,目标越要具体。
验收标准不能只靠模型自评
“请检查自己是否完成”不是可靠验收。模型可能漏看问题,也可能给出看似合理但不准确的判断。
更好的验收方式是尽量引入外部信号:
| 验收类型 | 可靠性 | 示例 |
|---|---|---|
| 自动测试 | 高 | 单元测试、集成测试、端到端测试 |
| 静态检查 | 高 | lint、typecheck、安全扫描 |
| 数据指标 | 高 | 准确率、召回率、响应时间 |
| 独立 Agent 审查 | 中 | 需求一致性、可读性、风险分析 |
| 主 Agent 自评 | 低 | 只能作为辅助参考 |
能用测试就不要只用自然语言判断;能用指标就不要只用“看起来不错”。
Token 成本和结果漂移要提前考虑
Loop 会多轮运行,天然比一次性 Prompt 更消耗 Token。如果任务本来可以用脚本解决,却每天让模型重新推理,不仅贵,而且结果可能不稳定。
同一个需求,模型今天可能写一个 Python 脚本,明天可能写一段 Shell,后天又改成 Node.js。对于需要稳定复现的生产任务,这种漂移会带来维护问题。
比较稳的策略是:
| 阶段 | 做法 |
|---|---|
| 探索期 | 用 Loop 找到可行流程 |
| 稳定期 | 把流程沉淀为脚本或 Skill |
| 运行期 | 用自动化调度脚本或 Skill |
| 异常期 | 再启动 Loop 分析和修复 |
Loop 更适合发现流程、优化流程,而不是永远替代确定性程序。
权限要按最小原则配置
Loop 一旦能自动运行,就必须控制权限。尤其是接入代码仓库、数据库、CI/CD、交易系统、生产环境时,不能让 Agent 拥有超出任务所需的权限。
一个比较安全的权限设计是:
| 能力 | 建议权限 |
|---|---|
| 读取代码 | 可以开放 |
| 修改代码 | 限制在独立分支或 Worktree |
| 提交 PR | 可以开放,但需要标记来源 |
| 合并 PR | 默认需要人工确认 |
| 查询生产数据 | 只读、脱敏、限制范围 |
| 修改生产数据 | 不建议自动开放 |
| 触发部署 | 需要人工审批或强规则约束 |
Loop Engineering 的目标是减少重复人工,不是取消所有人工控制。越靠近生产和资金,越需要保留人工闸门。
Loop Engineering 的核心价值
Loop Engineering 的价值可以概括为一句话:把人从重复反馈中移出来,把人放回目标设计和最终决策的位置。
它并不神秘,也不是全新的底层技术,而是把已有能力重新组织成更高层的自动化闭环:
- Agent Loop 负责让模型持续调用工具;
- 自动化负责让任务按条件运行;
- Worktree 负责隔离并行修改;
- Skill 负责沉淀可复用经验;
- Connector 负责连接真实系统;
- Sub Agent 负责拆分职责和独立验证;
- State 负责记录进度和上下文。
当需求清晰、验证明确、反馈可自动获取时,Loop 可以显著减少人工盯任务的时间。人只需要定义目标、边界和验收标准,然后在结果达标后做最终确认。
但如果需求本身还没想清楚,或者验收标准无法表达,强行做 Loop 往往会浪费更多时间和 Token。此时更适合让人留在循环里,先通过几轮人工反馈把问题定义清楚,再考虑自动化。
Loop Engineering 不是为了让 Agent 无限制地自己跑,而是为了让 Agent 在可验证、可停止、可追踪的流程里跑。真正重要的不是“循环”这个动作,而是循环背后的目标、反馈和边界。