目录

OpenClaw 自动压缩崩溃修复:reserveTokensFloor 调优实战

一次 Auto-compaction could not recover 故障的完整排查与修复

OpenClaw 自动压缩崩溃修复:reserveTokensFloor 调优实战

深夜的报错:Auto-compaction could not recover

正常使用 OpenClaw 时,突然遇到一条报错:

Auto-compaction could not recover this turn. This might be expected for conversations with very long outputs. If this happens frequently, try setting reserveTokensFloor to 50000 or higher.

翻译过来就是:自动压缩无法恢复本轮对话。 如果频繁出现,请将 reserveTokensFloor 设为 50000 或更高。

/images/Code-Art-Studio-images/openclaw-compaction-optimization/illustrations/1.webp

这条报错意味着 OpenClaw 的对话上下文管理机制——compaction(压缩)——在尝试回收 token 空间时失败了,导致当前对话轮次无法正常保存。如果放任不管,后续对话会越来越不稳定,最终可能丢失上下文。

根因诊断:reserveTokensFloor 过低

首先检查当前配置:

"compaction": {
  "mode": "safeguard",
  "reserveTokensFloor": 16000,
  "reserveTokens": 24000,
  "keepRecentTokens": 48000,
  "memoryFlush": {
    "enabled": true,
    "softThresholdTokens": 4000
  }
}

问题很明显:reserveTokensFloor = 16000。这个参数的含义是"无论如何都要保留的最小 token 数"。当对话积累到一定长度、工具输出又特别大时,16000 的底线不够用,压缩机制无法腾出空间,于是报错。

/images/Code-Art-Studio-images/openclaw-compaction-optimization/illustrations/2.webp

逐字段配置调优

查阅 OpenClaw 官方 schema 后,对每个字段逐一分析并优化:

参数原值新值原因
reserveTokensFloor1600050000核心修复。保证至少保留 5 万 token,防止压缩失败
reserveTokens2400032000工具输出较长,预留更多回复空间
keepRecentTokens48000不变保留最近对话不动,已足够
truncateAfterCompaction未设置trueJSONL 轮转防膨胀,压缩后自动截断
maxActiveTranscriptBytes未设置“20mb”二层防线,限制转录文件大小上限
memoryFlush.enabledtrue不变压缩前自动记忆刷新,保持
memoryFlush.softThresholdTokens4000不变压缩前触发记忆刷新的阈值

重点参数说明

reserveTokensFloor:compaction 机制的"安全底线"。无论对话多长、工具输出多大,系统都会确保至少保留这个数量的 token 不压缩。设为 50000 后,即使遇到超长工具输出也能正常回收。

reserveTokens:每次回复时预留的 token 空间。从 24000 提升到 32000,给多轮工具调用留出余量。

truncateAfterCompaction:设为 true 后,每次压缩完成都会轮转 JSONL 文件,防止转录文件无限膨胀。

maxActiveTranscriptBytes:限制当前活跃转录文件的最大字节数,作为二层防线。

执行过程:config.patch 被拒后的绕过方案

尝试用 config.patch 直接修改:

openclaw config.patch '{"agents":{"defaults":{"compaction":{"reserveTokensFloor":50000}}}}'

被拒绝,提示路径受保护(protected path)。这意味着 compaction 配置属于不可直接 patch 的深层嵌套字段。

/images/Code-Art-Studio-images/openclaw-compaction-optimization/illustrations/3.webp

回退方案:用 Python 脚本直接修改 openclaw.json

python3 -c "
import json
with open('/home/oklife/.openclaw/openclaw.json', 'r') as f:
    cfg = json.load(f)
cfg['agents']['defaults']['compaction']['reserveTokensFloor'] = 50000
cfg['agents']['defaults']['compaction']['reserveTokens'] = 32000
cfg['agents']['defaults']['compaction']['truncateAfterCompaction'] = True
cfg['agents']['defaults']['compaction']['maxActiveTranscriptBytes'] = '20mb'
with open('/home/oklife/.openclaw/openclaw.json', 'w') as f:
    json.dump(cfg, f, indent=2, ensure_ascii=False)
"

修改后验证配置:

openclaw config.validate
# Config valid ✅

确认三处修改全部生效:

"compaction": {
  "mode": "safeguard",
  "reserveTokensFloor": 50000,
  "reserveTokens": 32000,
  "keepRecentTokens": 48000,
  "truncateAfterCompaction": true,
  "maxActiveTranscriptBytes": "20mb",
  "memoryFlush": {
    "enabled": true,
    "softThresholdTokens": 4000
  }
}

恢复方案

如需回滚到原始配置:

python3 -c "
import json
with open('/home/oklife/.openclaw/openclaw.json', 'r') as f:
    cfg = json.load(f)
cfg['agents']['defaults']['compaction']['reserveTokensFloor'] = 16000
cfg['agents']['defaults']['compaction']['reserveTokens'] = 24000
del cfg['agents']['defaults']['compaction']['truncateAfterCompaction']
del cfg['agents']['defaults']['compaction']['maxActiveTranscriptBytes']
with open('/home/oklife/.openclaw/openclaw.json', 'w') as f:
    json.dump(cfg, f, indent=2, ensure_ascii=False)
"

经验总结

  1. reserveTokensFloor 是关键:OpenClaw 的 compaction 机制依赖这个参数作为安全底线。模型越大、工具输出越长,这个值就需要越高。建议 50000 起步。
  2. config.patch 有保护路径:深层嵌套的配置字段(如 compaction 下的子字段)可能无法通过 config.patch 修改,需要直接编辑 openclaw.json。
  3. 二层防线策略:truncateAfterCompaction 处理短时间内的问题,maxActiveTranscriptBytes 作为长期防膨胀的兜底。
  4. 修改后务必验证openclaw config.validate 确保配置语法正确,避免启动失败。

参考来源


–全文完–

感谢阅读
若你有故事想讲、有困惑想聊、或是想找个人说说心里话,甚至只是吐槽发泄一下情绪,都欢迎来找我聊聊:   《内容已折叠,点击展开》

希望我写的每一个字,成为我自己和某个人活下去、拼下去的力量。                     《内容已折叠,点击展开》

“技术终归是工具,而我们一次次认真把问题理顺,守住的其实不只是页面样式和代码输出,还有那一点不愿被混乱打败的心气,是每一个深夜仍愿点灯前行的人。”

转载请注明来自https://oklife.me。

文尾配图水墨画图片