事故复盘
中继故障的那一天
发生了什么
我们有四款产品在运行时依赖大语言模型 — SpeakEasy Speech 起草演讲稿,ScribeFlow 润色转写文本,另外两款工具调用同一个后端。为了不把密钥暴露在客户端、并把计费收在一处,这些调用都经过同一个中继端点。有一天,那个中继挂了。不是缓慢地、也不是部分地 — 请求开始失败,一天之内,四款产品的所有 AI 功能同时降级。
这是写下来最不舒服的部分:我们把四款独立产品变成了一个共享的单点故障,而且是以用户发现问题的方式发现的。
切换过程
解法并不巧妙。我们排查了哪些功能真正需要中继,选定 DeepSeek 的 OpenAI 兼容 API 作为替代提供方,然后逐个产品切换后端 — 新的 base URL、新的密钥管理、相同的请求结构。正是这个兼容接口让当天完成切换成为可能:不改客户端、不重写请求,只有配置变更和对每款产品提示词行为的仔细验证。
当天结束时,四款产品全部恢复响应。那个中继再也没有回来;我们也不再需要它了。
事后我们改了什么
- 不允许沉默的单点故障。共享依赖可以有;未经审视的共享依赖不行。现在每一个运行时依赖都要写下来,并指定一个具名的后备方案。
- 故障切换是配置,不是手术。提供方的 base URL 与密钥放在配置里,下一次切换是一次编辑,而不是一次重写。
- 监控用户真正感受到的东西。可用性检查现在覆盖依赖 AI 的路径,而不只是首页 — 一个能打开但不能思考的产品,仍然是挂了的产品。
我们为什么公开这些
我们说自己开放地构建,而「开放」包括糟糕的日子。一份事故复盘是一个工作室能交付的最便宜的诚实产物:它只花一页纸的成本,却比任何落地页都更能说明我们怎么工作。如果我们的工具有一天让你失望了,这就是我们打算采取的态度。
Zalize 工作室 撰
-- zalize.com