乐于分享
好东西不私藏

升级 OpenClaw 后,CPU 飙到 95%,我用 AI 一层一层扒开了它

升级 OpenClaw 后,CPU 飙到 95%,我用 AI 一层一层扒开了它

升级一个版本,CPU 从 25% 飙到 95%,风扇狂转。回退,再升,又崩。四次升级三次回退,7 个 Bug,一整天没合眼。

这不是什么性能优化文章。这是一个关于「我不懂这些术语,但 AI 懂」的对话实录。

我的 OpenClaw 系统跑在 4.21 版本上,一切正常。六个 Agent,六个飞书机器人,飞书插件,cron 备份,整套流水线每天稳定运行2个月。

然后我升了级。

风扇立刻开始咆哮。CPU 监控从 60% 直接蹿到 95%,而且不回落。Gateway 无响应,npm 在那里疯狂循环安装。整个系统像被什么东西卡住了脖子,喘不过气。

我当时的第一反应,已经回退多次,怕不只是 OpenClaw 的 bug 那么简单,打开 Claude Code 让他来修!

回退到 4.23,好了。再升到 5.3-1,又崩。再回退,再升 5.4,终于稳了。

四次升级三次回退,中间修了 7 个 Bug。sessions.list 从 150 秒优化到 3 秒,statx 调用从四万五千次降到零,CPU 从 60-95% 稳定在 25%。

但你如果只看结果,会觉得这就是个普通的性能优化故事。

实际上不是。真正有意思的是我怎么找到这些 Bug 的。

或者说,是 Claude Code 帮我找到的。

这块我想多聊两句。

我不懂 strace,但 Claude Code 懂

回退到稳定版本之后,我没有急着再升。我打开了 Claude Code,说了第一句话。

「升级之后 CPU 95% 不回落,帮我看看怎么回事。」

就这么一句。我没说什么系统调用,没说什么进程分析,我甚至不知道从哪开始查。但 Claude Code 知道。

它先跑了一个 ps aux,甩给我结果。node 进程,95%。

好,排除了「是系统整体问题」这个假设。就是 OpenClaw 自己在疯狂运行。

但它为什么在运行。在算什么,还是在读写什么。

我也不懂。但 Claude Code 懂。

它跑了一个叫 strace 的命令。我不太清楚这玩意具体是干嘛的,Claude Code 跟我解释,就是看进程在干嘛的,它在发什么系统调用,每次调用花了多长时间。

跑了几秒,统计结果出来我愣了一下。

绝大部分系统调用是 statx。不是网络请求,不是内存分配,是 statx。

Claude Code 告诉我,statx 就是查文件元数据的。每次打开一个文件之前,系统要先查一下这个文件存不存在、权限对不对。一个网关服务,应该在做网络通信和消息处理,不是在疯狂扫文件系统。

这就离谱了。

但我没全信它。我跟 Claude Code 说,先别急着下结论,你去 GitHub 上看看 OpenClaw 的 issue 区,核对一下到底是系统自身的 bug,还是我自己系统的特例问题。它跑了一圈回来说,issue 区确实有人在反馈升级后 CPU 飙升,但大多是 systemd service 路径锁死的问题,没人提过 statx 循环扫描。那说明这是我们自己的情况。

但 strace 只告诉了我调用类型,没告诉我路径。我告诉了 Claude Code 这个信息,它自己加了参数,带上时间戳和耗时重新跑。

结果让我倒吸一口凉气。

它在扫 plugins 目录。不是扫一次,是循环扫。97 个扩展目录,一个一个查,然后下一个循环,再一个一个查。永动机。

到这里根因已经浮出水面了。plugins.allow 配置文件里残留了一些已经删除的扩展路径,系统发现找不到,就触发 fallback discovery 机制,重新开始扫描。扫描完还是找不到,又触发 fallback。无限循环。

四万五千次 statx 就是这么来的。

我跟 Claude Code 说,清理掉。它帮我改了配置文件,重启。statx 从 45k 降到 0。

一个 Bug,搞定。

然后事情开始变得离谱

你以为这就完了。没有。

我跟 Claude Code 说,跑一下 doctor 看看还有没有其他问题。

它跑完,吐出来一堆。不是一个大 Bug,是七个。

说真的,我当时有点懵。一个升级,能炸出这么多东西。

我真的被震撼到了。

但每一个,都是 Claude Code 帮我定位的。我不需要一个一个去猜,我只需要把我的症状告诉它,它就知道该查哪里。

第二个,apiKey 的 schema 变了。旧版本的配置格式在新版本不兼容,直接报错。Claude Code 帮我把配置改到新格式,用 .env 环境变量替代硬编码。

第三个,systemd service 文件里的版本号锁死了。升级后实际路径变了,但 service 文件还指向旧版本。改模板,用相对路径。

第四个,exec 安全策略。3.31 版本之后 tools.exec.security 默认从 full 变成了 allowlist。单用户环境必须显式设回 full。这个坑我踩过一次,但升级的时候还是忘了检查。

我当时的反应是,这玩意怎么每次升级都要重新配一遍。Claude Code 跟我说,它帮我记着,下次升级之前先检查这一项。

第五个,飞书插件用户权限。应用权限 72/72 全通,但用户身份权限没授权。飞书的应用权限和用户权限是两条轨道,需要单独 OAuth。

我跟 Claude Code 吐槽,这设计也太绕了吧。它说确实,应用权限和用户权限分离是飞书的安全模型,但对普通用户来说就是「我明明授权了为什么还不行」。我说不就是吗。

反正我觉得,这种安全设计对普通用户来说就是折磨。

第六个,.clobbered 备份文件堆积。升级脚本生成的备份文件不清理会干扰正常启动,磁盘越占越多。

第七个,v4.24 Gateway 无响应加 npm 死循环。这是升级之后最先暴露出来的症状,和第一个 statx 问题是同一根藤上的瓜,plugins.allow 残留触发 fallback 循环,Gateway 卡死,npm 被反复触发安装。修完 statx 这个自然就好了。

7 个 Bug。每一个都不是「一眼能看出来」的那种。但每一个,都是我跟 Claude Code 一轮对话解决的。

你敢信,一个升级能炸出七个隐藏问题。

5.4 版本其实已经帮了我们不少

说句公道话,这次升级并不全是「旧配置撞上新版本」的锅。

5.4 本身也修了不少东西。sessions.list 从 150 秒优化到 3 秒,这个不是我的功劳,是 5.4 自带的性能改进。升级前我查过 release notes,知道这块有优化,但真正升上去看到数字的那一刻,还是觉得挺爽的。

所以客观讲,这次遇到的问题可以拆成三块。

第一块是我自己系统的历史配置问题。比如 plugins.allow 残留,那是之前测试插件留下的,我自己没清理。比如 systemd service 文件版本号锁死,是我当初手动改的模板,升级后忘了同步。

第二块是 OpenClaw 升级过程中的 breaking changes。apiKey schema 变了,exec 安全策略默认值从 full 变成 allowlist,这些都是版本升级带来的配置不兼容。不是 Bug,是升级文档里写了但你很容易漏看的东西。

第三块才是 5.4 本身修掉的旧问题。sessions.list 性能优化就是典型。

拆开看,每一块都没那么可怕。但凑在一起,就是一个风扇咆哮的周末。

顺便说一句,OpenClaw 这个社区现在真的很活跃。开发者迭代速度很快,几乎每周都有新版本。这么快的发展节奏下,遇到 breaking changes 太正常了。况且现在还有 OpenAI 收购作为背书,项目前景很好。Bug 是快速发展中的正常现象,不是项目不靠谱的标志。

我反而觉得,一个活跃的、有人持续维护的项目,比那些「三年不更新」的仓库靠谱多了。

我跟 Claude Code 的对话节奏

回过头看整个排查过程,其实有一个很有意思的模式。

每一轮对话都是同一个节奏。

我说,这里好像有问题。

Claude Code 说,让我跑个命令看看。

它跑命令,给我结果,用人话解释给我听。

我说,那怎么修。

它说,改这里,然后重启。

然后下一个。

坦率的讲,这个节奏让我觉得特别舒服。

其实吧,我以前总觉得这种技术问题得自己啃文档。我不需要知道 strace 是什么,不需要知道 statx 是干嘛的,不需要知道 systemd service 文件的格式是什么。我只需要会描述症状,「CPU 很高」「Gateway 没有响应」「npm 在一直安装」。

然后 Claude Code 就知道该查哪里。

这不是在学技术。这是在跟一个懂技术的人合作解决问题。而这个人恰好是个 AI。

回退不是失败,但更好的做法是不回退

说个细节。

四次升级三次回退。很多人觉得回退就是怂。我不这么想。

回退不是失败,是排除了一个方向。你知道这个版本不行,这个信息是有价值的。

但更好的做法是不要急着回退。

我跟 Claude Code 合作的过程中学到一件事,与其回退,不如逐层打开它。

用 ps 看哪个进程在占资源。用 strace 看这个进程在做什么调用。用日志看软件内部报了什么错。用配置文件看配置和实际环境是否匹配。用文件系统看磁盘上实际存在什么。

每一步都能排除一个假设。不是基于假设继续猜,是用事实说「不是这个」,然后往下一层走。

听起来很简单对吧。但实际操作中,人的本能是猜。

我自己也踩过这种坑,以前看到系统变慢第一反应就是回退。看到 CPU 高了就想回退,看到报错了就想重装。跳过诊断直接操作,然后操作完问题还在,再换一个操作。

我跟 Claude Code 最大的区别是,它不会猜。它只看数据。

这点我觉得挺重要的。

这套方法不只是用来修 Bug

我后来想了一下,这次升级最大的收获不是修了 7 个 Bug。

而是我确认了一件事,你不需要懂所有术语,你需要的是会跟 AI 描述问题。

说实话我还差得远,但我已经毫无保留地把我这一天的经验都掏出来了。

我不懂 strace。我不懂 statx。我不懂 systemd service 文件的版本号锁定机制。

但我知道怎么跟 Claude Code 说,「升级之后风扇开始狂转,帮我看看」。

然后它就知道该做什么。

每次系统犯错,就花时间工程化一个解决方案,确保它再也不会犯这个错。plugins.allow 残留变成了配置审查清单,apiKey schema 问题催生了 .env 环境变量规范,版本号锁死变成了 service 文件模板。

7 个 Bug 修完,系统不只是恢复了。它变得比升级前更健壮。

这才是升级的意义。不是拿到新功能,而是在解决问题的过程中把系统磨得更锋利。

每次升级都是一次压力测试。平时看不到的问题,在版本切换的瞬间全部暴露出来。那些你一直觉得「还能接受」的数字,四万五千次无意义的系统调用、60% 的 CPU 占用,在升级之后变成了压死骆驼的最后一根稻草。

它们一直都在。只是之前系统在容忍。升级打破了那个脆弱的平衡。

我现在有一套固定的流程。升级前备份配置。升级中监控状态。升级后跑 doctor 检查。出问题时不回退,用数据说话。

说起来就几句话。但每一句话背后都是一天一夜跟 Claude Code 对话的经验。

遇到问题别怕。你不需要懂所有术语。你需要的是会跟 AI 描述问题。


你升级软件或系统时遇到过类似的问题吗?你是自己排查还是求助别人?欢迎在评论区聊聊你的经历。


觉得有用,点个赞/在看/转发,想持续收到记得星标⭐,下次见。

相关阅读


我是 AI实战SOP,一个用 AI 搞工作流的技术人