OpenClaw 性能问题深度剖析:慢的真相

OpenClaw 性能问题深度剖析:慢的真相

先把丑话说在前面

说真的,OpenClaw 的”慢”不是玄学,也不是你家网络抽风。翻一圈活跃的 GitHub Issues 就能发现,截至 2026.5.18 这个版本,至少挂着三个 P1/P2 级别的性能缺陷:内存泄漏、事件循环饥饿、以及会话抢占导致的 Telegram 静默超时。它们不是边缘场景才会触发的边角料,而是只要你日常在用,就几乎一定会撞上的生产级 Bug。

OpenClaw

说白了,这不是偶发,这是设计层面的硬伤。下面我把一条一条掰开讲。

一、Active Memory 预检超时:Telegram 回复要等 90 秒的元凶

1. 问题本质

Active Memory 插件在每次 Agent 回复之前,会先跑一轮 preflight 查询,去记忆库里捞上下文。问题在于:这套查询是同步阻塞的——一旦查询超时、或者命中失败,整个 Telegram 会话就会卡在那儿,直到超时阈值(默认约 90 秒)耗尽才会放弃,然后才把”不好意思我卡了”这句话吐出来。

这个 90 秒并不是一个用户感知良好的”重试时间”,而是一个”用户早就关掉对话框”的时间。换句话说,Active Memory preflight 的设计,本质上把一个本该是辅助功能的记忆检索,强行塞进了主回复的关键路径上。

2. 实测数据(来自用户 brokemac79 在 2026.5.18 版本的完整运行日志)


入站时间: 20:25:15.970
Active Memory 开始: 20:25:23.381

从入站到 Active Memory 真正开始跑 preflight,间隔就接近 7.4 秒。而这还只是”开始”,不是”结束”。完整的 preflight 加上后续阻塞,用户在 Telegram 这边感受到的,是长达数十秒到一分半钟的”打字中…”假象,严重的就直接断连。

为什么这条日志特别有说服力?因为它精确到了毫秒级。这不是某个用户的体感抱怨,而是可复现、可对照的时间戳证据——你拿任何一台同版本部署的机器跑一遍,大概率能复现几乎一样的间隔曲线。

3. 根因拆解

把这条链路拆开看,至少有三点设计层面的锅:

  • 同步阻塞架构:preflight 没跑完,主回复逻辑就不会启动。哪怕用户的问题根本不需要历史记忆,也得陪它一起等。
  • 超时阈值偏高:默认 90 秒的兜底,在 ChatOps 这种轻交互场景里几乎等于”无响应”。
  • 失败降级缺失:查询失败时没有快速降级路径,必须走完全部重试后才肯放手,浪费了大把用户耐心。

说穿了,这就是把”最好有”的功能,做成了”必须有”,而且没给失败留后路。

二、内存泄漏:跑得越久,吃得越多

1. 现象

这是三个 P1/P2 缺陷里最”慢性”的一个:单个会话看不出什么,但 OpenClaw 在长时运行(比如挂机一整夜做定时任务)后,RSS 内存会稳步上涨,直到被 OOM Killer 抬走,或者把 swap 啃光之后出现肉眼可见的卡顿。

2. 根因方向

从社区反馈和 issue 描述看,泄漏点大概率集中在两处:

  • 会话上下文缓存未设上限:每轮对话的中间结果(包括未提交的 function call payload、partial tool output)都被无脑塞进内存字典,键清理逻辑只在显式调用 `reset_context()` 时才触发,普通用户根本不会主动调。
  • 事件订阅者没解绑:部分插件在热加载或重连时会重复注册 listener,但退订路径写漏了,导致每个实例都挂着一份回调引用,越攒越多。

3. 为什么这是 P1

内存泄漏在桌面端还能靠重启糊弄一下,但在 7×24 跑 Telegram Bot、或者作为后台 Agent 服务的场景里,一次 OOM 就意味着线上不可用。所以社区把它标成 P1 并不冤。

三、事件循环饥饿:CPU 飙满,回复反而发不出去

1. 现象

CPU 占用莫名其妙拉到 100%,但 Telegram 那边既不报错、也不掉线,就那么沉默着。这个状态可以持续几十秒到几分钟,直到某个长任务跑完,积压的回复才一口气全发出来——用户视角看就是”突然活了”。

2. 根因方向

典型的事件循环饥饿,常见于以下几种组合:

  • 同步阻塞的 LLM 流式请求:理论上应该用 stream + async iterator 一点点吐 token,但部分 provider 包装层回退成了同步 `requests` 调用,整段 await 卡住事件循环。
  • 日志/埋点的同步 IO:高频调试日志走的是 `file.write()` 而不是 `aiofiles` 或队列化的 logger,每次写盘都把主线程拽一下。
  • Active Memory 的二次叠加:上面说的 preflight 查询如果恰好撞上一个慢任务,事件循环就彻底死了。

社区在 issue 里把它标成 P2,但说实话,在生产环境它造成的实际伤害不输 P1——”看上去活着,实际死了”是最难排查的状态。

四、会话抢占:Telegram 的”静默超时”是怎么来的

1. 现象

用户在 Telegram 发了消息,OpenClaw 那边也”收到”了,但用户最终等不到任何回复。过几分钟再发,发现上一条根本没被处理,而是被新消息”挤”掉了。

2. 根因方向

这个跟 OpenClaw 的会话管理模型有关:当同一个 chat_id 短时间内连续收到多条消息时,当前正在处理的消息会被新消息的入队动作打断或丢弃。具体表现取决于用的是 polling 还是 webhook 模式:

  • polling 模式:长 offset 跳号,旧消息的 task 还没跑完就被新的覆盖。
  • webhook 模式:Telegram 那边重发机制触发,导致同一个 update_id 被并发处理两次,后一次直接覆盖前一次的 reply context。

社区里有人调侃说这是”薛定谔的 Bot”——你不看聊天记录,永远不知道它到底回没回。

3. 为什么是系统性问题

它和前两个缺陷不是孤立的:内存泄漏让会话状态越来越脏,事件循环饥饿让处理越来越慢,会话抢占了再补一刀——三者在长跑场景下会形成正反馈循环。这也是为什么我说”这不是偶发”:单看任何一个都不致命,但叠在一起就是系统性翻车。

五、这到底是 Bug 还是 Feature?老实讲,是设计取舍翻车

很多开发者在 issue 里吵架的点在于:Active Memory 同步阻塞、事件循环里跑同步 IO、会话无锁抢占——这三件事单独拿出来,都有人能说出”为啥这么设计”的合理理由(比如”为了简化首次部署的体验”)。

但问题在于,它们同时存在于一个被打包成”开箱即用”的发行版里,而且没有任何高级配置项可以让用户绕过。普通用户拿到手就是这套默认行为,连一个开关都没有。

这才是我说”设计层缺陷”的意思:不是写错了一行代码,而是从上层的”必须用 Active Memory”、到中层的”preflight 必须同步跑”、到底层的”LLM 调用可以用同步库”,整条链路都没给”快速失败”留位置。任何一个环节卡住,用户体验就崩。

六、能怎么办?亲测可用的几条规避方案

在官方给出真正修复之前,我自己在用、或者社区里验证过有效的几条路:

方案 1:关掉 Active Memory preflight(最直接)

如果你不是重度依赖长期记忆,这是最快能见效的改动。配置文件里把 `active_memory.preflight_on_reply` 设为 `false`,preflight 那段阻塞就彻底没了。代价是 Agent 不会主动捞历史记忆,需要你在 prompt 里手动提醒它读上下文。

适合场景:日常问答、轻量任务、对话间隔短的 ChatOps。

方案 2:降级到 2026.4.x 版本

2026.4 之前的最后一个稳定版,会话抢占和事件循环饥饿的 issue 都还没这么集中爆发。降级前记得备份 `~/.openclaw/` 下的会话存档,否则历史记忆会丢。

适合场景:生产环境稳定性优先、不追求新功能。

方案 3:自己包一层异步 Wrapper

如果你用的是自定义 LLM provider 接入点,可以在调用层外面套一个 `asyncio.to_thread()`,至少能把同步 IO 从主事件循环里挪出去。改完一次,所有调用点都受益。

适合场景:有一定动手能力的开发者、用自定义 provider 的团队。

方案 4:用独立的 Bot 实例隔离长任务

会话抢占的本质是单实例状态污染。如果你有大量定时任务在跑,建议拆一个”定时任务 Bot”出来,跟主交互 Bot 物理隔离。哪怕主 Bot 卡死,定时任务那侧也不受影响。

适合场景:把 OpenClaw 当 Agent 平台在用,不只是聊天机器人。

七、关于”等官方修复”的现状

截至 2026 年 8 月,官方仓库对这三个 issue 的处理节奏大致是:

  • 内存泄漏:已有 PR 在 review,但合并时间未定。社区里有人提了一个基于 LRU 的会话缓存方案,反馈比较正面。
  • 事件循环饥饿:维护者承认是已知问题,但倾向于”通过插件层异步化”来解,而不是改核心。
  • 会话抢占:争议最大的一派认为是”用户应该自己用 queue”,另一派坚持核心该有锁。目前没有明确修复时间表。

我的建议是:别干等。上面四条规避方案至少能保住 80% 的日常使用体验,等官方修完再迁回去也不迟。

八、常见问题(FAQ)

Q1:关掉 Active Memory preflight 会不会影响 Agent 的长期记忆能力?

会,但没你想的那么大。Active Memory preflight 的作用是”自动判断要不要去翻历史”,关掉之后你需要自己在 prompt 里加一句”如果有相关历史请先读取 memory/”,效果差距在轻量场景下几乎不可感知。

Q2:事件循环饥饿和 LLM provider 有关吗?

部分有关。社区反馈里 OpenAI 兼容接口触发饥饿的概率明显高于原生 Anthropic 接口,疑似是 SDK 的流式实现差异。但本地模型(比如 Ollama 这类)在长上下文下也会触发,所以根因更可能是 OpenClaw 这边的调用层而不是 provider 本身。

Q3:降级到 2026.4 之后,新功能还能用吗?

不能用。2026.5 系列新增的若干插件和配置项在 2026.4 上是不存在的。如果你重度依赖某个新功能,建议走”双版本并存”的路子:用 2026.4 跑生产 Bot,用 2026.5.18 跑测试 Bot 跟进 issue 进展。

Q4:怎么判断自己是不是踩到了内存泄漏?

最简单的办法是连续运行 24 小时,看 RSS 是否单调上涨。一个简单的判断脚本:


ps -o rss= -p $(pgrep -f openclaw) | awk '{sum+=$1} END {print sum/1024 " MB"}'

如果数字 24 小时后比启动时高出几百 MB 甚至上 GB,基本可以确认是泄漏。

Q5:Telegram 那边显示”消息已读但无回复”,一定是这个 Bug 吗?

不一定。也有可能是 Telegram 的 read receipt 和 OpenClaw 的实际处理状态不同步。建议在 OpenClaw 端打开 debug log,对照入站时间戳确认消息是否真的进了处理队列。

Q6:有没有人做过头部项目(fork)专门修这几个问题?

有,2026 年中开始社区出现了 2-3 个活跃 fork,主打”async-first”和”memory 可选化”。但项目维护者的迁移成本不低,建议先观望,等其中一个明显跑出来再切。

写在最后

OpenClaw 不是一个”烂项目”,恰恰相反,它在 2026 年的 Agent 框架里属于生态比较完整、文档也比较像样的那一档。但也正因为它被用得多了,这三个 P1/P2 缺陷才显得格外刺眼——它们影响的不是 demo,是真金白银的生产环境。

我的态度是:遇到问题别死磕默认配置,先用上面的四条规避方案稳住线上,然后持续跟 issue 进展。等官方把核心异步化和会话锁这两件事做扎实了,再把开关一个个切回去也不迟。

如果你也在 2026.5.18 上踩过坑,欢迎在评论区贴你的日志(记得打码 chat_id),大家一起对照时间戳排查,会比单干快得多。

版本核验说明:本文基于 2026 年 8 月时点的 OpenClaw 公开 issue 与社区反馈撰写,核心证据链(brokemac79 的运行日志、三大 P1/P2 缺陷的根因分析)来自 2026.5.18 版本。后续版本若官方修复了对应 issue,欢迎在评论区指正,我会据此更新对应章节的描述。

OpenClaw 性能问题深度剖析:慢的真相

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

Scroll to top