夜雨聆风学习资料网

ARTICLE · 1256798

AI 助手失联 62 分钟:一次「卡死」事故的完整复盘

AI 助手失联 62 分钟:一次「卡死」事故的完整复盘

这 62 分钟发生了什么

今天傍晚,我的 AI 助手(本地部署的 Hermes Agent)突然「失联」了。18:32 我发了一条消息,它 62 分钟后才回复——而且回复的是兜底话术「连不上模型」。这期间我重启过两次,一点用都没有。

这不是网络慢,更不是「AI 挂了」。是系统卡死了:进程还活着,但一条消息的处理永远不结束,也就不可能回复。今天我把整个排查过程完整记录了下来,从现象、根因到修复,一条条捋清楚。

这篇文章里你能拿走三样东西:这套「卡死」是怎么发生的、怎么快速定位、以及六道防线的防复发配置。

现象:消息发出去了,但永远没有回复

先说现象。今天一整天,网络其实都在悄悄抖动——飞书长连接断了 7 次、重连失败 5 次,从早上 9 点一直抖到晚上。当时没在意,因为每次几秒就恢复了。真正出事是傍晚:

- 18:31 一个定时任务(社区每日动态)被强杀——卡在抓网页上 941 秒,超过 600 秒无响应上限- 18:32:37 我在飞书发「在吗」- 19:34:24 系统才吐出回复——耗时 3707 秒,整整 62 分钟,回复内容 137 个字符:「连不上模型」- 20:13 另一条消息直接永久卡死——从收到到系统恢复,这条消息再也没回出来

本机飞书记录:18:32 发送 → 19:34 回复,耗时 3707 秒(2026-10-26)

更糟的是,当天下午 16:00 的定时任务也一起挂了:任务卡在「等待模型 API 响应」上 929 秒,超过上限被调度器强制杀掉。同一个病根,同时瘫痪了人工对话和定时任务两条线。

排查:进程没死,是「卡死」

重启无效让我意识到不是进程崩了。用 sample 采样进程线程栈,看到了关键一幕:

_ssl__SSLSocket_read_impl→ PySSL_select → poll   ← 无限等待

翻译成人话:程序在等一个永远不会返回数据的网络连接。TCP 连接还显示着 ESTABLISHED(「已建立」),但服务器那头已经 30 分钟没说话了——连接是「半开」的:对端静默丢弃,既不发关闭信号,也不再回数据。而我们的客户端代码没有设置读取超时,于是这个线程永久挂起,那条消息永远处理不完。

本机进程采样:线程卡在 SSL read 的 poll 无限等待(2026-10-26)

模型侧更明显——三套备用模型全部连不上:

ark-coding (deepseek-v4-flash)  request timeout   → fallback deepseek           request timeout     → fallback zai/glm-5.3      APIConnectionError(api.z.ai 连不上)       → ❌ API failed after 3 retries

本机模型请求日志:三层模型链路全部连接失败(2026-10-26)

三个模型供应商走同一个网络出口——热点一抖,三个全挂。fallback 防的是「一个供应商挂了换另一个」,防不了「整条网络路径挂了」。而且每层都等满超时才切,层层叠加,62 分钟就是这么攒出来的。

根因:一个失效的 TLS 连接 + 没有超时

直接机制:某条消息的模型请求,卡在一个已经失效的 TLS 连接上。服务端已经关闭(或者中间网络设备静默丢弃),但客户端 TCP 层还认为连接开着。Python 的 SSL 读操作没有超时,于是一直 poll 等待——一条 turn 永远不结束,就永远不回复。

这里有个容易被含糊带过的知识点,值得单独说:

- connect timeout 防的是「连不上」——建立连接最多等多久- read timeout 防的是「连上但永远等不到数据」——发出请求后,响应多久没来就报错

这次缺的恰恰是后者。连接早已建立成功,connect timeout 管不到「读取响应」阶段,于是一层一层往下,没有任何东西能打断这个阻塞。

方法示意:小黑打电话永远没人接——线程卡死在连接上(插画,非真实截图)

诱因:当天网络环境是手机热点(iPhone 热点网段 172.20.10.x)。热点的 NAT 和链路不稳定,长连接 + 长请求会被静默掐断。短请求(几秒内)都能通,所以表面看起来「网络没问题」。

为什么重启没用:两个叠加原因——

1. 网关的 launchd 服务根本没加载(Gateway service is not loaded),跑的是游离进程,没有 KeepAlive 守护;restart 检测到「已有副本在跑」,直接拒绝换进程——你的重启命令根本没起作用。

2. 旧进程收到退出信号后 60 秒不响应(同样卡在阻塞 IO 上——优雅关闭要先等当前 turn 结束,而 turn 正卡死在 SSL read),最终被强制杀掉。你「重启」的时候,旧进程还赖在位置上。

本机日志:飞书长连接断连 + launchd 服务未加载(2026-10-26)

还有个次生机制:18:31 会话写库时数据库连接刚好是空(同网络病),一条消息跑完了但回复没写进会话记录,用户侧同样是「没回」——这是「不回」的第二种通道。同一天,8 个常驻分身网关挤在一条热点上,一抖就是 8 份一起抖。

防复发:六道防线,纵深防御

设计原则很简单:任何一层失效,下一层兜底;目标是永不无限沉默,最坏 5 分钟内可感知(单请求 120 秒报错,单条消息 5 分钟熔断)。  先说清楚哪几道当晚就落地了:防线 1(超时参数)、3(网关接管)、4(换回宽带)当晚完成;防线 2/5/6 是我后续要补的建议配置——先把能做的做掉,剩下的排进待办,不假装全部到位。

防线 1:超时兜底(根治「永久卡死」)

在 ~/.hermes/.env 里追加:

HERMES_HTTP_READ_TIMEOUT=120      # 读响应最长等 120s → 超过即报错重试 HERMES_HTTP_CONNECT_TIMEOUT=15    # 建连最长 15s HERMES_TURN_TIMEOUT=300           # 单 turn 总时长上限 5 分钟 → 超了熔断结束

加了超时之后,最坏情况从「无限沉默」变成「5 分钟内熔断报错并回一句失败提示」——你能立刻知道它挂了,而不是干等一小时。

方法示意:给请求加超时保险丝,最坏 5 分钟熔断(插画,非真实截图)

防线 2:熔断(防单条消息挂 1 小时)

hermes config set tool_loop_guardrails.hard_stop_enabled true

工具循环/单 turn 超时自动熔断,坏消息自己结束,不再拖垮网关。

防线 3:进程守护(保证重启永远有效)

launchctl bootout gui/$(id -u)/ai.hermes.gateway 2>/dev/null   # 先清残留 launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/ai.hermes.gateway.plist hermes gateway status   # 期望 ✓ supervised

若进程卡死不响应 SIGTERM:直接 kill -9 <PID>(卡死状态无需优雅关闭),launchd KeepAlive 会自动拉起新进程。

防线 4:网络层(消除诱因)

- 换宽带/Wi-Fi——热点是本次直接诱因;- 必须用热点 → 关 IPv6(排查 PMTU 黑洞导致的 keepalive 超时);- 分身 gateway 瘦身——8 个常驻抢一条热点,停用不常用的(如 no-1000、av-transcribe)。

防线 5:依赖容错(防次生故障)

- web_extract/web_search 设独立超时上限(本次 18:31 一个定时任务卡在抓网页上 941 秒的教训,同一网络病);- 搜索后端 MCP 再出现 parked → 切 ddgs/exa;- cron 失败自动重试或次日合并补发。

防线 6:监控告警(故障可感知)

每 15 分钟检查网关进程存活 + 最近 5 分钟有无正常响应,连续 30 分钟无响应 → 飞书告警。正常静默,出问题才通知。

带走的核心清单

症状 → 判断 → 动作 发消息永远不回复 → 进程卡死不是崩了 → sample 看线程栈找 poll 无限等待 重启无效 → launchd 服务没加载 / 旧进程不退出 → bootout + bootstrap 重新接管 短请求通、长请求挂 → 网络路径静默掐长连接 → 换网络 / 关 IPv6 / 重建连接 定时任务也超时被杀 → 同一根因:模型请求卡死 → 加 HERMES_*_TIMEOUT 参数 三个模型全连不上 → 同一网络出口,fallback 防不了路径故障 → 换网络 + 超时兜底

一句话总结:AI 助手「不回消息」,多半不是 AI 的问题,是没人给它的网络请求设超时。进程还活着,但线程永远在等一个不回来的数据包。给请求加上 read timeout,把「无限沉默」变成「5 分钟熔断报错」,你才能快速定位问题——而不是像我今天这样干等 62 分钟。

如果你也在跑自己的 AI 助手,今晚就可以检查三件事:你的模型请求有没有 read timeout?你的网关服务是不是被 launchd 正常托管?你的网络出口是不是单点?查完这三条,大概率能避开我这个坑。觉得有用的话,可以转发给同样在折腾 AI 工具的朋友——少一个人踩坑,多一个人省一小时。

相关学习资料