SSD Nodes Learn 8GB 内存 — 每年 $66
指南 Matt Connor作者: Matt Connor · 更新于 2026-08-01

什么是循环工程?AI Agent 循环设计定义

循环工程不是编写一个巧妙提示词,而是设计 AI agent 的触发器、边界、验证和预算,让其持续运行并在预算耗尽时停止。

循环工程的含义

循环工程是设计 AI agent 运行的重复周期:什么事件会唤醒它、它可以访问哪些内容、如何检查其输出,以及什么条件会停止它。提示工程塑造发送给模型的一条消息。循环工程塑造在您休眠时发送数千条消息的流程。工作的基本单位从提示转变为循环。

简而言之:您不再编写指令,而是开始编写控制系统。agent 仍然需要高质量的指令,但这些指令只是循环中的一个组件。循环按计划运行,在代码的隔离副本中工作,通过测试验证自身结果,并在预算耗尽时停止。

该术语为何在 2026 年出现

这个名称目前正在公开场合逐渐固定下来。GitHub 仓库 cobusgreyling/loop-engineering 在首次出现后的两个月内获得了 9,600 个 stars(截至 2026 年 7 月),其标语是“停止编写提示词。设计循环。获得评分。”它将这一转变归纳为六个构建模块:调度、worktrees、技能、插件和连接器、子代理,以及保存在对话之外的持久记忆。

其中引用了 Anthropic Claude Code 负责人 Boris Cherny 的话:

我不再向 Claude 编写提示词。我让一些循环持续运行,由它们向 Claude 编写提示词。

另一个仓库 AI-Builder-Club/skills 拥有约 1,100 个 stars(截至 2026 年 7 月),并直接说明了这两个角色:一名“代码库套件”负责让代理能够安全地在仓库中运行测试和执行部署;一名“循环工程师”负责构建工作流,使其在触发器激活时唤醒、执行工作,并将学到的内容写入共享文件,以便下一个循环读取。

这两个仓库都不是这一实践的发明者。任何运行过 nightly build、持续集成中的 linter,或会自动创建工单的 cron job 的人,都已经熟悉这种结构。新的变化在于,循环中的执行者现在具有非确定性,因此周围的机制必须承担不同的职责。

循环的四个部分

每个正常运行的循环都包含以下四个部分。缺少其中任何一个部分,循环都可能在凌晨3点唤醒您。

  • 触发器。 启动一次运行的事件:定时器、webhook、新的 pull request 或警报。
  • 边界。 在该次运行期间,代理可以访问的文件、凭据和网络。
  • 验证。 通过退出代码进行检查,以决定保留还是丢弃本次运行的输出。
  • 预算。 结束本次运行的令牌、时间和费用上限,无论运行是否成功。

将这四点转换成问题,您就能对准备持续运行的任何代理进行设计审查。

触发器:唤醒代理

定时器是最简单的触发器。在 Linux 服务器上,systemd 定时器通常优于 cron,因为它会记录日志,按您的设置重试,并且不会启动仍在运行的单元的第二个实例。最后这一点可以避免代理循环中最常见的重叠错误:两次运行同时编辑同一分支。

将单元写入 /etc/systemd/system/agent-loop.service

[Unit]
Description=Agent loop: triage open issues
After=network-online.target
Wants=network-online.target

[Service]
Type=oneshot
User=agent
WorkingDirectory=/srv/agent/repo
ExecStart=/srv/agent/bin/loop.sh
TimeoutStartSec=1800

将定时器写入 /etc/systemd/system/agent-loop.timer

[Unit]
Description=Run the triage loop every 30 minutes

[Timer]
OnBootSec=5min
OnUnitActiveSec=30min
Unit=agent-loop.service

[Install]
WantedBy=timers.target
sudo systemctl daemon-reload
sudo systemctl enable --now agent-loop.timer
systemctl list-timers agent-loop.timer

systemctl list-timers 应显示一个 NEXT 列,其中包含未来的时间,以及一个 LEFT 列,用于显示倒计时。结果为空表示定时器未启用,因为在没有 --now 的情况下使用 enable,只会将其安排在下一次启动时运行。TimeoutStartSec=1800 的重要性超出预期:如果代理因等待输入而挂起,单元将一直处于活动状态,定时器也永远不会再次触发。使用 journalctl -u agent-loop.service -n 50 查看一次运行。

如果改用 cron 驱动循环,请自行添加重叠保护,因为 cron 会直接启动第二个实例:

*/30 * * * * /usr/bin/flock -n /tmp/agent-loop.lock /srv/agent/bin/loop.sh

持有锁时,flock -n 会立即以状态 1 退出。因此,第二次运行会静默退出,不会与第一次运行发生竞争。同样的 systemd 服务和定时器设置 也适用于服务器上的任何长时间运行任务,无论是否为代理。

边界:为每次运行创建独立副本

编辑工作树的代理可能会覆盖尚未提交的更改。Git worktree 可以低成本解决这个问题:每次运行使用独立目录和独立分支,同时共享同一个对象存储。

cd /srv/agent/repo
git worktree add -b loop/triage-01 /srv/agent/work/triage-01 origin/main
git worktree list

git worktree list 会为每个工作树输出一行,其中包含其路径、提交和分支。运行结束时,git worktree remove /srv/agent/work/triage-01 会删除该目录,git worktree prune 会清理目录已消失的条目。此时并行循环就安全了,因为两个目录中的两个代理分别位于两个分支上,不会相互覆盖更改。

边界也涉及凭据。无人值守运行的循环会长期持有令牌,而每次运行都可能将令牌泄露到日志、提交或模型上下文中。将令牌的权限限制为循环会访问的单个仓库。在可行的情况下,不要让令牌出现在代理自身 shell 可见的环境中。向循环授予生产环境访问权限前,请阅读如何避免将机密暴露给 AI 代理。如果需要更严格的隔离,请将整个循环放在每次运行后都可以销毁的一次性 VM 中

验证:确保循环安全的关卡

这是循环与会自动输入命令的 cron 作业之间的区别所在。代理的输出只是提案。由关卡决定是否继续。

#!/usr/bin/env bash
set -euo pipefail

repo=/srv/agent/repo
branch="loop/$(date -u +%Y%m%dT%H%M%SZ)"
tree="/srv/agent/work/$(basename "$branch")"

cd "$repo"
git fetch --quiet origin
git worktree add -b "$branch" "$tree" origin/main
cd "$tree"

# the agent's own command runs here, in non-interactive mode

if ! npm test; then
  echo "gate failed: discarding $branch" >&2
  cd "$repo"
  git worktree remove --force "$tree"
  exit 1
fi

git push origin "$branch"
cd "$repo"
git worktree remove "$tree"

set -euo pipefail 在该脚本中发挥着实际作用。没有 -e 时,失败的 git fetch 会被忽略,运行会继续使用过时的 origin/main。没有 -u 时,变量名中的拼写错误会展开为空字符串,随后清理操作会针对错误路径运行,而不是明确失败。

if ! npm test 块体现了全部思路。由你已经信任的检查(例如测试套件或类型检查器)的退出代码决定是推送还是销毁分支。没有关卡的循环会产生没人有时间审查的工作,这比不产生工作更糟。带有关卡的循环会生成一个已经通过相同标准的分支,而人工贡献者的分支也必须通过该标准。

选择一个能够如实失败的关卡。在空 diff 上也能通过的测试套件会让循环认为不执行任何操作就是成功。测试薄弱的代码仓库会产生薄弱的循环。因此,热门代码仓库会先提出“让代码库适配代理”,然后才提出“编写循环”。

预算:限制运行时长

无限重试的代理会产生无上限的费用。为每个循环设置墙上时钟上限,并由上面的 TimeoutStartSec 强制执行;在脚本中设置重试次数;再通过服务提供商账户设置支出上限。然后记录每次运行的成本,以便在账单出现前发现循环成本正在上升。始终运行的代理 VPS 的成本控制介绍账务管理,管理代理在不同轮次之间携带的上下文介绍如何控制单次运行成本中影响最大的因素。循环每 30 分钟重新读取同一个代码仓库,就会每 30 分钟为此付费。

成本是循环通常优于长时间单次会话的原因。一次全新启动、执行一个范围明确的任务并退出的运行,会保持较小的上下文。持续打开 8 小时的会话会保留此前的所有错误,并在每一轮中为完整的对话记录付费。

热门仓库总结的模式

loop-engineering 仓库列出了 7 种生产模式。与其把它们当作宣言,不如把它们看作一份菜单。每日分诊。一个负责处理拉取请求的助手,用于监视评审评论并回复。一个持续集成清理器,用于处理失败的构建任务。依赖项清理器。变更日志起草器。合并后的清理。问题分诊。

这些模式都有一个范围明确的任务,以及一个清晰的门槛。“修复失败的构建”具有机器可以读取的通过条件。“改进代码库”则没有,因此它永远不会成为循环。它只会变成一个带有计划的混乱任务。

它们也都有书面记录。两个仓库都会把状态从对话中移出,写入仓库中的文件:运行了什么、发现了什么、作出了什么决定。该文件就是循环的记忆,也是第二个循环可以在第一个循环的工作基础上继续执行,而不必重新发现相同内容的原因。它还支持事后审计代理,因为运行结束后,模型的上下文就会消失。

循环失败的原因

这些失败很常见,而且会在不同团队中反复出现。

  • 没有门禁。 输出不断累积,没有人审核,信任逐渐崩溃,循环最终被关闭。
  • 重叠运行。 同一分支上同时运行两个任务,或两个代理在同一个工作树中运行,产生冲突,代理随后还要尝试解决这些冲突。
  • 无声漂移。 循环持续通过,是因为检查条件过于宽松,无法使任务失败。
  • 范围无界。 在繁忙仓库中,每次提交都会触发任务。一天之内,这就会变成成本问题。

每种情况的修复方法都相同:缩小任务范围,强化检查条件,并记录运行情况。如果无法用一句话描述通过条件,就说明该任务还不适合自动化。

不先掌握术语也能开始

您不需要框架。一台始终在线的小型 Linux 服务器、一个测试套件应当失败时确实会失败的 git 代码库、一个 systemd timer,以及一个包含 if 的 shell 脚本,就能构成完整闭环。这确实是大多数人应该采用的起点,因为设计问题应通过运行系统来解决,而不是通过选择工具来解决。一个闭环稳定后,运行第二个闭环主要只需再配置一个 timer 和一个 worktree。有关基础设置,请参阅如何在 VPS 上运行编码 AI 代理;如果您希望让代理本身运行在您控制的硬件上,请参阅当前可自行托管的 AI 代理选项

FAQ

循环工程与提示词工程有何不同?

提示词工程优化一条消息:措辞、示例和输出格式。循环工程优化消息周围的整个循环:启动一次运行的触发器、运行所处的沙箱、接受或拒绝输出的检查,以及终止循环的预算。循环内部仍然需要高质量的提示词。提示词不再是日常调优的重点,因为门控条件和触发器对结果的影响更大。

构建代理循环是否需要框架?

不需要。一个 systemd timer、每次运行使用一个 git worktree、以测试命令结束的 shell 脚本,以及提供商账户上的支出上限,就覆盖了定义中的所有部分。框架会增加调度接口、共享内存格式和多代理路由。这些功能在运行多个循环时很有用,但不是构建第一个循环的必要条件。

什么是代码库 harness?

它是一组让代理能够在没有人工参与的情况下处理代码库的工具和配置:一条命令完成设置、可在非交互模式下运行并明确失败的测试、linter,以及部署或预览更改的方法。这个术语与 loop engineering 一样,源自2026年出现的一批代码库。实际判断很简单:如果新的人工贡献者无法用一条命令从克隆代码库运行到测试通过,代理也无法做到。

如何防止代理循环产生高额账单?

在3个位置设置上限。在 systemd 单元上设置 TimeoutStartSec,这样挂起的运行会被终止。在脚本内部限制重试次数,不要一直循环直到成功。在 API 账户上设置硬性支出上限,因为这是代理无法通过辩解突破的唯一上限。然后记录每次运行的成本,因为成本翻倍的循环通常意味着其范围在不知不觉中扩大了。

哪些任务最适合优先转换为循环?

选择具有机器可读通过条件且影响范围较小的任务。修复失败的构建、更新依赖项并重新生成变更日志都符合条件,因为测试套件或差异可以证明结果。重构或设计等开放式工作目前不符合条件,因为没有可供门控条件检查的内容;没有门控条件的循环,只会以高昂成本积累待审查工作。

#loop-engineering#ai-agents#claude-code#workflow#automation