从“等你说话”到“主动巡逻”——让 Agent 真正 7×24 运转
1. 从 Cron 到 Heartbeat:自主巡检的范式跃迁
定时任务 vs 心跳巡检:你的 Agent 该怎么“醒”
很多人搭第一个 AI Agent 都会选择日报 Agent:每天定时触发,搜索热门新闻,推送到微信 / 飞书。 看起来很好用,但是这里面有个认知误区……
- 每天固定时间执行,不管有没有值得推送的内容。 无条件
- 每次都推送同样格式的消息——即使今天全是你不关心的领域。 无筛选
- 如果搜索失败了呢?它不知道,你也不知道。 无反馈
这真的是“智能”吗?还是只是一个高级闹钟?
这个 case 做的是 Cron,不是 Heartbeat
Cron ≠ Heartbeat
Cron Task = 定时闹钟:到点就响,无条件执行。 Heartbeat = 自主巡检:醒来先看清单,判断后再决定做什么。 一个是“机械执行”,一个是“带脑子巡逻”。
1.1 Heartbeat 执行流程全景
- 定时触发 every: 30m,固定间隔唤醒。
- activeHours 过滤 非活跃时段直接跳过,省 Token。
- 上下文加载 SOUL.md + MEMORY + Session 完整注入。
- 静默拦截 HEARTBEAT_OK 被 Gateway 丢弃,用户零感知。 暂时无法在飞书文档外展示此内容
1.2 静默机制:HEARTBEAT_OK 的拦截逻辑
核心概念:Agent 回复 HEARTBEAT_OK = “一切正常,不用打扰用户”。
- HEARTBEAT_OK 出现在回复的开头或结尾 → 识别为静默信号。
- 剥离后剩余内容 ≤ 300 字符(ackMaxChars)→ 整条消息被丢弃。
- HEARTBEAT_OK 出现在回复中间 → 不做特殊处理。
- 告警消息:不包含 HEARTBEAT_OK,直接输出告警文本。
- 普通对话中出现 HEARTBEAT_OK → 自动剥离并记录日志。
看个例子: [图片]
1.3 Cron vs Heartbeat:核心区别
Cron Task(定时任务)
触发后:无条件执行预设动作 每次都有输出,可用独立 Session
上下文:隔离执行,无记忆 独立 Session 无对话历史
类比:闹钟,7:00 响就是 7:00 响
Heartbeat(心跳巡检)
触发后:先读检查清单,评估后决策 无事发生时静默(HEARTBEAT_OK)
上下文:携带完整 SOUL + MEMORY 默认在主 Session 中运行
类比:保安巡逻,每半小时转一圈,没事不打扰
两个关键差异:1. “有没有决策能力”,2. “能不能静默”。 Cron 不管三七二十一都会推消息,Heartbeat 没大事汇报就闭嘴。
调试技巧:手动唤醒
问题:心跳默认每 30 分钟触发一次,调试时不可能每次都等半小时。 解决方案:直接在飞书中用自然语言让 Agent 执行巡检。
请立刻执行一次心跳巡检
现在跑一遍你的巡检清单
检查一下 HEARTBEAT.md 里的所有检查项,告诉我结果
注意区别:自然语言触发是对话式执行,Agent 可能在当前对话中回复结果,与真正定时心跳有差异(后者走 Gateway 静默拦截)。调试阶段够用,验证静默行为时需等自然心跳周期触发。
AI check AI:你的 Agent 现在有什么“定时能力”?
在飞书中发送: [图片] [图片]
2. Cron 还是 Heartbeat?场景选型与组合策略
五个问题帮你做决定。
选型决策树:五个问题定方案
- Q1-Q2 → Cron 精确时间、需要隔离的任务。
- Q3 → Heartbeat 同频率检查可合并,节省成本。
- Q4-Q5 → Cron 一次性提醒或需指定模型。
- 默认 → Heartbeat 大多数监控类任务最终落到 Heartbeat。 暂时无法在飞书文档外展示此内容
一句话记住:心跳看状态,Cron 干活 Heartbeat 擅长“看” Cron 擅长“做” 收件箱有没有紧急邮件? 每天 7:00 生成晨间简报 日历上 2 小时内有没有会议? 每周五 17:00 生成周报 服务器磁盘是不是快满了? 20 分钟后提醒我开会 共同特征:检查状态 → 判断 → 静默或告警 共同特征:在指定时间执行具体任务
成本差距:5 个 Cron VS 5 个任务 1 个 Heartbeat 5x
Token 成本差距 5 次 方案 A: 5 个 Cron job 每次 5 份 Token 消耗 1 次 方案 B: 1 个 HEARTBEAT.md 每次 1 份 Token 消耗 场景:5 个每 30 分钟检查的监控任务(邮件、日历、磁盘、任务、Git)。
- 方案 A:创建 5 个 Cron Job → 每次触发 5 次 Agent turn → 5 份 Token 消耗。
- 方案 B:写入 1 个 HEARTBEAT.md → 每次触发 1 次 Agent turn → 1 份 Token 消耗。 结论:同频率监控任务,合并到 Heartbeat 比拆成多个 Cron 便宜。
Cron vs Heartbeat 完整对比矩阵 维度 Cron Heartbeat 触发方式 精确时间 / cron 表达式 / –at 固定间隔 Session 通常是独立 Session 默认主 Session 上下文 独立 Session 无对话历史 携带完整 Agent 上下文 静默能力 无(每次都有输出) 有(HEARTBEAT_OK 被拦截) 模型选择 可为每个 Job 指定不同模型 统一使用心跳配置的模型 适用场景 报告生成、数据抓取、定时提醒 状态监控、异常检测、例行巡检 成本特征 每个 Job 独立计费 多项检查合并为一次调用 Cron 灵活但贵,Heartbeat 省钱但粗——根据场景选择。
四种典型组合模式 模式1:纯 Cron 每天 9:00 发周报、20 分钟后提醒开会 时间精确、一次性任务 模式2:纯 Heartbeat 每 30 分钟检查邮件 + 日历 + 服务器 多项监控合并、成本最优 模式3:Cron 干活 + Heartbeat 巡检 Cron 7:00 抓数据写文件 Heartbeat 8:00 检查文件是否生成 模式4:Cron 启动 + Heartbeat 持续监控 Cron 触发一个长任务 Heartbeat 持续检查任务是否完成 适合耗时较长的工作流
社区实践:什么情况下 Heartbeat 不合适?
- “每周一 9:00 发周报”——需要精确时间,用 Cron。
- “17 分钟后提醒我”——一次性提醒,用 Cron –at。
- 重型任务(代码库分析、长文本生成)——会阻塞主 Session。
- 需要用高阶模型(Opus)处理——用 Cron 指定 –model。
- 心跳间隔太短(5 分钟)检查一天只变两次的日历——浪费 Token。
适合 Heartbeat 的信号:同频率、轻量级、需要判断、正常情况应该静默。
3. HEARTBEAT.md 设计方法与社区案例
写好心跳清单:社区案例与避坑指南。
HEARTBEAT.md 的定位:心跳清单,不是任务手册
官方定义:小而稳定、每 30 分钟安全注入一次的检查清单。
- 文件为空(只有标题没有内容)→ OpenClaw 自动跳过心跳,节省 API 调用
- 文件不存在 → 心跳仍会运行,模型自行决定做什么(不推荐)
- 核心原则:Keep it Tiny —— 精简才是正义
- 每次心跳都会把 HEARTBEAT.md 注入 Prompt,内容越长 → Token 消耗越大
社区案例
社区案例一:VPS 运维巡检(最简模式)
原始代码
# HEARTBEAT.md
- VPS disk: run `df -h` and alert
if any partition is above 85%.
- VPS memory: run `free -h` and alert
if used is above 90%.
- Inbox: scan for urgent emails and
draft replies when clearly needed.
- Calendar: check next 2 hours and
remind me 15 min before events.
- If nothing needs attention
reply HEARTBEAT_OK.中文翻译
# 心跳巡检清单
- 磁盘:执行 df -h,
任何分区超过 85% 则告警
- 内存:执行 free -h,
使用率超过 90% 则告警
- 收件箱:扫描紧急邮件,
必要时起草回复
- 日历:检查未来 2 小时日程,
提前 15 分钟提醒
- 以上均无异常,
回复 HEARTBEAT_OK来源:LumaDock 社区教程。特点:每条一行,阈值明确。关键:最后一行停止条件必须有。
社区案例二:轮转心跳(多任务调度模式)
原始代码
# HEARTBEAT.md
## Cadence-Based Checks
Read `heartbeat-state.json`.
Run whichever check is most overdue.
**Cadences:**
- Email: every 30 min (9AM-9PM)
- Calendar: every 2h (8AM-10PM)
- Tasks: every 30 min (anytime)
- Git: every 24h (anytime)
- System: every 24h (3 AM only)
**Process:**
1. Load timestamps from state file
2. Find most overdue check
3. Run that check
4. Update timestamp
5. Report or HEARTBEAT_OK中文翻译
# 心跳巡检清单
## 基于节奏的轮转检查
读取状态文件,
执行最过期的那项检查。
**各任务频率:**
- 邮件:每 30 分钟(9 点-21 点)
- 日历:每 2 小时(8 点-22 点)
- 任务:每 30 分钟(全天)
- Git:每 24 小时(全天)
- 系统:每 24 小时(仅凌晨 3 点)
**执行流程:**
1. 从状态文件加载上次时间
2. 计算哪项最过期
3. 执行该项检查
4. 更新时间戳
5. 有事报告,没事静默来源:digitalknk。特点:每次只跑最过期一项。适合任务 5+ 的场景。
官方推荐:结构化 tasks: block(自动调度)
原始代码
tasks:
- name: inbox-triage
interval: 30m
prompt: "Check for urgent unread emails and flag anything time sensitive."
- name: calendar-scan
interval: 2h
prompt: "Check for upcoming meetings that need prep or follow-up."
# Additional instructions
- Keep alerts short.
- If nothing needs attention after all due tasks, reply HEARTBEAT_OK.中文翻译
任务列表:
- 名称:邮件分诊
间隔:30 分钟
指令:“检查紧急未读邮件,标记时间敏感的内容”
- 名称:日历扫描
间隔:2 小时
指令:“检查即将到来的会议,是否需要准备或跟进”
# 补充指令
- 告警保持简短
- 所有到期任务均无异常,回复 HEARTBEAT_OKOpenClaw 自动解析 tasks: block,只有到期任务注入心跳 Prompt。
没有任务到期 → 整次心跳被跳过(reason=no-tasks-due)。
openclaw.json 心跳配置项全景
| 配置项 | 默认值 | 说明 |
|---|---|---|
| every | “30m” | 心跳间隔,“0m” = 禁用 |
| target | “none” | 消息投递目标,“last” = 最近联系的渠道 |
| activeHours.start / end | 无 | 活跃时段窗口(本地时区) |
| model | 继承默认 | 心跳专用模型(可用便宜模型降本) |
| lightContext | false | true = 只加载 HEARTBEAT.md,不加载完整上下文 |
| isolatedSession | false | true = 每次心跳用独立 Session(省 Token,但无对话历史) |
| directPolicy | “allow” | DM 投递策略,“block” = 禁止私聊推送 |
| includeReasoning | false | true = 额外发送推理过程消息 |
日常三件套:every(多久跑一次)+ target(消息发到哪)+ activeHours(几点到几点活跃)。其余为进阶配置。
检查项编写四步法:条件 → 判断 → 动作 → 静默
- 条件:什么时段执行?(时段窗口)
- 判断:检查什么?判断标准是什么?(明确、可验证)
- 动作:异常时做什么?(具体的告警文本或执行操作)
- 静默:正常时怎么处理?(回复 HEARTBEAT_OK,不多说一个字)
模板示例:
在 HH:MM-HH:MM 时段内执行此项检查
检查 [目标] 是否满足 [条件]
如果不满足:[具体动作]
如果满足:回复 HEARTBEAT_OK
反模式警示:心跳的两种“翻车姿势”
“狼来了”模式
症状 每次心跳都推送消息,用户被轰炸后直接忽略
原因 检查项写得太模糊,Agent 总能找到点什么说
修复 判断条件必须可量化(“>85%” 而非“磁盘快满了”)
Token 焚烧炉模式
症状 每月 Token 费用暴增
原因 HEARTBEAT.md 写了一整页,注入频率太高
修复 精简清单( < 200 tokens)+ 合理间隔(30-45min)
社区翻车实录:1 分钟心跳的教训
案例来源:Medium 用户 @C.Dalrymple 的 OpenClaw 实战日志。
场景:用户将心跳设为 1 分钟以快速测试 X/Twitter 监控功能。
WhatsApp 消息疑似刷屏,Agent 不断回显 SOUL.md 内容和错误信息。
更严重:Agent 在尝试发帖时,暴露了用户的手机号码。
对话历史被大量心跳消息淹没,正常交互无法进行。
用户总结:
OpenClaw 需要明确的指令和防护栏,光告诉它“做什么”不够,还必须告诉它“不做什么”
这正是 SOUL.md Boundaries 层的意义所在
HEARTBEAT.md 四条黄金法则
精简至上
控制在 200 tokens 以内,每条检查项一两行 清单不是论文
阈值明确
用可量化的判断条件 “>85%”、“文件不存在”、“缺少标记”
必须有停止条件
最后一行写明“以上均无异常时,回复 HEARTBEAT_OK” 没有这行 = “狼来了”
设定时段窗口
每个检查项标注适用时段“08:00-09:00” 避免凌晨 3 点推送“今日日报未生成”
小结
- 心跳清单不是任务手册 检查项四步法:条件 → 判断 → 动作 → 静默。三种写法:自由文本 / 轮转调度 / tasks: block。
- 配置三件套 every + target + activeHours,日常最常用的三个参数。
- 四条黄金法则 精简、阈值明确、有停止条件、设时段窗口——避免“狼来了”和 Token 焚烧炉。
4. 实战:Cron + Heartbeat 打造高质量日报
每天早上 7 点,让 Agent 帮你读完全网资讯。
为什么一次抓取不够?
- 单次搜索覆盖面有限,容易遗漏重要信息 —— 质量问题
- 所有逻辑塞在一次执行中,Token 消耗大且不可控 —— 成本问题
- 新方案:拆分为“两轮抓取 + 一次巡检”的组合架构 —— 解决方案
Cron 负责干活(抓数据、写文件),Heartbeat 负责巡检(检查质量、异常告警)
三阶段组合架构总览
- 07:00 第一轮抓取
Cron + 独立 Session,三领域广覆盖。 - 07:30 第二轮补充
读取第一轮结果,定向补充薄弱领域。 - 08:00 心跳巡检
检查日报是否完整,异常才推送。
设计要点:Cron 用独立 Session,Heartbeat 用主 Session。
Step 1:确认当前状态
飞书对话:
帮我检查一下当前的 Heartbeat 配置状态:
1. 读取 openclaw.json 中 heartbeat 相关配置
2. 读取当前 HEARTBEAT.md 的内容
3. 列出 memory/ 目录下现有的文件
4. 确认当前的时区设置
确认要点:
- heartbeat 已启用
- every / target / activeHours 三件套配置
- 巡检清单
- 每日记录
- 时区正确
Step 2:注册第一轮 Cron 任务(07:00 三领域抓取)

Step 3:注册第二轮 Cron 任务(07:30 定向补充)

Step 4:编写 HEARTBEAT.md 巡检清单

对应设计:
- 时段窗口 黄金法则 4:08:00-09:00。
- 明确判断条件 黄金法则 2:文件存在 / 缺失 / 包含标记。
- 三种结果分支 告警 / 提醒 / 静默。
- 停止条件 黄金法则 3
Step 5:配置心跳参数三件套

Step 6:手动触发验证
第一轮抓取

第二轮抓取

Step 7:巡检三种场景
| 场景 | 状态 | 预期结果 |
|---|---|---|
| 场景 A | 日报缺失 | 收到「⚠️ 今日资讯日报未生成」 |
| 场景 B | 日报半完成 | 收到「资讯日报第二轮采集尚未完成」 |
| 场景 C | 日报完整 | 期望静默 |

注意:对话式触发下如果 Agent 会回复检查结果(如“日报完整,无异常”)——这是正常的。
真正的静默验证:观察 Dashboard 心跳日志,或等下一个自然心跳周期,确认飞书无新消息。
小结
- 组合架构 Cron 负责干活(两轮抓取),Heartbeat 负责巡检(质量检查)。
- 两轮抓取策略 第一轮广覆盖,第二轮定向补充薄弱领域。
- 三分支设计 HEARTBEAT.md 的三分支:完整 → 静默、缺失 → 告警、半完成 → 提醒。
5. 总结
| 知识点 | 一句话总结 |
|---|---|
| Cron vs Heartbeat | Cron = 定时闹钟,Heartbeat = 带脑子的巡逻保安 |
| 选型决策树 | 五个问题定方案:精确时间?隔离?可合并?一次性?特殊模型? |
| 成本口诀 | 同频率监控合并到 Heartbeat,Token 成本降 5 倍 |
| 静默机制 | HEARTBEAT_OK 被 Gateway 拦截,用户零打扰 |
| 四条黄金法则 | 精简、阈值明确、有停止条件、设时段窗口 |
| 组合架构 | Cron 干活 + Heartbeat 巡检 = 高质量自动化 |
| 机制 > 规则 | 规则只是期望,心跳才是执行保障 |