【AI 业务流架构师】05-Heartbeat心跳机制:让Agent从被动应答走向主动服务
Heartbeat 心跳机制:让 Agent 从被动应答走向主动服务
引言
用过聊天机器人的读者大概都有类似的体验:你不说话,它就永远沉默。哪怕服务器磁盘已经告急、日历上的会议十分钟前就该提醒、昨天的日报任务悄悄挂掉了——只要没人开口,Agent 便一无所知。这种"你问我答"的交互范式,把 Agent 桎梏在一个等待指令的位置上,离真正意义上的"助理"相去甚远。
本文聊聊打破这一局面的关键设计:心跳机制(Heartbeat)。以开源 Agent 框架 OpenClaw 为例,我们拆解它如何让 Agent 周期性"醒来"巡检自身职责范围内的世界,并在"有事"与"没事"之间做出得体的选择。
一、被动响应范式的三块短板
传统 Chatbot 乃至很多定时推送机器人,本质上都在被动框架里打转。以一个常见的"每天定点推送 GitHub Trending"任务为例,它看起来实现了主动,实际暴露了三个问题:
- 无条件执行。到了预设时间,无论今天有没有值得关注的内容,推送雷打不动地发出去。
- 不做筛选。消息格式千篇一律,哪怕条目全是你不关心的领域,也照推不误。
- 没有反馈回路。如果抓取或搜索过程失败了,任务本身浑然不觉,用户也毫不知情。
这类"高级闹钟"式实现,缺的不是定时能力,而是判断能力——它不能在执行前评估状态、在执行后决定是否值得打扰用户。心跳机制补的正是这块拼图。
二、心跳机制的核心思想:定时唤醒,先判断再行动
心跳机制可以概括为一句话:让 Agent 按固定间隔被唤醒,醒来第一件事不是干活,而是读一遍自己的巡检清单,评估当前状态,然后决定"告警"还是"闭嘴"。
一个形象的类比:Cron 任务像闹钟,到点就响;心跳 Agent 像巡逻的保安,每半小时在园区转一圈,没事不打扰值班室,发现异常立刻上报。二者的差异不在于"是否定时",而在于"定时之后干什么"。
2.1 心跳的执行流程
以 OpenClaw 为例,一次完整的心跳大致经过四步:
定时触发 ──► 时段过滤 ──► 上下文加载 ──► 执行与静默拦截
(every:30m) (activeHours) (SOUL/MEMORY/ (HEARTBEAT_OK
Session 注入) 被 Gateway 丢弃)
- 定时触发:默认每 30 分钟唤醒一次,间隔可配置。
- 活跃时段过滤:非活跃时段(比如深夜)直接跳过本轮心跳,省下不必要的 Token 开销。
- 上下文加载:唤醒后,Agent 的人格设定、记忆文件、会话历史照常注入,它是在"完整人格"的状态下巡检,而不是一个失忆的临时实例。
- 执行与静默拦截:Agent 按清单逐项检查,无事则输出静默信号,该信号在网关层被拦截,用户全程零感知。
2.2 静默信号:实现"无事不打扰"的关键
这是整个机制里最精巧的一环。约定一个特殊标记(OpenClaw 中为 HEARTBEAT_OK),当它出现在回复的开头或结尾、且剥离标记后剩余内容不超过约 300 字符(ackMaxChars 阈值)时,网关直接丢弃整条消息。标记出现在回复中间则不做特殊处理。反过来说,告警消息里绝不能包含这个标记,否则会被误拦截。
调试时还有一个小技巧:可以直接用自然语言让 Agent"立刻执行一次心跳巡检"。但要清楚,这种对话式触发会以普通回复的形式呈现检查结果,与真正的定时心跳(走网关静默拦截)行为不同。验证真实静默效果,应观察心跳日志或等一个自然周期确认没有新消息到达。
三、Heartbeat 与 Cron:不是替代,而是分工
心跳机制落地时最常见的问题是:它和传统的 Cron 定时任务到底什么关系?答案是分工协作,可以用一句口诀概括:心跳看状态,Cron 干活。
| 维度 | Cron 任务 | Heartbeat 心跳 |
|---|---|---|
| 触发方式 | 精确时间点 / cron 表达式 / --at 一次性 |
固定间隔轮询(默认 30 分钟) |
| 触发后行为 | 无条件执行预设动作 | 先读清单评估,再决定行动 |
| 输出特征 | 每次必有产出 | 无事时静默(信号被拦截) |
| 会话形态 | 可选主会话或独立会话 | 默认主会话,携带完整上下文 |
| 模型选择 | 可按任务指定不同模型 | 统一用心跳配置的模型 |
| 典型场景 | 生成报告、抓取数据、定点提醒 | 状态监控、异常检测、例行巡检 |
| 成本特征 | 每个任务独立计费 | 多项检查合并为一次调用 |
选型时可以按五个问题依次判断:需要在精确时间点执行吗(是→Cron)?需要与主会话隔离吗(是→Cron)?多项同频检查能合并吗(是→Heartbeat)?是一次性提醒吗(是→Cron 的 --at)?需要指定特定模型吗(是→Cron 的 --model)?都不满足,就归入心跳。
成本差异值得单独强调。假设你有 5 个监控项(邮件、日历、磁盘、任务、代码仓库),都希望每半小时看一眼。拆成 5 个 Cron 任务,每轮触发 5 次 Agent 调用、烧 5 份 Token;合并进 1 份心跳清单,每轮只花 1 份。差距是五倍量级——这不是优化技巧,而是架构选择直接决定的成本结构。
生产环境中最常用的组合是"Cron 干活 + Heartbeat 巡检":Cron 在 7:00 用独立会话抓取数据写入文件,心跳在 8:00 检查文件是否生成、内容是否合格。Cron 专注做事、互不干扰;心跳带着完整上下文做质检和兜底。对于耗时较长的任务流,还可以让 Cron 触发、心跳持续监控完成情况,形成"启动—盯梢"的闭环。
当然心跳并非万能。需要精确时间(每周一 9:00 发周报)、一次性提醒、重型计算(会阻塞主会话)、必须用高阶模型处理的任务,都应该交给 Cron。另外,拿 5 分钟的高频心跳去盯一个一天只变化两次的日历,纯属烧钱。
四、心跳清单的设计方法
心跳的行为由一份巡检清单文件(OpenClaw 中为 HEARTBEAT.md)定义。这份文件的定位是清单,不是任务手册——每次心跳它都会被注入 Prompt,写多长就烧多少 Token。官方建议控制在 200 tokens 以内,而社区最常见的错误恰恰是把清单写成几百行的操作文档。
4.1 检查项的四要素
一条合格的检查项应包含四段信息:
- 在 08:00-09:00 时段内执行此项检查
- 检查 memory/ 下今天的日报文件是否存在
- 如果不存在:发送告警「今日日报未生成,请检查任务状态」
- 如果存在且内容完整:回复 HEARTBEAT_OK
即:时段条件 → 可验证的判断标准 → 异常时的具体动作 → 正常时的静默约定。四者缺一不可,尤其最后一条——清单末尾必须明确"以上均无异常时,回复 HEARTBEAT_OK"这个停止条件,否则 Agent 总能"找出点事"来说。
4.2 三种组织形态
清单有由简到繁的三种写法,按任务规模选择:
- 自由文本:每条检查项一行,适合三五项以内的场景,如"磁盘超过 85% 告警;紧急邮件扫描;未来 2 小时日程提醒;均无异常回复 HEARTBEAT_OK"。
- 轮转调度:维护一个状态文件记录各检查项的上次执行时间戳,每次心跳只执行"最过期"的一项。适合检查项超过五个、且各自频率不同的场景。
- 结构化任务块:框架直接解析结构化的任务定义(名称、间隔、提示语),只有到期的任务才会注入本轮 Prompt;没有任务到期时整次心跳直接跳过,是官方推荐的省 Token 姿势。
4.3 关键配置项
心跳行为在主配置文件中调优,日常最核心的是"三件套":
every:心跳间隔,默认 30 分钟,设为 0 可禁用;target:消息投递目标(如"最近联系的渠道");activeHours:活跃时段窗口,配合本地时区使用。
进阶项还包括 lightContext(只加载清单不加载完整上下文,进一步省 Token)、isolatedSession(每次心跳用独立会话,省 Token 但丢失对话历史)、model(为心跳指定便宜模型)等。修改后需重启网关生效。
五、典型主动服务场景
定时巡检是最基础的用法:磁盘水位、服务存活、收件箱紧急邮件、未来两小时的日程,逐项检查、阈值判断、异常告警。
智能早报展示了心跳与 Cron 的深度配合。把日报拆成三个阶段:7:00 第一轮 Cron 广覆盖抓取三个领域的资讯并写入文件,附上覆盖评估;7:30 第二轮 Cron 读取评估结果,对薄弱领域定向补充搜索,完成后在文件末尾打上"采集确认"标记;8:00 心跳巡检该文件——文件缺失则告警"日报未生成",缺确认标记则提醒"二轮采集未完成",一切齐备则静默。相比单次抓取,这种"两轮抓取 + 一次巡检"的结构既提升了覆盖质量,又把成本拆散到可控的单元里。
异常告警是心跳的主场:监控项设定可量化阈值,越过阈值才发声,平时保持安静。
记忆守护则是一个容易被忽视的场景。很多 Agent 调教者会在配置里写"每日对话要点需归档"之类的规则,然后发现 Agent 执行几天后悄然断档——因为纯文本规则只是"期望",会话压缩、上下文丢失都可能让规则失效。解法是把软规则升级为硬巡检:在心跳清单中加一项"每 4 小时检查今天的记录文件是否存在,不存在则回顾对话并补写"。这条规则揭示了一个朴素道理:规则只是期望,机制才是保障——好的系统从不依赖自觉,而靠定期检查兜底。4 小时的频率也是权衡的结果:既避免 30 分钟级的高频浪费,又保证重要决策在被上下文压缩吞掉之前落盘。
六、频率与成本:防空转、防打扰
心跳的运营成本几乎完全由两个变量决定:清单长度 × 心跳频率。相应地,防"空转"和防打扰的设计要点可以归纳为四条:
- 精简至上。清单控制在 200 tokens 以内,每项一两行。写得越长,烧得越快。
- 阈值必须可量化。写"磁盘超过 85% 告警",而不是"磁盘快满了告警"。模糊的判断标准会让 Agent 每次都能找到话说,用户很快就会把它的推送当噪音忽略——这就是典型的"狼来了"反模式。
- 必须有停止条件。清单末尾明示静默约定,给 Agent 一个明确的"没事就闭嘴"的出口。
- 设定时段窗口。每个检查项标注适用时段(如 08:00-09:00),避免凌晨三点推送"今日日报未生成"这种荒诞消息;全局层面用 activeHours 圈定活跃时段。
两个高频翻车案例值得引以为戒。其一是"Token 焚烧炉":清单写了一整页,心跳间隔又设成 15 分钟,费用账单直接起飞——修复方法无非精简清单、放宽间隔到 30–45 分钟。其二是把心跳调成 1 分钟做快速测试:结果消息刷屏淹没对话历史,Agent 反复回显人格设定和错误信息,甚至把用户的敏感信息暴露出去。后者还提醒我们:给 Agent 下指令时,光说"做什么"不够,还得说清"不做什么",行为边界的约束不可省略。
七、常见坑速查
- 把定时推送当心跳:无条件执行、不做筛选、无反馈回路的推送,只是披着主动外衣的闹钟。
- 清单写成操作手册:每次心跳都整页注入 Prompt,成本失控。
- 告警里混入静默标记:告警消息会被网关误拦截,用户收不到。
- 对话式触发验证静默:对话里 Agent 总会回复点什么,真正的静默要看心跳日志或等自然周期。
- 重型任务塞进心跳:代码库分析、长文本生成会阻塞主会话,这类活应交给独立会话的 Cron。
- 软规则无人兜底:写在配置里的行为约定没有机制保障,迟早断档。
小结
心跳机制的本质,是把 Agent 的运行模型从"事件驱动、被动应答"扩展为"事件驱动 + 时间驱动的混合模型"。它的三个设计支点缺一不可:定时唤醒提供时间维度,完整上下文保证判断质量,静默拦截守住"无事不打扰"的体验底线。而它与 Cron 的分工——心跳看状态、Cron 干活——则给出了成本与灵活性之间的工程平衡。
更进一步,心跳还回答了 Agent 自治中的一个深层问题:如何让"期望的行为"持续发生?答案是把它从文本规则变成有周期、有检查、有兜底的机制。从被动应答到主动服务,差的从来不是一句 prompt,而是一颗按节律跳动的心脏。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐
所有评论(0)