
1. 长期养虾的会话为什么会越跑越卡如果你用 OpenClaw 跑一个长期在线的 Agent比如客服虾、日报虾、群管理虾跑上几天大概率会遇到两个现象一是响应越来越慢二是某天突然报上下文超限。这不是模型变笨了而是会话文件在悄悄膨胀。OpenClaw 的会话管理Session Management核心就两件事把每轮对话可靠地落盘以及在 Token 逼近上下文窗口时做 Compaction压缩。落盘用的是 JSONL压缩靠的是阈值触发的摘要或裁剪策略。理解这两块你才能让一只虾连续养几个月不崩。这篇聚焦三样东西JSONL 会话文件的字段结构、Compaction 的配置骨架、以及怎么验证压缩真的生效了。适合已经在跑 OpenClaw、想让 Agent 长期稳定运行的人。下面所有配置我都用config.toml风格给出你可以直接抄进自己的项目改参数。2. 前置把模型接入层配好再谈会话会话压缩本身要调用 LLM 生成摘要所以你得先有一个稳定的模型接入层。我这边习惯用 TaoToken 做统一入口它的 API 地址是https://taotoken.net/api兼容 OpenAI 风格的调用方式OpenClaw 里配置 base_url 和 key 就能接上。先去控制台拿一个 API Key地址在https://taotoken.net/console/api-keys。拿到之后在 OpenClaw 的模型配置里填上[model] provider openai-compatible base_url https://taotoken.net/api api_key sk-你的key default_model gpt-4o-mini这里default_model是主对话模型压缩摘要可以单独指定一个更便宜的模型后面 Compaction 配置里会用到。如果你还没决定用哪个模型跑摘要可以先去模型对话页面试几轮确认输出质量再定https://taotoken.net/models。接入文档在https://taotoken.net/doc里面有完整的参数说明和错误码对照配 base_url 报 404 的时候翻一下能省不少时间。3. 可复制的 config.toml 会话与压缩骨架OpenClaw 的会话配置分三块存储路径、Compaction 策略、维护调度。下面这份骨架我按长期运行场景调过你可以整段复制再改数值。[session] # 会话数据根目录 data_dir ./data/sessions # 单会话最大消息数超过后强制触发压缩检查 max_messages 200 [session.compaction] enabled true # 触发阈值单位 token接近上下文窗口的 70% 比较稳 threshold 4000 # 压缩策略summary / sliding / selective strategy summary # 保留最近 N 轮不参与压缩 preserve_last_n 10 # 生成摘要用的模型建议用便宜的小模型 summary_model gpt-4o-mini # 摘要最大输出 token summary_max_tokens 512 [session.maintenance] # 空闲超过 30 天的会话自动归档 max_idle_days 30 # 每天凌晨 3 点跑维护任务 schedule 0 3 * * * [session.maintenance.rotation] enabled true max_file_size 10MB compress_on_archive true [session.storage] max_total_size 10GB alert_threshold 0.8三种策略怎么选我列个对照策略行为适合场景summary用 LLM 把早期对话总结成摘要通用客服、陪伴类sliding滑动窗口直接丢弃最早的消息低成本、上下文不重要selective保留关键消息压缩其余任务导向、有明确目标threshold这个值别设太满。上下文窗口如果是 8k你设 7000 触发留给摘要生成和下一轮输入的空间就不够了。我一般按窗口的 60% 到 70% 来设。4. JSONL 会话文件字段逐个说清OpenClaw 每个会话在data/sessions/{agentName}/{userId}/下有三个文件session.json存元数据transcript.jsonl存对话转录compaction.json存压缩记录。重点看 JSONL因为它是你排查问题的第一现场。transcript.jsonl每行一条消息是标准 JSON Lines 格式。一条普通对话长这样{role:user,content:帮我查下订单 ORD-20260301-001,ts:2026-03-01T10:00:05Z} {role:assistant,content:正在为你查询,ts:2026-03-01T10:00:06Z,tokens:{in:1200,out:15}}工具调用会多两个角色{role:tool_call,name:order_query,params:{orderId:ORD-20260301-001},ts:2026-03-01T10:00:16Z} {role:tool_result,name:order_query,result:{status:shipped},ts:2026-03-01T10:00:17Z}字段含义我整理成表字段类型说明rolestringsystem / user / assistant / tool_call / tool_resultcontentstring消息正文工具类消息可能为空tsstringISO8601 时间戳tokensobject该条消息的输入输出 token 数仅 assistant 有namestring工具名仅工具类消息有params / resultobject工具入参和返回JSONL 的好处是流式追加写入某一行写坏了不影响其他行逐行读取也方便你做离线分析。压缩发生后早期消息会被替换成一条role: summary的记录你 grep 一下就能看到压缩点grep role:summary data/sessions/main/user-456/transcript.jsonl5. 验证 Compaction 是否真的触发配好了不代表生效了得实测。我一般分三步验证。第一步看压缩计数。session.json里有compactionCount字段跑几轮长对话后读一下cat data/sessions/main/user-456/session.json | python -m json.tool如果compactionCount从 0 变成 1、2说明压缩触发过。同时看tokenCount压缩后它应该明显回落。第二步看转录文件里的摘要记录。上面那条 grep 命令能直接定位。正常输出类似{role:summary,content:用户此前咨询订单 ORD-20260301-001 的物流状态已告知已发货。,ts:2026-03-05T14:30:00Z,covers:[msg-1,msg-2,msg-3]}covers字段列出被这条摘要替换掉的消息 id对照一下是不是早期那批。第三步发一条依赖早期上下文的请求看 Agent 还记不记得。比如前面聊过订单号压缩后直接问「刚才那个订单到哪了」如果它还能答出订单号说明摘要保留了关键信息压缩是有效的。想更直观地看 token 变化可以开调试日志OPENCLAW_LOGdebug openclaw run --agent main日志里会打印compaction triggered: tokens 4120 threshold 4000这类信息触发时机一目了然。6. 本篇常见错排查压缩不触发先确认enabled true再看threshold是不是设得比实际 token 还高。有人把 threshold 设成 8000但模型窗口只有 8k永远等不到触发就报错了。把 threshold 降到窗口的 60% 左右。摘要模型报错summary_model如果填了一个没接入的模型名压缩会静默失败compactionCount一直不动。检查模型接入层配置确认这个模型在https://taotoken.net/models里能正常对话。JSONL 某行解析失败多半是写入过程中进程被 kill最后一行不完整。OpenClaw 读取时会跳过坏行但你可以手动检查while read -r line; do echo $line | python -m json.tool /dev/null || echo 坏行: $line; done transcript.jsonl压缩后 Agent 失忆preserve_last_n设太小或者 summary 策略把关键信息压没了。把preserve_last_n调到 15 到 20或者改用 selective 策略保留关键消息。存储涨得比预期快检查 rotation 有没有开max_file_size到了会不会归档。归档前建议先导出备份永久删除不可恢复openclaw session export --user user-456 --format json如果你在接入层遇到 base_url 或鉴权问题直接翻接入文档https://taotoken.net/doc错误码都有对照。长期跑编码类 Agent 的话可以考虑 Coding Plan压缩和会话这块的默认参数针对长任务调过省得自己一项项试https://taotoken.net/coding-plan。