#心跳与定时任务的疑问
1 messages · Page 1 of 1 (latest)
先给结论,这块确实容易绕。最好再贴一下 openclaw --version,因为这部分最近改动挺多。按当前 docs/main,核心是:
1) 会把“工作区”注入上下文吗?
会,但不是把整个工作区目录都塞进去。
注入的是 workspace 里的 bootstrap files,比如 AGENTS.md、SOUL.md、USER.md、HEARTBEAT.md 等,不是任意文件。
- Heartbeat 默认是 main session turn,所以它默认有:
- 主会话历史
- workspace bootstrap files
- 但如果你开了:
heartbeat.lightContext: true→ 只保留HEARTBEAT.mdheartbeat.isolatedSession: true→ 不带之前聊天历史
- Cron:
session=isolated→ 跑在独立cron:<jobId>会话里,不继承主聊天历史--light-context→ cron 的 bootstrap context 会直接变空
所以你感觉它“不太聪明、记不住约定”,最常见就是:
- 约定只写在聊天里,没写进
AGENTS.md/HEARTBEAT.md - heartbeat 开了
isolatedSession - cron 用了
isolated - cron 还开了
--light-context
2) 可以用私聊渠道的会话触发定时任务吗?
可以,但不是用 main。
你要区分:
main= agent 的主会话- 私聊/群聊/频道 session = 某个具体聊天上下文
如果你想让 cron 复用某个私聊 session 的上下文,要用:
sessionTarget = current
在“创建任务的那个会话”里绑定当前 session
- 或
session:<sessionKey>
显式绑定某个已知 session key
一个重要细节:
current 只有在“有当前聊天上下文”时才会解析成功。
如果你是在纯 CLI/headless 环境里创建,没有当前 session,它会回退成 isolated。
3) 定时任务里的“主会话” vs “隔离会话”
主会话(main)
- 不是独立 agent run
- 是往主时间线塞一个 system event
- 然后由 heartbeat / 主会话去处理
- 适合提醒、触发器、让主脑子接着干
隔离会话(isolated)
- 真正启动一次独立 assistant run
- 会话是
cron:<jobId>
- 默认不带主聊天历史
- 适合日报、总结、批处理、后台任务
如果你希望“更聪明、更记得约定”,通常优先:
- 把长期规则写进
AGENTS.md - 把 heartbeat 专用规则写进
HEARTBEAT.md - 需要连续记忆时,不要用 isolated,改用
current或session:<...>
4) “发布消息到主时间线” vs “运行助手任务(隔离)”
这是“执行内容”的区别,不是投递区别。
发布消息到主时间线
- 本质是
systemEvent - 把一段文字投到主会话
- 更像“提醒主会话下一轮去做事”
运行助手任务(隔离)
- 本质是
agentTurn - 直接跑一次独立 assistant task
- 用你写的 prompt 当任务输入
简化理解:
- 想“提醒主会话做某事” → 选 发布消息到主时间线
- 想“现在就单独跑个任务” → 选 运行助手任务(隔离)
5) 投递里的“发布摘要 / webhook / 无”
这是“执行完以后,结果往哪送”。
发布摘要(默认)
- 把运行结果摘要发到聊天里
- 这是 isolated agentTurn 常见默认值
webhook
- 执行完成后,往一个 URL 发 HTTP POST
- 适合接自己系统
无(仅内部)
- 任务照跑
- 但不往聊天/Webhook 发结果
- 结果只留在内部记录 / task ledger
6) 为什么 heartbeat / cron 会显得笨
我基本可以确定就是“上下文少了”,不是你错觉。
优先检查这几个点:
AGENTS.md里有没有你说的那些“约定”HEARTBEAT.md有没有写 heartbeat 专用规则- heartbeat 有没有开:
lightContext: true
isolatedSession: true
- cron 有没有用:
session=isolated--light-context
- 有没有给 heartbeat / cron 单独配了更弱的 model
我建议你怎么配
- 要聪明、记得上下文
heartbeat 用主 session,cron 用current/session:<...> - 要省 token
heartbeat 才开isolatedSession + lightContext - 要稳定遵守规则
把规则写进AGENTS.md,不要只放在聊天历史里
文档:
- https://docs.openclaw.ai/gateway/heartbeat
- https://docs.openclaw.ai/concepts/agent-workspace
- https://docs.openclaw.ai/concepts/session
如果你愿意,我下一条可以直接按你的配置思路,给你一份“想保留记忆的 heartbeat/cron 推荐配置”和“省 token 但容易变笨的配置”对照表。
我cron任务配置为
主会话
发布消息到主时间线
投递选择无(仅内部)
点击执行,运行历史显示已跳过,disabled,是什么问题
还有我选择主会话后,投递只能选择无(仅内部)或者webhook,那么选无(仅内部)能收到消息吗
这次基本能定位了。
你这个组合:
- 主会话
- 发布消息到主时间线
- 投递 = 无(仅内部)
本质上不是“cron 自己发消息”,而是:
- cron 往 main session 塞一个 system event
- 然后尝试唤醒 heartbeat 去处理它
所以如果运行历史里是 skipped / disabled,很大概率是:
1) heartbeat 被关了
按源码,main session + wake now 会去跑一次 heartbeat。
如果 heartbeat 返回 disabled,这个 cron run 就会记成 skipped / disabled。
最常见就是这里被设成了:
agents.defaults.heartbeat.every: "0m"
或者对应 agent 的 heartbeat 被禁用了。
2) 如果这是一次性任务(at)
一次性任务在 ok / skipped 后会被自动停用,避免死循环。
所以你可能会同时看到:
- 这次 run 是
skipped
- job 现在变成了
disabled
你问的第二个点
选了“主会话”后,投递只有 “无” 或 “webhook”,为什么?
因为 “发布摘要(announce)”是给隔离 assistant run 用的。
而你现在选的是:
- 主会话
- system event
这不是一个独立 assistant task,所以没有“给这个独立任务发摘要到聊天”的路径。
那“无(仅内部)”能收到消息吗?
默认不能指望收到 cron 自己发出的消息。
无(仅内部) 的意思就是:
- cron 不做外部投递
- 不往聊天发 summary
你最多只能期待:
- 这个 system event 被 main session/heartbeat 处理后
- heartbeat 再决定发一条消息出来
所以如果:
- heartbeat 是禁用的
- 或 heartbeat 的
target不是可投递目标
- 或这次 heartbeat 没真的跑起来
那你就不会收到消息。
可以这样理解
你的当前配置适合
“往主脑子里塞一句提醒,等它下一轮自己处理”
不适合
“定时到了,直接给我发一条消息”
如果你想要定时到了就稳定给你回消息,更适合用:
- 隔离会话
- 运行助手任务(隔离)
- 发布摘要(默认)
我建议你怎么选
想直接收到消息
选:
- 隔离会话
- 运行助手任务(隔离)
- 发布摘要(默认)
想只是给主会话加个内部提醒
选:
- 主会话
- 发布消息到主时间线
- 无(仅内部)
但前提是 heartbeat 不能关,否则这个提醒没人处理。
先查这几个
麻烦贴一下这几个输出,我就能直接告诉你是哪一类:
openclaw --version
openclaw cron runs --id <jobId> --limit 20
openclaw system heartbeat last
文档:
如果你愿意,我下一条可以直接给你一套“想收到消息”的 cron 推荐配置。
如果选主会话,和运行助手任务(隔离),又是什么意思呢
这个组合其实是不成立的,可以直接理解成“选项打架了”。
源码里的硬限制是:
• sessionTarget="main" 只能配 systemEvent
• sessionTarget="isolated" | "current" | "session:..." 只能配 agentTurn
也就是:
合法组合只有两类
| 会话 | 执行内容 | 含义 |
| -------------------------- | ---------- | ---------------------------------------------------- |
| 主会话 | 发布消息到主时间线 | 往 main session 塞一条 system event,让 heartbeat / 主会话去处理 |
| 隔离 / current / 自定义 session | 运行助手任务(隔离) | 真正启动一次 assistant run |
───
所以你问的这个
“主会话 + 运行助手任务(隔离)”是什么意思?
严格说,没意义,属于无效组合。
它不是“让主会话跑一个隔离任务”,而是:
• 前半句要求它走 main session
• 后半句又要求它走 agentTurn / isolated run
这两个方向是冲突的。
如果 UI 里暂时让你选到了,可以把它当成:
• 前端还没完全拦住
• 但后端语义上不支持
───
你可以这么记
选“主会话”
你就是在说:
不要单独跑任务,
只是往主会话脑子里塞一句话。
所以执行内容必须是:
• 发布消息到主时间线
───
选“运行助手任务(隔离)”
你就是在说:
现在单独开一个任务自己跑。
所以会话必须是:
• 隔离
• 或 current
• 或 session:xxx
───
最简单的口诀