芥末
发布于 2026-06-18 / 13 阅读
0
0

Loop Engineering:让 Agent 自己完成开发、验证与迭代

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 五个类别分类,并且已经有一组带标准答案的测试数据。

传统做法是:

  1. 写一个分类 Prompt;
  2. 让模型输出分类结果;
  3. 人工抽查准确率;
  4. 发现错误后手动补充规则;
  5. 再跑一轮;
  6. 把比较稳定的 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,可以问三个问题:

  1. 有没有明确的完成标准?
  2. Agent 能不能自动获得反馈?
  3. 多轮迭代是否比人工介入更省成本?

三个答案都为“是”,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 在可验证、可停止、可追踪的流程里跑。真正重要的不是“循环”这个动作,而是循环背后的目标、反馈和边界。


评论