openclaw heartbeat节省token的小技巧

最近一段时间有空的时候在研究如何降低openclaw的token消耗
因为基本上如果一天不干什么不和它对话的话,也要吞掉我十几二十刀的gpt5.4额度
于是看了一下平常的请求,发现heartbeat这个操作真耗token啊,动不动一个请求就90k token :sweat_smile:
这费用还是我给openclaw打了缓存补丁之后,要是没打补丁更是上天
我的heartbeat相关配置之前是这样的,当时就是直接照抄了站内的教程(我记得是两篇巨长的文章)

      "heartbeat": {
        "every": "30m",
        "target": "last",
        "directPolicy": "allow"
      },

然后我发现请求体里面一直在同一个session重复 “Read HEARTBEAT.md …”, 都重复一百多次了!

{
  "model": "gpt-5.4",
  "input": [
    {
      "role": "developer",
      "content": "You are a personal assistant running inside OpenClaw.\n## Tooling\nTool availabili...[42548 chars]"
    },
    {
      "role": "user",
      "content": [
        {
          "type": "input_text",
          "text":  (省略。。。)
        }
      ]
    },
    {
      "type": "message",
      "role": "assistant",
      "content": [
        {
          "type": "output_text",
          "text": "I'll check HEARTBEAT.md for any periodic tasks.",
          "annotations": []
        }
      ],
      "status": "completed",
      "id": "msg_1"
    },
 (省略一堆function call。。。)
 
    {
      "type": "message",
      "role": "assistant",
      "content": [
        {
          "type": "output_text",
          "text": "Memory maintenance was already done today (2026-04-03). The backup notification ...[63 chars]",
          "annotations": []
        }
      ],
      "status": "completed",
      "id": "msg_5"
    },
    {
      "role": "user",
      "content": [
        {
          "type": "input_text",
          "text": "Read HEARTBEAT.md if it exists (workspace context). Follow it strictly. Do not i...[311 chars]"
        }
      ]
    },
    {
      "role": "user",
      "content": [
        {
          "type": "input_text",
          "text": "Read HEARTBEAT.md if it exists (workspace context). Follow it strictly. Do not i...[311 chars]"
        }
      ]
    },
    {
      "role": "user",
      "content": [
        {
          "type": "input_text",
          "text": "Read HEARTBEAT.md if it exists (workspace context). Follow it strictly. Do not i...[311 chars]"
        }
      ]
    },
    {
      "role": "user",
      "content": [
        {
          "type": "input_text",
          "text": "Read HEARTBEAT.md if it exists (workspace context). Follow it strictly. Do not i...[311 chars]"
        }
      ]
    },
    {
      "role": "user",
      "content": [
        {
          "type": "input_text",
          "text": "Read HEARTBEAT.md if it exists (workspace context). Follow it strictly. Do not i...[311 chars]"
        }
      ]
    },
    {
      "role": "user",
      "content": [
        {
          "type": "input_text",
          "text": "Read HEARTBEAT.md if it exists (workspace context). Follow it strictly. Do not i...[311 chars]"
        }
      ]
    },
    {
      "role": "user",
      "content": [
        {
          "type": "input_text",
          "text": "Read HEARTBEAT.md if it exists (workspace context). Follow it strictly. Do not i...[311 chars]"
        }
      ]
    },
    {
      "role": "user",
      "content": [
        {
          "type": "input_text",
          "text": "Read HEARTBEAT.md if it exists (workspace context). Follow it strictly. Do not i...[311 chars]"
        }
      ]
    },
    {
      "role": "user",
      "content": [
        {
          "type": "input_text",
          "text": "Read HEARTBEAT.md if it exists (workspace context). Follow it strictly. Do not i...[311 chars]"
        }
      ]
    },
    {
      "role": "user",
      "content": [
        {
          "type": "input_text",
          "text": "Read HEARTBEAT.md if it exists (workspace context). Follow it strictly. Do not i...[311 chars]"
        }
      ]
    },
    {
      "role": "user",
      "content": [
        {
          "type": "input_text",
          "text": "Read HEARTBEAT.md if it exists (workspace context). Follow it strictly. Do not i...[311 chars]"
        }
      ]
    },
    {
      "role": "user",
      "content": [
        {
          "type": "input_text",
          "text": "Read HEARTBEAT.md if it exists (workspace context). Follow it strictly. Do not i...[311 chars]"
        }
      ]
    },
    {
      "role": "user",
      "content": [
        {
          "type": "input_text",
          "text": "Read HEARTBEAT.md if it exists (workspace context). Follow it strictly. Do not i...[311 chars]"
        }
      ]
    },
    {
      "role": "user",
      "content": [
        {
          "type": "input_text",
          "text": "Read HEARTBEAT.md if it exists (workspace context). Follow it strictly. Do not i...[311 chars]"
        }
      ]
    },
    {
      "role": "user",
      "content": [
        {
          "type": "input_text",
          "text": "Read HEARTBEAT.md if it exists (workspace context). Follow it strictly. Do not i...[311 chars]"
        }
      ]
    },
    {
      "role": "user",
      "content": [
        {
          "type": "input_text",
          "text": "Read HEARTBEAT.md if it exists (workspace context). Follow it strictly. Do not i...[311 chars]"
        }
      ]
    },
    "...[159 more items]"
  ],

  "tools": [
 (省略。。。)
  ],
  "reasoning": {
    "effort": "high",
    "summary": "auto"
  },
 (省略。。。)
  "instructions":  (省略。。。)
}

然后我就把这个问题丢给codex了,让我添加这两个配置:

      "heartbeat": {
        "every": "30m",
        "isolatedSession": true,
        "lightContext": true,
        "target": "none",
        "directPolicy": "allow"
      },
  • isolatedSession写成true的意思是,heartbeat 会在“没有 prior conversation history 的 isolated session”里运行,能明显减少token消耗
  • 如果再启用lightContext,那么比如AGENTS.md、USER.md、TOOLS.md、MEMORY.md之类的bootstrap文件就不会在heartbeat的时候注入(只有HEARTBEAT.md会被注入上下文)。所以如果你的HEARTBEAT.md写的很明确,告诉openclaw要读哪个文件要干什么,那就完全可以开启,进一步节省token. 如果HEARTBEAT.md写的很模糊,需要openclaw综合你的AGENTS.md, MEMORY.md之类的进行综合判断,那可能还是别加了。
  • "target"改为none,就防止heartbeat的消息和用户消息放的太近

修改后,我的heartbeat请求基本上只有10k左右token了

每次的请求体也明显干净多了

{
  "model": "gpt-5.4",
  "input": [
    {
      "role": "developer",
      "content": "You are a personal assistant running inside OpenClaw.\n## Tooling\nTool availabili...[36009 chars]"
    },
    {
      "role": "user",
      "content": [
        {
          "type": "input_text",
          "text": "Read HEARTBEAT.md if it exists (workspace context). Follow it strictly. Do not i...[313 chars]"
        }
      ]
    }
  ],
  "tools": [
    (省略。。。)
  ],
  "reasoning": {
    "effort": "high",
    "summary": "auto"
  },

  "instructions":  (省略。。。)

这样heartbeat就不会带一堆重复的heartbeat请求了 :bili_040:

15 Likes

heartbeat一晚上跑了15m的gpt-5.5,基本上还都是无缓存的。服了。感谢大佬的教程,配置上我在观察一下

1 Like