心跳令牌成本分析

深入分析 OpenClaw 的 cron 心跳机制及其令牌成本影响。

来源

src/cron/service/timer.ts(877 行)

什么是心跳?

心跳是每 600 秒(10 分钟)发送到 LLM 的完整上下文,期望得到简单的"HEARTBEAT_OK"响应。这使长时间运行的 cron 作业保持活跃和响应。

export const DEFAULT_JOB_TIMEOUT_MS = 10 * 60_000; // 10 分钟

成本模型

每次调用的令牌消耗

场景输入令牌输出令牌总成本/次调用
(最小历史)~10,000~800~$0.045
(典型会话)~50,000~1,000~$0.165
(最大上下文)~150,000~2,000~$0.48

价格假设(Claude Opus 4.6):

  • 输入:$3/百万令牌
  • 输出:$15/百万令牌

每日成本预测

以 600 秒(10 分钟)间隔 = 每天 144 次心跳

场景令牌/天每日成本
10,800 × 144 = 1,555,200$6.48
50,800 × 144 = 7,315,200$24.15
152,000 × 144 = 21,888,000$86.40

每月预测(30 天)

场景每月成本
~$194
~$725
~$2,592

错误退避策略

当心跳错误发生时,OpenClaw 应用指数退避:

// 来自 src/cron/service/timer.ts
const ERROR_BACKOFF_SCHEDULE_MS = [
  30_000,      // 第 1 次错误  →  30 秒
  60_000,      // 第 2 次错误  →   1 分钟
  5 * 60_000,  // 第 3 次错误  →   5 分钟
  15 * 60_000, // 第 4 次错误  →  15 分钟
  60 * 60_000, // 第 5+ 次错误 →  60 分钟
];

function errorBackoffMs(consecutiveErrors: number): number {
  const idx = Math.min(consecutiveErrors - 1, ERROR_BACKOFF_SCHEDULE_MS.length - 1);
  return ERROR_BACKOFF_SCHEDULE_MS[Math.max(0, idx)];
}

MAX_SCHEDULE_ERRORS = 作业禁用前的 3 次。

超时配置

export const DEFAULT_JOB_TIMEOUT_MS = 10 * 60_000; // 10 分钟

function resolveCronJobTimeoutMs(job: CronJob): number | undefined {
  const configuredTimeoutMs =
    job.payload.kind === "agentTurn" && typeof job.payload.timeoutSeconds === "number"
      ? Math.floor(job.payload.timeoutSeconds * 1_000)
      : undefined;

  if (configuredTimeoutMs === undefined) {
    return DEFAULT_JOB_TIMEOUT_MS;
  }

  return configuredTimeoutMs <= 0 ? undefined : configuredTimeoutMs;
}

每个作业执行的超时: 10 分钟(600,000 毫秒)

优化建议

1. 增加心跳间隔

当前: 600 秒(10 分钟) 建议: 1800-3600 秒(30-60 分钟)

节省: 每日成本降低 3-6 倍

间隔心跳/天每日成本(高)
10 分钟(当前)144$86.40
30 分钟48$28.80
60 分钟24$14.40

2. 使用轻量级健康检查

用最小状态检查替换完整上下文:

  • 仅发送:作业元数据 + 上次运行状态
  • 预期响应:简单的"OK"或状态枚举
  • 令牌节省: 减少 95%+

使用轻量级检查的估计成本

  • 输入:~500 令牌(仅元数据)
  • 输出:~100 令牌
  • 成本/次调用:~$0.003
  • 每日成本:~$0.43(vs. $86.40)

3. 条件心跳

仅在以下情况发送心跳:

  • 作业有待处理工作
  • 上次运行 > 1 小时前
  • 用户明确配置 heartbeat: true

节省: 根据作业活动模式减少 50-80%

4. 心跳的上下文修剪

在心跳前应用激进的压缩:

  • 仅保留:最后 5-10 条消息
  • 旧历史的摘要
  • 令牌节省: 减少 60-80%

权衡

方法令牌节省实现复杂度风险
增加间隔高(3-6 倍)作业无响应
轻量级检查非常高(20 倍)失去上下文感知
条件式中(2-5 倍)错过边缘情况
上下文修剪中高(5-10 倍)响应的上下文减少

推荐的混合方法

  1. 增加间隔至 30 分钟(立即节省 3 倍,风险最小)
  2. 在完整心跳之间添加轻量级检查(每 5 分钟检查一次,每 30 分钟完整心跳)
  3. 对完整心跳应用上下文修剪(保留最后 10 条消息 + 摘要)

预期节省: 成本降低 80-90%,权衡可接受

交叉引用