1.4G 会话导致 OpenClaw 回复慢被 sessions.list 卡住
OpenClaw Gateway 健康、模型完成、回复已落盘,Chat 页却死活不显示。一路追下来,问题不是单一故障,而是 Control UI 重连 → 全量 sessions.list → transcript usage fallback → event loop 阻塞 → WebSocket 掉线的慢路径。

我是 AI灵感闪现,致力于让 AI (OpenClaw/小龙虾 和 Claude Code/CC) 全面自主接管我的健康、投资、学习、工作与生活,把节省下来的时间,用于真正体验人生。我只给 AI 想法或目标,全程不陪跑,让 AI 自主运行类似 Tesla FSD 自动驾驶。已上架两款由 AI 自主开发的 App:MoneyMind 省钱思维、HeartPetBond 心宠纽带。健康、投资、学习、工作和生活的 AI 接管路径,正在持续推进,并分享实践在微信公众号 AI灵感闪现 和 网站
https://www.vibesparking.com
0. 引子
Gateway 健康,模型完成,assistant 回复已经写进 transcript。 但 Chat 页死活不显示新消息。
这是一次很典型的「不是模型问题、不是进程问题」的故障。最后追到根上是一条慢路径:Control UI 重连 → 全量 sessions.list → 后端 transcript usage fallback → event loop 阻塞 → WebSocket 心跳超时。
记录如下,给同样跑 OpenClaw Gateway、又恰好被同一条路径绊住的同行参考。
-
日期:2026-05-04 -
环境:macOS,OpenClaw 2026.5.2,Gateway 端口<gateway_port> -
目标:排查并缓解 openclaw-gateway卡住、Control UI 无响应、聊天回复已写入 transcript 但前端未及时显示的问题
1. 现象
用户在 Control UI 访问 Chat 页:
http://localhost:<gateway_port>/chat?session=agent%3Amain%3A<session>
发送 hi 后,页面没有及时显示回复。与此同时,Gateway 日志中出现:
-
sessions.list存在 19s、23s、26s 级慢请求 -
chat.history出现 11s 延迟 -
WebSocket 中途断开并重连,断开码包括 1001、1006 -
liveness diagnostic 报告 event loop delay / utilization 异常
关键日志特征:
sessions.list 19405mssessions.list 19190mssessions.list 18232mssessions.list 26762mssessions.list 23456mschat.history 11262mswebchat disconnected code=1001webchat disconnected code=1006liveness warning: reasons=event_loop_delay,event_loop_utilization,cpu
2. 启动方式确认
最初怀疑 Gateway 不是通过 LaunchAgent 启动。排查后确认当前实际是通过用户级 LaunchAgent 启动:
plist: ~/Library/LaunchAgents/ai.openclaw.gateway.plistlabel: ai.ocplatform.gatewaycommand: /opt/homebrew/bin/node \ /opt/homebrew/lib/node_modules/openclaw/dist/index.js gateway \ --port <gateway_port>
重启方式:
launchctl kickstart -k gui/501/ai.openclaw.gateway
健康检查:
curl http://localhost:<gateway_port>/health
结果:Gateway 能启动并通过 /health,问题不是单纯的进程未运行,而是运行期间 event loop 被慢请求和文件 I/O 挤压。
经验:看到「Gateway 卡」第一反应是不是要重启进程,但
/health通过的时候,重启基本无效。要换一个角度看 event loop 和慢请求。
3. 已执行的修复动作
3.1 关闭高噪音 cron job
修改文件:
~/.openclaw/cron/jobs.json
禁用了多个会定期触发 agent / audit / build / sync 的任务,包括:
-
daily-session-workspace-audit -
skills-security-audit -
Memory Dreaming Promotion -
astro-blog-daily-build -
claude-code-changelog-watch -
openclaw-changelog-watch -
gbrain-live-sync -
gbrain-dream-cycle
目的:减少 Gateway 后台任务对 CPU、session store、transcript 文件和 WebSocket 的竞争。
3.2 移除不可用 MCP 配置
修改文件:
~/.openclaw/openclaw.json
将不可用的 MCP openchronicle 移除,当前设置为:
"mcp":{"servers":{}}
目的:避免启动和运行期间不断尝试加载不可用 MCP,减少错误噪音和初始化成本。
3.3 增加 session maintenance 配置
在 ~/.openclaw/openclaw.json 中加入:
"session":{"dmScope":"per-channel-peer","maintenance":{"mode":"warn","pruneAfter":"90d","maxEntries":80,"maxDiskBytes":"200mb","highWaterBytes":"150mb"}}
目的:让 OpenClaw 对 session store 膨胀发出警告,并为后续 cleanup 提供上限策略。
3.4 先备份再清理 session 数据
按用户要求,先备份目录,再执行清理。
备份目录:
~/.openclaw/backups/session-cleanup-20260504-0859/agents
备份大小约:
1.4G
执行清理命令:
/opt/homebrew/bin/openclaw sessions cleanup --all-agents --enforce --json
清理结果摘要:
-
vs-openclaw-mgr删除 1904 个未引用 session 文件 -
释放空间约 453,080,258bytes -
vs-sites-astrosession store 从 139 条裁剪到 80 条 -
~/.openclaw/agents从约1.4G降到约941M
清理后重启 Gateway。
4. 用户测试会话排查
用户测试 session:
agent:main:<session>
实际 session id:
44ce243a-e9eb-4331-8a22-290f375836ec
transcript 文件:
~/.openclaw/agents/main/sessions/44ce243a-e9eb-4331-8a22-290f375836ec.jsonl
检查结果:
-
用户消息 hi已写入 transcript,时间约2026-05-04 09:01:39 +08:00 -
assistant 回复也已写入 transcript,时间约 2026-05-04 09:01:46 +08:00 -
runtime 日志显示 run_completed,没有模型调用失败 -
session store 状态已变为 done,并写入endedAt
结论:模型和 agent run 本身完成了。前端没显示不是「没有生成回复」,而是 Gateway/WebSocket/Control UI 的刷新链路在慢请求期间断开或延迟。
5. 关键根因
5.1 Control UI 在 Chat 页面触发昂贵的 sessions.list
排查安装包中的 Control UI bundle:
/opt/homebrew/lib/node_modules/openclaw/dist/control-ui/assets/index-<hash>.js
发现 Chat 页面和重连路径多次调用:
activeMinutes: 0,limit: 0,includeGlobal: true,includeUnknown: true
而前端请求组装函数会把 activeMinutes:0 和 limit:0 省略掉,最终后端收到的是:
{includeGlobal: true,includeUnknown: true}
这会变成无时间限制、无数量限制的 session 列表请求,并跨 agent 扫描 session store。
5.2 后端 sessions.list 会触发 session store 和 transcript 文件读取
排查后端实现:
/opt/homebrew/lib/node_modules/openclaw/dist/server-methods-<hash>.js/opt/homebrew/lib/node_modules/openclaw/dist/session-utils-<hash>.js
相关实现:
-
sessions.list调用listSessionsFromStoreAsync -
listSessionsFromStoreAsync虽然会分批 yield,避免一次性完全卡死 event loop -
但它仍然需要扫描 session store -
构建 session row 时,如果缺少 token / cost / context 字段,会读 transcript 做 usage fallback -
对派生标题和 last-message preview,也可能读取 transcript
代码注释本身也指出,readSessionTitleFieldsFromTranscript 的同步文件 I/O 是主要阻塞来源。
5.3 多个 WebSocket 连接放大了问题
日志中同时出现多个连接 ID 发起 sessions.list、node.list、chat.history:
conn=<conn-id-1>conn=<conn-id-2>conn=<conn-id-3>
这说明浏览器可能存在多个 Control UI tab,或重连过程中重复触发初始化请求。多个连接同时刷新,会把 session store 扫描、node list、chat history 叠加在一起。
5.4 大 MEMORY.md 和 cleanup timeout 是次要因素
日志中还有:
workspace bootstrap file MEMORY.md is 21493 chars (limit 12000); truncatingagent cleanup timed out: step=pi-trajectory-flush timeoutMs=10000
影响:
-
MEMORY.md过大导致 agent bootstrap 成本高,本次 run 的 bootstrap-context 约 7.2s -
pi-trajectory-flushcleanup timeout 发生在回复之后,会影响最终收尾和状态传播
但这两个不是 sessions.list 19s/26s 的主因。主因仍是 Control UI 的 chat 刷新路径触发昂贵 session 列表请求。
6. 当前状态
已经完成:
-
Gateway 由 LaunchAgent 管理,能正常启动 -
多个高噪音 cron 已禁用 -
不可用 MCP 已移除 -
session maintenance 配置已加入 -
session 数据已备份并清理 -
用户测试消息的 assistant 回复确认已写入 transcript -
Gateway 清理后 CPU 下降到低水平, sessions.list多数降到约 600ms ~ 1.1s,但冷启动 / 重连阶段仍可出现 20s 级慢请求
尚未完成:
-
尚未修改 /opt/homebrew下的 Control UI 安装包 -
曾准备备份并 patch index-<hash>.js,但用户中断了该步骤,因此没有继续写入全局安装目录
7. 建议的最终修复
7.1 前端 Chat 页面不要做全量 sessions.list
应将 Chat 页面和 WebSocket 重连路径中的 session 刷新参数从:
{activeMinutes: 0,limit: 0,includeGlobal: true,includeUnknown: true}
改成类似:
{agentId: currentAgentId,activeMinutes: 120,limit: 20,includeGlobal: false,includeUnknown: false}
目的:
-
只查当前 agent 的近期会话 -
避免聊天页为了显示当前对话而跨所有 agent 扫 session store -
减少 WebSocket reconnect 时的初始化负载
7.2 前端请求组装函数要支持 agentId
当前 _u() / vu() 请求组装逻辑只传:
includeGlobalincludeUnknownactiveMinuteslimit
建议补上:
if (n?.agentId) c.agentId = n.agentId;
否则即使调用方传了 agentId,后端也收不到。
7.3 后端应避免 sessions.list 读取 transcript usage fallback
建议后端将 sessions.list 的 transcript usage fallback 改成惰性或可选:
-
列表页默认只返回 store 中已有 metadata -
缺失 token / cost 字段时不在列表请求里读 transcript -
需要详情时再用 sessions.describe或单独 endpoint 补充
这是更彻底的上游修复。
7.4 运营侧建议
短期规避:
-
只保留一个 Control UI tab -
修复期间避免打开 Sessions / Usage 等会触发大量列表刷新或统计的页面 -
如果页面没有显示回复,先刷新 Chat 页面;因为 transcript 里很可能已经有回复
中期配置:
-
将 session maintenance 从 warn改为enforce,防止 session store 再次膨胀 -
定期执行 openclaw sessions cleanup --all-agents --enforce -
缩短或拆分过大的 MEMORY.md,降低 agent bootstrap 成本
8. 回滚信息
session 数据备份:
~/.openclaw/backups/session-cleanup-20260504-0859/agents
如果后续对 Control UI asset 打补丁,应先备份:
/opt/homebrew/lib/node_modules/openclaw/dist/control-ui/assets/index-<hash>.js
建议备份名:
index-<hash>.js.bak-chat-sessions-scope-20260504
注意:/opt/homebrew/lib/node_modules/openclaw 是全局 npm 安装目录,OpenClaw 升级后本地补丁可能被覆盖。
9. 总结
本次问题不是单一的 LaunchAgent 或模型失败。实际链路是:
-
Control UI Chat 页面和重连逻辑反复触发昂贵的 sessions.list -
sessions.list在当前实现下会扫描 session store,并可能读取 transcript -
清理前 session 数据量和历史锁竞争已经很重,导致 event loop 被长时间占用 -
event loop 被占用后,WebSocket 心跳和 chat.history响应延迟 -
assistant 回复已经写入 transcript,但前端连接断开或刷新延迟,因此用户看不到及时显示
已经通过关闭噪音任务、移除失效 MCP、配置 maintenance、备份并清理 session 数据显著降低压力。剩余的根治点是修改 Control UI chat 路径,避免聊天页面进行跨 agent、无时间限制、无数量限制的 session 列表刷新。
工程师的口头禅有时挺准:「能跑就行」,但「能跑」不等于「跑得起」——尤其当 event loop 是单线程、transcript 是 .jsonl、还掺着同步 I/O 的时候。下一次看到 Chat 页不显示新消息,不要先怀疑模型,先去翻 sessions.list 的耗时分布。

加入 AI灵感闪现 微信群
长按下图二维码进入 AI灵感闪现 微信群

长按下图二维码添加微信好友 VibeSparking 加群

关注 AI灵感闪现 微信公众号

夜雨聆风