那一刻其实很日常:我在飞书里 @ OpenClaw,让它“改个配置”。
消息发出去,工具也照常回了结果。我以为这事到此为止。
几分钟后,我发现不对劲:无论怎么 @、怎么发指令,它都不再回应——像是突然失声。
如果你把大模型工具只当成聊天窗口,这最多算“今天网络不好”。但当它同时承担网关、定时任务、消息投递这些角色时,这意味着另一件事:入口进程可能已经挂了。
更麻烦的是:入口挂了,你想用它修它,但指令进不去。
这篇文章复盘一次真实事故:一次配置变更触发了 Gateway 无限重启,导致飞书无法唤醒;最终只能切换到另一套工具(Claude Code / 本地编码代理)直接在机器上排障,把系统救回来。
本文想讲清楚一个结论:工程化使用 AI 时,你必须准备“两套大模型工具”——一套在线当主力,一套离线当救援。
(文中隐去具体用户名/机器路径;命令保持可复现。)
1)事故经过:从“让它改个配置”到“全链路失声”
起因很简单:
我在飞书里下达指令,让 OpenClaw 去修改某个配置/运行方式。 修改完成后,OpenClaw Gateway 开始异常:进程不断退出并被拉起。
最要命的是:Gateway 是飞书消息的入口。
当 Gateway 挂了,你在飞书里再怎么 @ 它、再怎么发命令,它都收不到——这不是“模型不听话”,而是“入口进程已死亡”。
于是出现了典型的“自动化悖论”:
你想用自动化工具修它 但修它的指令必须先经过它 它死了,指令进不去
到这一步,必须切换到第二条控制面。
2)从日志看真相:不是模型“失聪”,是配置校验把 Gateway 拦在门外
事故定位的第一步永远是:看状态 + 看日志。
这次的关键点在于:Gateway 根本没有成功启动。
日志里写得很直白(类似下面这种):
Invalid config at ~/.openclaw/openclaw.jsonagents.defaults.blockStreamingBreak: Invalid input (allowed: "text_end", "message_end")
也就是说:它不是“运行起来以后崩了”,而是启动自检阶段就直接退出。
3)根因:大模型按“旧版本认知”写了一个新版本不支持的 streaming 配置
昨晚的触发点,是我让大模型帮我在 openclaw.json 里加一条 streaming 相关配置,用来控制“分块输出/断句/合并”的体验。
结果它给出的配置是:
{ "agents": { "defaults": { "blockStreamingBreak": "sentence" } } } 但恰好昨天 OpenClaw 刚更新过,配置 schema 发生了变化:
blockStreamingBreak只接受 "text_end"或"message_end""sentence"这个值不再被支持(或者从来就不是这个字段的可选值)
于是 Gateway 启动时做配置校验,发现枚举值非法,直接拒绝启动——飞书里的你看到的就变成了“怎么 @ 都不回”。
这就是工程化 AI 场景里非常典型的一类事故:
模型给出了“看起来合理”的配置,但它的知识滞后于你系统当天的真实版本。
4)修复:改回合法值(或删除该配置),让 Gateway 先活过来
修复其实很直接:把 blockStreamingBreak 改成合法值,或者干脆先删掉这条配置。
例如(选其一):
"blockStreamingBreak": "text_end" 或:
"blockStreamingBreak": "message_end" 然后在“飞书入口之外”重启 Gateway:
openclaw gateway restart openclaw gateway status 一旦 Gateway 恢复在线,飞书这条控制面才会重新可用。
5)这次事故真正想说明的:你需要“第二条控制面”来修第一条控制面
这次我最强烈的体感是:
第一条控制面(飞书里的 OpenClaw)负责高效、日常、运营化 但当它因为“入口进程没起来”而失效时,你必须还有第二条控制面(Claude Code / 本地编码代理 / SSH / 终端)
否则你会陷入死循环:
你想用 OpenClaw 修 OpenClaw 但修复指令必须先经过 Gateway Gateway 起不来,指令进不去
所以,“两套大模型工具”不是为了追求更强,而是为了追求可恢复性。
这次事故给我的最大启示是:当你的大模型工具进入了“改配置/跑服务/控生产”的角色,它就必须像生产系统一样设计控制面。
6.1 第一套:聊天内的 OpenClaw(主力控制面)
它的价值是:
离业务近:飞书里一条消息就能改配置、跑任务、汇报结果 更适合“运营化”:可审计、可持续跑 cron、能把结果投递到群
但它的风险也很明确:
它依赖 Gateway 在线 一旦入口进程挂掉,你就会陷入“我必须通过它才能修它”的死循环
6.2 第二套:Claude Code / 本地编码代理(救援控制面)
它的价值是:
不依赖飞书入口:Gateway 死了也能直接上机器处理 更适合系统级排障:看 systemd、改 unit、查日志、跑诊断命令
这套工具不是为了和 OpenClaw “争主力”,而是为了在关键时刻保证:你依然有一条可以下指令的通道。
一句话总结:主力负责效率,救援负责确定性。
如果你已经在用 OpenClaw 这类工具跑“长期任务/生产工作流”,建议直接把下面这几条变成团队 SOP:
1) 明确两条控制面 - 主力:飞书内指令(OpenClaw) - 救援:本地编码代理/SSH/控制台(Claude Code 等)
2) 任何会影响入口进程的操作,都要有回滚 - 改配置前先备份 - 改 systemd unit 前先留 .bak
3) systemd 语义边界要记牢 - user unit(~/.config/systemd/user/):不要写 User= - 需要 User= 的:用 system unit(/etc/systemd/system/)
4) 给自己留一个“黑灯开关” - 至少能在 Gateway 死亡时:查看日志、改配置、重启服务
结语
把大模型工具当“聊天 App”时,你只需要选一个最聪明的。
把它当“生产系统的控制面”时,你需要的不是更聪明,而是:可恢复、可回滚、可救援。
所以我现在的原则很简单:永远准备两套大模型工具。
一套负责让你飞起来;另一套负责在你摔下来的时候,把你捞上来。
夜雨聆风