原文标题:Why My OpenClaw Sessions Burned 21.5M Tokens in a Day (And What Actually Fixed It)

原文作者:MOSHIII

原文编译:Peggy,BlockBeats

编者按:在 Agent 应用快速普及的当下,许多团队发现一个看似反常的现象:系统运行一切正常,但 token 成本却在不知不觉中持续攀升。本文通过对一次真实 OpenClaw 工作负载的拆解发现,成本爆炸的原因往往并不来自用户输入或模型输出,而是被忽视的上下文缓存重放(cached prefix replay)。模型在每一轮调用中反复读取庞大的历史上下文,从而产生巨量 token 消耗。

文章结合具体 session 数据,展示了工具输出、浏览器快照、JSON 日志等大型中间产物如何被不断写入历史上下文,并在 agent 循环中被重复读取。

通过这一案例,作者提出了一套清晰的优化思路:从上下文结构设计、工具输出管理到 compaction 机制配置。对于正在构建 Agent 系统的开发者而言,这不仅是一份技术排查记录,也是一份真金白银的省钱攻略。

以下为原文:

我分析了一次真实的 OpenClaw 工作负载,发现了一个我认为很多 Agent 用户都会认出来的模式:

token 使用量看起来很「活跃」

回复看起来也很正常

但 token 消耗却突然爆炸式增长

下面是这次分析的 结构拆解、根本原因,以及实际可行的修复路径。

TL;DR

最大的成本驱动因素 太长。而是巨量的缓存前缀(cached prefix)被反复重放。

从 session 数据来看:

总 tokens:21,543,714

cacheRead:17,105,970(79.40%)

input:4,345,264(20.17%)

output:92,480(0.43%)

换句话说:大多数调用的成本,其实并不是在处理新的用户意图,而是在反复读取巨大的历史上下文。

「等等,怎么会这样?」的时刻

我原本以为高 token 使用量来自:非常长的用户 prompt、大量输出生成、或者昂贵的工具调用。

但真正主导的模式是:

input:几百到几千 token

cacheRead:每次调用 17 万到 18 万 token

也就是说,模型 每一轮都在反复读取同一个巨大的稳定前缀。

数据范围

我分析了两个层面的数据:

1、运行时日志(runtime logs)

2、会话记录(session transcripts)

需要说明的是:

运行日志主要用于观察行为信号(如重启、报错、配置问题)

精确的 token 统计来自 session JSONL 中的 usage 字段

使用的脚本:

scripts/session_token_breakdown.py

scripts/session_duplicate_waste_analysis.py

生成的分析文件:

tmp/session_token_stats_v2.txt

tmp/session_token_stats_v2.json

tmp/session_duplicate_waste.txt

tmp/session_duplicate_waste.json

tmp/session_duplicate_waste.png

Token 实际消耗在哪里?

1)Session 集中

有一个 session 的消耗远高于其他:

570587c3-dc42-47e4-9dd4-985c2a50af86:19,204,645 tokens

然后是明显断崖式下降:

ef42abbb-d8a1-48d8-9924-2f869dea6d4a:1,505,038

ea880b13-f97f-4d45-ba8c-a236cf6f2bb5:649,584

2)行为集中

token 主要来自:

toolUse:16,372,294

stop:5,171,420

说明问题主要出在 工具调用链循环,而不是普通聊天。

3)时间集中

token 峰值并不是随机的,而是集中在几个小时段:

2026-03-08 16:00:4,105,105

2026-03-08 09:00:4,036,070

2026-03-08 07:00:2,793,648

巨大的缓存前缀里到底有什么?

并不是对话内容,而主要是 大型中间产物:

巨大的 toolResult 数据块

很长的 reasoning / thinking traces

大型 JSON 快照

文件列表

浏览器抓取数据

子 Agent 的对话记录

在最大 session 中,字符量大约是:

toolResult:text:366,469 字符

assistant:thinking:331,494 字符

assistant:toolCall:53,039 字符

一旦这些内容被保留在历史上下文中,后续每次调用都可能 通过 cache 前缀重新读取它们。

具体示例(来自 session 文件)

在以下位置反复出现了 体量巨大的上下文块:

sessions/570587c3-dc42-47e4-9dd4-985c2a50af86.jsonl:70

大型网关 JSON 日志(约 3.7 万字符)

sessions/570587c3-dc42-47e4-9dd4-985c2a50af86.jsonl:134

浏览器快照 + 安全封装(约 2.9 万字符)

sessions/570587c3-dc42-47e4-9dd4-985c2a50af86.jsonl:219

巨大的文件列表输出(约 4.1 万字符)

sessions/570587c3-dc42-47e4-9dd4-985c2a50af86.jsonl:311

session/status 状态快照 + 大型 prompt 结构(约 3 万字符)

「重复内容浪费」vs「缓存重放负担」

我也测量了 单次调用内部的重复内容比例:

重复比例约:1.72%

确实存在,但并不是主要问题。

真正的问题是:缓存前缀的绝对体量太大

结构是:巨大的历史上下文、每轮调用重新读取、上面只叠加少量新的输入

因此优化重点不是去重,而是上下文结构设计。

为什么 Agent 循环特别容易出现这个问题?

三个机制互相叠加:

1、大量工具输出被写入历史上下文

2、工具循环会产生大量短间隔调用

3、前缀变化很小 → cache 每次都会重新读取

如果 context compaction 没有稳定触发,问题会迅速放大。

最重要的修复策略(按影响排序)

P0—不要把巨大的工具输出塞进长期上下文

对于超大工具输出:

  • 保留摘要 + 引用路径 / ID
  • 原始 payload 写入 文件 artifact
  • 不要把完整原文保留在 chat history

优先限制这些类别:

  • 大型 JSON
  • 长目录列表
  • 浏览器完整快照
  • 子 Agent 完整 transcript

P1—确保 compaction 机制真正生效

在这份数据中,配置兼容性问题多次出现:compaction key 无效

这会悄悄关闭优化机制。

正确做法:只使用版本兼容配置

然后验证:

openclaw doctor --fix

并检查启动日志确认 compaction 被接受。

P1—减少 reasoning 文本持久化

避免长推理文本被反复 replay

生产环境中:保存简短摘要,而不是完整 reasoning

P3—改善 prompt caching 设计

目标 不是最大化 cacheRead。目标是,在紧凑、稳定、高价值的前缀上使用 cache。

建议:

  • 把稳定规则放进 system prompt
  • 不要把不稳定数据放进稳定前缀
  • 避免每轮注入大量 debug 数据

实操止损方案(如果是我明天要处理)

1、找出 cacheRead 占比最高的 session

2、对 runaway session 执行 /compact

3、对工具输出加入 截断 + artifact 化

4、每次修改后重新跑 token 统计

重点追踪四个 KPI:

cacheRead / totalTokens

toolUse avgTotal/call

>=100k token 的调用次数

最大 session 占比

成功的信号

如果优化生效,你应该看到:

100k+ token 调用明显减少

cacheRead 占比下降

toolUse 调用权重下降

单个 session 的主导程度降低

如果这些指标没有变化,说明你的上下文策略仍然过于宽松。

复现实验命令

python3 scripts/session_token_breakdown.py 'sessions' \

--include-deleted \

--top 20 \

--outlier-threshold 120000 \

--json-out tmp/session_token_stats_v2.json \

> tmp/session_token_stats_v2.txt

python3 scripts/session_duplicate_waste_analysis.py 'sessions' \

--include-deleted \

--top 20 \

--png-out tmp/session_duplicate_waste.png \

--json-out tmp/session_duplicate_waste.json \

> tmp/session_duplicate_waste.txt

结语

如果你的 Agent 系统看起来一切正常,但成本却在持续上升,可以先检查一个问题:你付费的是新的推理,还是在大规模重放旧上下文?

在我的案例里,绝大部分成本其实来自 上下文重放。

一旦你意识到这一点,解决方案也就很明确:严格控制进入长期上下文的数据。

原文链接