会话心跳(/heartbeat)
/heartbeat 为当前会话设置一条循环指令。只要会话空闲且间隔已到,该提示词就会作为一条普通用户消息触发 —— 同一对话、同一上下文、同一提示缓存。
/heartbeat every 10m Check the deployment and report meaningful changes
灵感来自 Prime-Agent 的 /heartbeat。Hermes 的改编版本严格保留了消息流不变量:心跳只在轮次之间注入(绝不在运行中途),且以纯用户角色消息的形式注入。
心跳 vs 定时任务:我该用哪个?
它们看起来相似,但承担的工作不同:
/heartbeat | hermes cron | |
|---|---|---|
| 运行于 | 本对话 —— 完整上下文、讨论的记忆 | 每次触发都是全新的隔离会话 |
| 进程重启后是否存活 | 状态持久化(SessionDB);网关监听在重启后自动恢复 | 是 —— 完全持久化的调度器 |
| 数量 | 每个会话一个 | 任务数量不限 |
| 最适合 | “我们干活时在这个对话里盯着 X” | 常驻任务、报告、看门狗、推送交付 |
经验法则:如果循环提示词需要对话的上下文,就用 /heartbeat。如果它是一个自包含的任务,就用 cron。
命令
| 命令 | 作用 |
|---|---|
/heartbeat every <interval> <prompt> | 设置(或替换)会话的心跳。间隔支持:90s、10m、2h、1d(最小 60s)。 |
/heartbeat 或 /heartbeat status | 显示心跳、其间隔以及距下次触发的时间。 |
/heartbeat pause | 停止触发,但不清除。 |
/heartbeat resume | 恢复(重新锚定计时器 —— 不会立即过期触发)。 |
/heartbeat clear | 移除心跳。 |
/hb 是别名。可用于 CLI、TUI / Desktop 应用以及网关平台(在 Slack 上使用 /hermes heartbeat …)。
行为细节
- 仅在空闲时触发。 心跳绝不会打断正在运行的轮次。如果触发时刻智能体正忙,它会在下一次空闲轮询时触发。在网关中,处于监听状态的空闲会话会主动唤醒,无需新的入站消息。
- 错过的触发会合并。 如果会话在多个间隔内一直忙碌(或进程未运行),你只会得到一次心跳轮次,而不是堆积的积压。计时器在每次触发时重新锚定。
- 用户消息优先。 排队的用户消息总是优先;心跳会等待输入队列清空。
- 缓存安全。 注入的提示词是一条普通用户消息。不修改系统提示词,不改变工具集。
- 网关恢复。 启动时会在所属配置档中,使用当前持久化的对话和线程路由恢复活动心跳。每次轮询都会在临时存储故障或适配器停机后重试恢复;暂停、已清除的心跳以及挂起的会话不会重启。无需新的聊天消息。
- 持久化与对话边界。 状态保存在
SessionDB.state_meta中,以heartbeat:<session_id>为键,并跟随上下文压缩引起的会话轮替。在消息网关中,通过 reset、switch 或 suspension 离开会话会清除其心跳;恢复该已归档对话不会使其复活。触发需要所属进程(CLI 会话或网关)正在运行。已被准入的网关触发在会话解析之后、智能体执行之前会再次检查:它可以跟随压缩子会话,但不能把其旧的指令带入被 reset 或切换过的对话。 - 执行记账。 网关在适配器准入时预留一次到期触发。如果该次尝试在进入智能体运行器之前结束(包括取消,或路由、授权、紧急停止、准备拒绝),且调度此间未变更,则会退还该触发次数。一旦进入了智能体运行器,即使执行失败或被中断,该次触发仍会计数。此计数并不代表模型响应成功或对外交付成功;进程突然死亡可能导致退还回调无法执行。
- 勿造工作防护。 注入的提示词告诉智能体:当没有实质性变化时简要回复并停止,这样空闲心跳不会产生无谓的忙碌工作。
示例
你: /heartbeat every 15m Check whether the CI run for PR #1234 finished; summarize the result when it does
♥ 已设置心跳(每 15m):Check whether the CI run for PR #1234 finished; ...
[15 分钟内你在同一会话中处理其他事情]
Hermes:[心跳 —— 循环指令,每 15m 触发一次]
💻 gh pr checks 1234 (1.2s)
CI 仍在运行(14/37 检查完成)。暂无内容可报告。
当答案不再变化时,用 /heartbeat clear 清除它 —— 或者让它继续守望。