OpenClaw Session自动清理优化指南
摘要
长上下文问题根源解析 某次运维中,AI 助手的响应速度骤然下跌——一个简单查询从发出
长上下文问题根源解析
某次运维中,AI 助手的响应速度骤然下跌——一个简单查询从发出到返回结果,耗时长达 86 秒。
排查日志后发现真凶:上下文长度 122k tokens。
这暴露了 AI Agent 部署中的经典陷阱:每次对话都被完整追加到 transcript 文件。日积月累,文件膨胀失控,模型推理时被迫加载整段历史到上下文窗口,响应延迟随之暴增。
这就是 长上下文问题(Long Context Problem),也是 AI Agent 生产环境中极易被忽视的性能瓶颈。没有人能忍受一分半钟的等待,但许多人正默默承受这种体验降级。

理清 Session 与 Transcript 的关联
在 OpenClaw 等 AI Agent 框架中,session 管理分为两层结构:
sessions.json (索引层)
├── agent:main:feishu-xxx → sessionFile: /path/to/transcript-abc.json
├── agent:main:feishu-yyy → sessionFile: /path/to/transcript-def.json
└── agent:main:main → sessionFile: /path/to/transcript-main.json
- sessions.json — 轻量级索引文件,记录各 session 的元数据,例如创建时间、最后更新时刻、对应文件路径等
- transcript 文件 — 实际存储完整对话历史的 JSON 文件。每条消息、每次工具调用、每个 token 均被完整记录
关键点在于:这两个文件彼此独立。
若仅删除 sessions.json 中的 key(相当于只移除索引),却不删除对应的 transcript 文件(数据),后果如下:
- 下次启动时,框架找不到该 session 的索引,认为它不存在,进而新建一个 session
- 旧 transcript 文件仍残留在磁盘上,永远不会被自动清理
- 长期积累导致磁盘空间被大量“孤儿文件”逐步侵蚀
因此,清理操作必须同时处理 key 和 file,两者缺一不可。这一点极易被忽略,但后果切实存在。
解决方案:自动化清理脚本
明确问题后,解法随之清晰。可采用 Bash + Node.js 混合脚本实现:
#!/usr/bin/env bash # 清理 Feishu session + Main session 脚本 set -e SESSIONS_FILE="/home/water/.openclaw/agents/main/sessions/sessions.json" THRESHOLD_MS=$((24 * 60 * 60 * 1000)) # 24 小时阈值
核心逻辑(Node.js 内嵌)
const data = JSON.parse(fs.readFileSync(SESSIONS_FILE, 'utf8'));
const now = Date.now();
Object.keys(data).forEach(k => {
if (!k.includes('feishu')) return; // 仅处理 feishu sessions
if (k.includes('cron')) return; // 跳过 cron sessions
const session = data[k];
const updatedAt = session.updatedAt || session.createdAt || 0;
const age = now - updatedAt;
if (age > threshold) {
// ① 先删文件
const sessionFile = session.sessionFile;
if (sessionFile && fs.existsSync(sessionFile)) {
fs.unlinkSync(sessionFile);
}
// ② 再删索引
delete data[k];
deleted++;
}
});
// 写回索引文件
fs.writeFileSync(SESSIONS_FILE, JSON.stringify(data, null, 2));
操作顺序需特别注意:先删文件,再删索引。 若顺序颠倒,删完索引后进程突然崩溃,该文件将永久成为孤儿,再也无人知晓其存在。
特殊处理:Main Session 每日强制重置
除 Feishu session 外,还需对 main session 执行无条件每日清理:
const mainKey = 'agent:main:main';
if (data[mainKey]) {
const sessionFile = data[mainKey].sessionFile;
if (sessionFile && fs.existsSync(sessionFile)) {
fs.unlinkSync(sessionFile);
}
delete data[mainKey];
}
此处不判断年龄,直接删除。理由充分:
- Main session 是日常对话的主 session,积累速度最快
- 每天重置一次,上下文始终保持干净,推理速度稳定
- 真正重要的信息通过
MEMORY.md持久化,不依赖对话历史
重启 Gateway
清理 sessions.json 后,需重启 Gateway 使变更生效:
pkill -f openclaw-gateway || true sleep 2 nohup openclaw-gateway >> "$LOG_FILE" 2>&1 & sleep 3
其中 || true 是细节处理,避免 pkill 因找不到进程而返回非零退出码,触发 set -e 导致脚本意外终止。
自动化:配置 Cron Job
将脚本配置为每日定时执行,即可实现零人工干预:
{
"name": "Daily Feishu Session Cleanup",
"schedule": { "kind": "cron", "expr": "0 14 * * *", "tz": "Asia/Shanghai" },
"sessionTarget": "isolated",
"payload": {
"kind": "agentTurn",
"message": "Run the Feishu session cleanup script and report results",
"timeoutSeconds": 120
},
"delivery": { "mode": "announce", "channel": "feishu" }
}
设计要点:
sessionTarget: isolated— 在隔离 session 中执行,避免污染主 sessionkind: agentTurn— 让 Agent 执行脚本并汇总结果,通过 Feishu 推送通知- 选择每天 14:00 执行,属于下午低峰期,不影响正常使用
需注意一个坑点:sessionTarget: main 仅支持 payload.kind = systemEvent,即直接执行而不经过 LLM。若希望 LLM 汇报并推送通知,必须使用 isolated + agentTurn 组合。混用会导致超时或推送缺失,反馈体验极差。
效果对比
| 指标 | 清理前 | 清理后 |
|---|---|---|
| 上下文长度 | ~122k tokens | < 5k tokens |
| 平均响应时间 | 21-86 秒 | 3-8 秒 |
| 磁盘占用(sessions) | 持续增长 | 每日重置 |
响应时间从最差的 86 秒降至 3-8 秒,体验提升显著。一个简洁的清理脚本,带来日常使用的流畅感,投入回报清晰可见。
延伸思考:AI Agent 的“记忆管理”
该问题本质是 AI Agent 的工作记忆(Working Memory)与长期记忆(Long-term Memory)分离问题。
- 对话 session / transcript 相当于工作记忆,应保持短暂且聚焦
- MEMORY.md / 知识库 相当于长期记忆,用于存放关键决策与知识
许多人在部署 AI Agent 时,习惯要求它“记住一切”,结果将工作记忆误当作永久存储。上下文爆炸只是时间问题。
正确做法:
- 定期蒸馏——从对话中提取有价值信息,写入长期记忆
- 定期清理——工作记忆无需无限堆积,它仅是临时缓存
- 分层存储——工作 session、日志、知识库各司其职,互不干扰
这与人类记忆机制相似——你不需要记住每天说过的每一句话,但重要决策和习得的知识会自动沉淀。
总结
一个简单的 cron 清理脚本,解决了 AI Agent 最常见的性能退化问题。核心要点:
- 同时删 key 和 file,避免磁盘泄
来源:互联网
本网站新闻资讯均来自公开渠道,力求准确但不保证绝对无误,内容观点仅代表作者本人,与本站无关。若涉及侵权,请联系我们处理。本站保留对声明的修改权,最终解释权归本站所有。