周期性循环(/loop)
/loop 会按周期在你当前会话内重复运行一条提示词(或一个斜杠命令)。每次唤醒都是一次真正的 agent 回合:Hermes 重新读取当前状态——最新的 CI 结果、最新的队列深度、文件此刻的样子——完成工作、汇报,然后安静下来直到下一个 tick。
这是 Hermes 对 Claude Code 的 /loop(及其 /proactive 别名,在这里同样有效)的实现。/goal 由评判器驱动——"持续干到目标达成"——而 /loop 由计时器驱动:"每隔 N 分钟(或在合理时)再做一次,直到有什么说停。"
何时使用
- 轮询外部状态。 "盯着部署 / CI 运行 / 队列,有变化就告诉我。"这是最典型的用途。
- 迭代到变绿。 "跑测试,修失败项,重复直到全部通过。"
- 工作会话期间的监控。 你在同一段对话里做别的事,同时盯着错误率或一个长任务的进度。
- 周期性整理。 在长会话中每隔 N 分钟重跑一次 lint 或状态摘要。
当工作应当无人值守地运行——过夜、按真实时刻表、跨终端重启存活——请改用 cron 任务。/loop 活在会话内部;cron 活在所有会话之外。而当任务是单一目标且有完成定义时,/goal 通常更合适。
快速开始
/loop 5m 检查部署状态,告诉我是否已经上线
你会看到:
- 循环已接受——
↻ 循环已设置(每 5m):检查部署状态…… - 首次唤醒立即触发——在下一次空闲轮询时(网关:下一次 15s watcher 扫描),Hermes 注入唤醒并针对当前状态跑一个正常回合。
- 重复——此后每隔 5 分钟一次,直到某个停止条件触发或你手动停止。
循环一个斜杠命令同样简单:
/loop 10m /recap
两种节奏模式
固定间隔——由你设钟。 给出一个间隔(30s、5m、2h、1h30m),循环就按该时刻表触发。当你监控的事物按自己的时间线变化时使用:
/loop 2m 在 ci.example.com/job/42 轮询构建,一结束就 ping 我
自定节奏——Hermes 设钟。 省略间隔,循环自行调速:它从下限起步(默认 1 分钟),当 agent 的回复不再变化时,按指数退避——2m、4m、8m,直到上限(默认 15 分钟)。一旦某次回复与上一次不同,节奏立刻回到下限。变化检测是本地摘要比较(忽略时间戳),因此空闲等待不额外耗成本:
/loop 盯着迁移进度并总结进展
经验法则:外部时钟驱动工作时用固定间隔;工作本身驱动节奏时用自定节奏。
停止条件
满足以下任一条件时循环结束:
| 条件 | 方式 |
|---|---|
| agent 判定完成 | 唤醒提示词教会 agent:任务完成或已无意义时,在回复末尾单独一行输出 LOOP_COMPLETE。 |
| 运行次数上限 | --times N——N 次唤醒后停止。 |
| 基于证据的条件 | --until <条件>——每次唤醒后,驱动 /goal 的同一个辅助评判器按你的条件检查回复。若评判器判定条件不可达成,循环会带着原因暂停,而非反复触发,直到 tick 预算耗尽(失败开放:评判器出问题绝不会卡死循环)。 |
| 你 | /loop stop(或 /loop pause 保留它)。 |
| 兜底预算 | loops.max_ticks(默认 100)会暂停循环,使无人值守会话不会无限烧 token。0 = 不限。 |
示例:
/loop 2m 轮询 CI --times 30
/loop 5m 盯着队列 --until 队列深度归零
命令
| 命令 | 作用 |
|---|---|
/loop [间隔] <提示词> [--times N] [--until <条件>] | 为本次会话启动(或替换)循环。首次唤醒立即触发;后续按节奏。 |
/loop 或 /loop status | 显示节奏、已触发 tick 数及距下次唤醒的时间。 |
/loop pause | 停止触发但不丢失循环。 |
/loop resume | 恢复运行。 |
/loop stop | 结束循环。 |
/proactive … | /loop 的别名(对齐 Claude Code)。 |
在 CLI、TUI(hermes --tui)、web 仪表盘聊天、桌面应用以及每个网关平台(Telegram、Discord、Slack、WhatsApp……)上均可用。在消息平台上,网关甚至会在你两条消息之间触发唤醒——循环属于该聊天的会话,其结果以普通回复形式到达——即使该会话同时在 TUI / 桌面应用中打开,路由唤醒也交由网关处理。
与 /goal 配合
两个特性都在空闲边界注入合成回合,因此遵循一条规则:活跃的 goal 拥有会话。 当 /goal 正在主动驱动(评判器说"继续")时,循环唤醒延后。goal 结束、暂停或停在等待屏障(/goal wait,或评判器自动的 WAIT 判定)上后,循环立即利用空闲时间恢复。一个停驻的 goal 加一个 /loop 是天然组合:goal 等那个大异步事项,循环则对另一事物保持心跳。
真实的用户消息永远优先于二者——唤醒只在会话空闲、且没有你的消息排队时触发。
行为细节
- 唤醒是普通的 user 角色回合。 不改动系统提示词,不切换工具集——提示词缓存保持完整。在消息网关中,唤醒不是对设置循环那条消息的回复,因此其输出发到聊天/话题时不引用那条消息。
- 跨
/resume和压缩存活。 循环状态按会话持久化,并跨上下文压缩边界迁移,与/goal相同。 - 每会话一个循环。 设置新的
/loop会替换旧的。要跑多个循环就开多个会话(或用 cron 管理一组时刻表)。 - 打断一个唤醒回合(Ctrl+C)会暂停循环——可用
/loop resume恢复,因此取消就是真的取消。 - token 成本随节奏缩放。 每个 tick 都是一次完整的 agent 回合。间隔应匹配状态实际变化的频率;空闲等待优先用自定节奏。
配置
# ~/.hermes/config.yaml
loops:
min_interval_seconds: 30 # 固定间隔的下限
max_ticks: 100 # 兜底预算(0 = 不限)
self_paced_floor_seconds: 60 # 自定节奏起步间隔
self_paced_ceiling_seconds: 900 # 自定节奏最大退避
--until 评判器经由 goal_judge 辅助任务路由,因此 auxiliary.goal_judge.* 的路由覆盖(提供商、模型)同样适用于循环条件。
/loop vs /goal vs cron
/loop | /goal | cron | |
|---|---|---|---|
| 触发方式 | 计时器(或自定节奏) | 每回合后的评判器判定 | 时刻表,位于任何会话之外 |
| 活在 | 你当前会话 | 你当前会话 | 每次运行独立的会话 |
| 结束于 | 停止条件 / 上限 / 你 | 目标达成 / 预算 / 你 | 你移除该任务 |
| 最适合 | 轮询、监控、周期性重跑 | 单一目标,迭代到完成 | 无人值守、长周期时刻表 |