最近 Loop Engineering 这个概念挺火的,大家都在聊怎么让 agent 自己跑循环,别一行行 prompt 了。
我们之前也聊过这套打法——/goal 管"做到什么算完",/loop 5m 管"多久看一次",/skill-creator 管"把套路沉淀下来"。但有一类事情用前面2种手段解决的还是不太好:就是频率不固定的。
比如盯股票的,开盘恨不得每分钟刷一次,午休半小时看一眼就行——固定间隔要么浪费 token,要么错过行情。
针对这一类场景,我们给 /loop 加了新能力——动态唤醒。有了这套机制,"盯盘"这类任务终于能跑完整的 Loop Engineering 了——agent 自己调监控频率、自己判断什么时候该停、发现问题了还能自己 fork 一个 /goal 去处置。
那到底什么时候该用哪个命令呢?
三种"放手"的程度
交出终点:/goal
你告诉 agent "做到什么算完",剩下的交给它自己跑。
/goal 把 lint 错误从 847 降到 0,stop after 10 tries /goal 让首页 Lighthouse 评分到 90 以上
你给 agent 一个目标 + 完成条件,它就开始自己跑了。每一轮它都会自检——"目标达成了吗?" 达成了就停,没达成就换个思路继续试。有个 stop after N tries 的兜底,防止它死循环。关键在于 agent 全程是有状态的,它记得前几轮试了什么、为什么没用,所以会逐步调整策略。
适合场景:终态明确、可验证的任务。代码审查通过、测试全绿、文档写完——你知道"完成"长什么样,只是到达终点的路径可能曲折。而 agent 有状态记忆,路径走歪了它能自己拐回来。
你需要准备:一个可机器验证的完成条件。要"lint errors = 0"这种,别要"代码质量好一点"这种。模棱两可的终态,/goal 会在中间反复横跳,烧 token 但不出活。
局限:/goal 是"一次性"的。它到达终点就停了。如果你的需求是"持续盯着一个变化的东西",/goal 帮不了你——你不能对它说"目标是股价别跌破 15 块",因为它会立刻回复"好的,股价现在 16 块,目标已达成",然后结束。
交出节奏:/loop 5m
你告诉 agent "每隔多久做一次",它按你的节拍走。
/loop 5m 调用 gpu-train-guard skill 巡检 [node-01..node-08] /loop 30m 检查 PR 是否有新的 review comment /loop 1h /standup
底层就是个 cron 条目——CronCreate 按你给的间隔注册定时器,到点了把 prompt 原封不动喂给 agent 跑一遍。每一轮都是全新上下文,上一轮的状态不会带过来。所以它特别适合"每次做一样的事":查个状态、跑个巡检、生成个日报。
适合场景:巡检、轮询、周期性维护。你知道大概多久看一次合适,任务内容在每次执行时基本一致,只是输入变了。
你需要准备:两样东西——巡检内容(最好封装成 skill,别写在 prompt 里)和间隔。间隔怎么选?一个原则:间隔 = 你能接受的最大延迟。GPU OOM 后 30 分钟才处理就不可逆了,那间隔就定 5 分钟。PR 评论 2 小时不回复 reviewer 不会跑,那间隔就定 30 分钟。
局限:节奏是死的。开盘每分钟刷一次合理,但午休也每分钟刷一次就是浪费。而且你一旦走开,节奏就改不了了——哪怕 agent 自己发现"这个 CI 已经在跑了,5 分钟内不会出结果",它也只能老老实实 5 分钟后再查一次。
交出判断权:/loop(动态唤醒)
这次升级的核心就在这。你不用给节奏,给个目标就行——"盯着这件事",剩下的 agent 自己决定多久看一次、什么时候该加速、什么时候该停。
/loop 盯一下 CI pipeline,跑完了告诉我结果 /loop 监控 #opinion 频道舆情,有负面声音立即分析 /loop 看着今天的股价,跌破 15 块通知我
适合场景:节奏需要随情况变化的持续监控。目标的状态在变,agent 需要根据状态判断"下次该多久后看"。
你需要准备:监控目标的清晰描述 + 判断标准。比如"盯着股价"就太模糊了——盯什么?通知什么?应该说"看着今天的股价,跌破 15 块通知我,收盘了就停"。
关键机制:动态唤醒说白了就是一个"续命"机制。每次 agent 执行完一轮检查后,它调用 ScheduleWakeup 来安排下一次唤醒——延迟多少由它自己定(60 秒到 1 小时之间)。调了就是继续,不调就是结束。 所以 agent 可以自己决定什么时候不干了,你不用回来按取消键。另外它还能配合一个 Monitor 工具挂在日志流上,事件来了立刻醒,连轮询都省了——这个后面细说。
盯盘:弹性节奏的终极场景
上面聊的三种放手程度里,盯盘恰好是最需要“交出判断权”的。
盯盘的场景大家都熟:
场景 |
平稳时 |
异常时 |
异常时行动 |
结束条件 |
股票盯盘 |
30 分钟 |
2 分钟 |
通知用户 + 分析涨跌原因 |
收盘 |
线上告警 |
15 分钟 |
1 分钟 |
通知用户 + fork /goal 排障 |
告警清零 |
舆情监控 |
1 小时 |
3 分钟 |
通知用户 + 生成舆情摘要 |
热度回落 |
PR 等审 |
2 小时 |
5 分钟 |
回复评论 + 通知用户 |
PR merged |
这些场景看着不一样,但有个共同点:节奏没法提前预判,得看情况。你硬定一个固定间隔,要么太平的时候烧 token,要么出事的时候反应太慢。
盯盘真正难在哪?定时看一眼倒好办,难的是这三件事:
- 频率自调:情况平稳就拉长间隔,情况紧急就缩短间隔
- 自主结束:目标达成了(收盘了、告警清零了、PR merged 了),自己停下来
- 自主行动:发现异常时能根据情况决定下一步——该通知就通知,该深入调查就调查
这三件事,固定间隔的 /loop 5m 做不到,/goal 也拿它没辙——没有明确的终态条件。动态唤醒能接住,因为它把“节奏”和“停不停”的决策权都交给了 agent。
好,说了这么多,下面看看本次升级,我们具体改了什么。
Loop 的 5 大升级
这次升级做了五件事:动态唤醒机制(核心)、Monitor 事件唤醒、三模式自动路由、/crontab 管理面板、--durable 持久化。
1. 动态唤醒机制(ScheduleWakeup)
这个是核心。我们新增了一个 ScheduleWakeup 工具,它的工作方式极其简单:
- agent 每轮执行完毕后,调用
ScheduleWakeup,传入delaySeconds和reason - 系统在指定秒数后再次唤醒 agent,执行同一任务
- 如果 agent 不调用
ScheduleWakeup,循环自动结束
就这么回事。不用写 cron 表达式,不用定固定间隔,也不用声明退出条件。agent 根据当前情况自己判断:该多久后看?还看不看?
举个例子,你让 agent 盯股价,它可能会这样跑:一开始股价正常,5 分钟后再看;快接近警戒线了,缩短到 2 分钟;跌破阈值了,通知你的同时 fork 一个 /goal 去分析原因,继续 1 分钟一次盯着;收盘了,agent 觉得没必要再看了,不调 ScheduleWakeup,循环自然结束。
几个关键行为:
- 频率自调:从 5 分钟 → 2 分钟 → 1 分钟 → 10 分钟,全是 agent 自己判断的
- 自主行动:跌破阈值时还 fork 了一个
/goal去调查原因,光通知不够 - 自主结束:收盘后 agent 判断“不需要再看了”,不调用
ScheduleWakeup,循环自然终止
后面盯盘实战部分会详细讲解,这里先不展开了。
2. Monitor 事件唤醒:不用猜时机了
动态唤醒解决了"多久看一次",但轮询终归有延迟——事情发生在两次唤醒之间,最坏情况得等一个完整间隔。告警都出来了,agent 还在睡。
所以这次还加了一个 Monitor 工具:agent 可以挂一个后台 shell 命令(tail -f 告警日志、watch 一个接口、盯一个进程的输出……),命令一有输出,每行内容实时变成事件通知唤醒 agent。事件驱动,秒级响应。
有了 Monitor,两个通道就分工了:
- Monitor 管应急:事件来了立刻叫醒 agent,不用等下一轮轮询
- ScheduleWakeup 管兜底:退化成心跳,20-30 分钟醒一次确认监控还活着
你可能会担心:日志刷得飞快,agent 岂不是被事件洗版?这块我们做了防风暴设计:令牌桶限流(高频输出会被合并成批发送),连续过载会自动停掉 monitor 并提醒 agent 换个更严的过滤条件(比如 tail -f app.log 换成 tail -f app.log | grep ERROR)。不想监控了,TaskStop 一下就停。
3. /loop 三模式自动路由
升级后的 /loop 多了几种模式,根据你的输入自动选:
输入 |
模式 |
机制 |
适用 |
|
固定间隔 |
CronCreate |
节奏明确的巡检 |
|
动态唤醒 |
ScheduleWakeup |
节奏需要弹性 |
|
loop.md 任务 |
ScheduleWakeup + loop.md |
项目常规维护 |
路由规则很简单:第一个参数是时间(如 5m),就走固定间隔;不是时间,就走动态唤醒;什么都不传,看有没有 loop.md。
所以你不用学新命令。/loop 5m check the deploy 还是老样子——固定 5 分钟。而 /loop check the deploy(去掉了 5m)就切换到动态模式,agent 自己决定节奏。
loop.md 模式更进一步:你在 .qoder/loop.md 里写一份任务清单,/loop 不带参数就会自动执行这份清单,每轮唤醒时自动注入最新内容。任务清单改了,下一轮自动生效。
4. /crontab 管理面板
之前管理定时任务只能用命令行——删一个任务要先 list 找到 ID,再 delete。这次我们做了一个交互式 TUI 管理面板:
┌─ Crontab ──────────────────────────────────────┐ │ [Session] [Persistent] [Wakeup] │ │ │ │ ID Schedule Prompt │ │ ──── ───────── ─────── │ │ a1b2 */5 * * * * check the deploy │ │ c3d4 0 */2 * * * /standup │ │ │ │ ↑↓ Navigate · Enter Details · d Delete │ │ Esc Exit │ └────────────────────────────────────────────────┘
三个 Tab:
- Session:当前会话的临时定时任务(进程退出即消失)
- Persistent:持久化到磁盘的定时任务(支持
--durable创建),展示过期时间 - Wakeup:动态唤醒任务,展示下次唤醒时间和 prompt
每个任务的详情页都支持就地编辑:
- 按
s编辑定时表达式——弹出预设列表(1m / 5m / 15m / 30m / 1h / ... / Custom),上下选择,Enter 确认。Custom 模式下输入5m/2h/30s之类的人类时间,自动转 cron - 按
p编辑 prompt——预填原始内容,支持就地修改 - 按
e编辑过期时间(Persistent tab) - Wakeup tab 的
s键同样支持重新调度——7 个预设延迟从 30s 到 1h
动态唤醒任务这块,管理面板挺好用:你能随时看到 agent 给自己设的下一次唤醒时间、理由,想改延迟就改延迟,想改 prompt 就改 prompt,不用等 agent 下一轮。
5. --durable 持久化
默认情况下,/loop 创建的任务是 session 级的——进程退出就没了。加 --durable 可以持久化到磁盘:
/loop --durable 30m check the deploy /loop --durable 7d /babysit-prs (7 天后自动过期) /loop --durable /standup (永久,直到手动删除)
持久化任务会在进程重启后自动恢复,默认 7 天过期。--durable 不加天数 = 永久,加了天数 = 指定天数后过期。过期时间在 /crontab 管理面板里直接可见、可编辑。
盯盘实战:把 loop 动态唤醒用起来
说了这么多,到底跑起来效果怎样?拿一个我们实际遇到过的场景走一遍。
场景:线上服务告警盯盘
你的线上服务今天有大促活动,流量预计是平时的 5 倍。你需要盯盘:监控告警、发现问题及时处置、活动结束后自动收工。
传统做法:写个 crontab 脚本每 5 分钟检查一次告警 API,有告警发企微。问题是:高峰期 5 分钟太慢,平峰期 5 分钟太频繁,而且脚本只会喊"出事了"不会处理。
换成 Loop Engineering 的做法:
第一步:动态盯盘
/loop 监控线上服务的告警状态: 1. 用 alert-cli 监听告警事件流,有新告警立即处理 2. 如果有 P0/P1 告警,立即通知我并深入分析根因 3. 如果有 P2/P3 告警,记录并按需处理 4. 活动结束后告警清零,结束盯盘
agent 会怎么跑?它上来先把监控架好:调 Monitor 挂上告警事件流,再设一个 20 分钟的 ScheduleWakeup 当心跳。然后:
[10:00] 启动:Monitor("alert-cli listen --format json", persistent) → ScheduleWakeup(1200s, "监控已挂上,心跳兜底") [10:20] 心跳唤醒 → 监控活着,无告警 → ScheduleWakeup(1200s, "一切正常") [10:32] Monitor 事件:2 条 P2 告警 → agent 秒级被叫醒 → 记录 + 自动处理(重启不健康的 pod) → ScheduleWakeup(300s, "有 P2 告警,缩短心跳监控恢复情况") [10:37] 心跳唤醒 → P2 告警已清 → 恢复正常 → ScheduleWakeup(1200s, "告警清零,回到兜底节奏") [11:16] Monitor 事件:5 条 P0 告警!→ 秒级唤醒 → 立即通知用户 → /goal 分析 P0 告警根因,10 分钟内给出修复方案 → ScheduleWakeup(120s, "P0 处置中,加密心跳追进度") [11:18] /goal 完成 → 根因:数据库连接池耗尽 → 修复:扩大连接池 + 重启服务 [11:24] Monitor 事件:告警恢复通知 → 修复生效 → ScheduleWakeup(1200s, "告警清零,回到兜底节奏") [14:00] 用户:活动结束了 → TaskStop 停掉 Monitor → 不调 ScheduleWakeup,循环结束
注意看两个通道的配合:P2、P0 告警都是 Monitor 秒级推过来的,不用等轮询;而 ScheduleWakeup 全程只干两件事——平时当心跳,处置期间加密追进度。节奏全程是 agent 自己调的。
第二步:搭配 /goal、workflow 和 skill 做深度处置
上面的流程里,P0 告警一出现,agent 就 fork 了一个 /goal 去分析根因。这全靠 agent 自己判断——它觉得“P0 太严重,光通知不够,得深入查一下”。
/loop 负责持续盯着,发现问题了怎么处置?几种选择:fork 一个 /goal 去全力解决,调用对应的 skill 跑预案流程,或者触发一个 workflow 执行预设的应急步骤。你提前把处置逻辑写进 skill 或 workflow 里,相当于一份预案表单——agent 发现异常后自己决定用哪个、怎么用。你不用手动在监控和处置之间来回切换。
第三步:用 /crontab 随时介入
盯盘跑到一半,你想看看 agent 给自己设的下一次唤醒是什么时候、为什么。打开 /crontab → Wakeup tab:
┌─ Wakeup Detail ────────────────────────────────┐ │ Next wakeup: 11:20:15 (in 1m 40s) │ │ Reason: P0 处置中,加密心跳追进度 │ │ Prompt: 监控线上服务的告警状态... │ │ │ │ s · Reschedule p · Edit prompt │ │ Esc · Back │ └────────────────────────────────────────────────┘
看到 agent 把心跳设成了 120s,你觉得没必要(P0 已经在处理了,Monitor 也还挂着),按 s 手动改成 600s。或者你想加一条新的监控指令,按 p 编辑 prompt,追加一句"同时检查数据库连接池使用率"。
第四步:持久化盯盘
如果你需要盯盘跨进程(比如重启了终端),加 --durable:
/loop --durable 监控线上服务的告警状态...
任务持久化到磁盘,重启后自动恢复。过期时间在 /crontab 里可见,可以随时调整。
怎么选
聊了这么多,落到实际选型上,其实就是一个问题:你的任务,终点和节奏,哪个你能说清楚?
终点能说清楚 → /goal
适合:lint 清零、测试全绿、文档写完这类活儿——你知道“完成”长什么样。
不适合:盯盘、持续监控——跑到终点就停了,没法一直盯着。
准备:一个可机器验证的完成条件 + 最大重试次数。
节奏能说清楚 → /loop 5m
适合:巡检、轮询、定期维护——你知道大概多久看一次合适。
不适合:盯盘、弹性监控——间隔是死的,agent 改不了。
准备:巡检内容(封成 skill,别写在 prompt 里)+ 间隔(间隔 = 你能接受的最大延迟)。
都说不清楚 → /loop(动态唤醒)
适合:盯盘、弹性监控——节奏需要 agent 自己判断。有现成的事件源(日志流、事件 API)时更香,Monitor 直接挂上去秒级响应。
不适合:合规要求固定间隔的场景,或者你明确知道间隔不会变的。
准备:监控目标的清晰描述 + 判断标准 + 异常处置预案(写进 skill 或 workflow)。
混搭才是常态
实际用下来,单用一个的情况少。最常见的组合:/loop 持续盯着,发现问题 fork /goal 深入处理,或者调用 skill/workflow 跑预案。一个管节奏,一个管深度,一个管套路。
最后:Loop Engineering 讲的是设计
写到最后想多聊两句。Loop Engineering 这个概念,说到底就是从"我来做"变成"我来设计怎么让 agent 做"。
这次升级做的几件事——动态唤醒、Monitor、管理面板、持久化——都是在降低"设计"的门槛:
- 动态唤醒让你不用预判节奏,秒表归 agent 管
- Monitor 让 agent 不用猜时机,事件来了直接叫醒它
- 管理面板让你随时能介入,不用退出对话去敲命令行
- 持久化让你关了终端也不丢任务,重启后自动恢复
盯盘这个场景好在哪?它把"人设计、agent 执行"的分工展示得很清楚:
人做了什么 |
Agent 做了什么 |
定义监控目标和判断标准 |
挂 Monitor、调监控节奏 |
审查 agent 的处置决策 |
响应事件、发现问题、fork /goal 处置 |
决定什么时候结束盯盘 |
自主判断是否需要继续 |
设计监控系统 |
执行监控 |
你花 5 分钟想清楚“盯什么、什么算异常、异常了怎么办”,然后写成一条 /loop。剩下的,agent 替你盯到天荒地老——或者说,盯到它自己判断“不需要再盯了”为止。
Loop Engineering 想达到的效果就是:你的注意力从"重复检查"挪到"设计更好的检查策略"上。
打开Qoder CLI ,开始用起来吧!agent 会自己决定多久看一次。
# 开始你的第一次动态盯盘 qodercli /loop 看着今天的 CI pipeline,跑完告诉我结果,失败的话分析原因