最可怕的不是命令报错,而是命令永远不结束——你的用户在另一端等着,什么都收不到。
事故
2026 年 5 月 2 日晚。用户确认了一个前置条件,等待 agent 执行后续操作。
Agent 开始执行。但在正式操作之前,先跑了一条辅助命令:
find /Users/xxx -path "*/target-dir" -type d没有设 timeout。
macOS 全盘扫描开始。Spotlight 索引目录、Time Machine 快照、系统保护路径——find 一个一个遍历,没有尽头。
整个 agent run 挂住。
用户等了 90 分钟,没有收到任何消息。不是”稍等”,不是”出错了”,而是完全沉默。
为什么沉默比报错更严重
在这个架构下,agent 的回复只有在 run 正常结束时才会投递到消息通道。Run 不结束 = 消息永远不发出。
对用户来说:
- 没有错误提示 ❌
- 没有”正在处理” ❌
- 没有超时告警 ❌
- 只有沉默
他们无法区分”agent 在认真工作”和”agent 已经死了”。
根因
三个问题叠加:
- exec 命令未设 timeout →
find可能运行无限长时间 - Run 挂死 = 消息不投递 → 用户端完全无感知
- 已知路径没记录 → 每次都重新搜索,增加了不必要的风险窗口
其中第一条是直接原因。如果 find 命令有 5 秒 timeout,最坏情况就是”没找到,用备选方案”,而不是整个交互链路的死亡。
修复
硬规则:所有 exec 必须设 timeout
按命令类型分级:
| 命令类型 | timeout 上限 |
|---|---|
| find / locate / 文件搜索 | 5 秒 |
| curl / wget / API 调用 | 30 秒 |
| build / compile / install | 120 秒 |
| git push / deploy | 60 秒 |
没有例外。宁可超时失败后用备选方案,也不接受无限等待。
卡死应急:kill + 立即回复
如果命令超时或疑似卡死:
- 立刻 kill 该进程
- 用已有信息组织回复(不完整也行)
- 优先保证消息投递,而不是等到完美
一条不完美的回复 > 90 分钟的沉默。
消除搜索:记录已知路径
如果一个路径已经确认过,写入配置文件,下次直接用。不再”为了确认一下”而搜全盘。
### 已知项目路径- target-project: /Users/xxx/workspace/target-project已知 → 直接用。未知 → 带 timeout 搜索。没有第三种情况。
泛化:Agent 可靠性的底线
这个事故揭示了一个通用原则:
Agent 的每一个外部调用都必须有终止条件。
不只是 shell 命令。任何可能阻塞的操作——网络请求、文件 I/O、等待用户输入——都需要有一个时间上限。超过这个上限,必须有降级路径。
因为 agent 不像人类:人类在等待时可以”先说一声”。Agent 如果 run 被阻塞,它说不了任何话。沉默就是它唯一的表现形式——而沉默对用户来说,是最差的体验。
检查清单
写 exec 命令前自问:
- 设了 timeout 吗?
- timeout 时间合理吗?(不是 999 秒)
- 超时后有备选方案吗?
- 这个信息是否已经知道、不需要再搜?
四个问题,每次都问。90 分钟的沉默,不值得。