资讯详情

一个配置开关让全司AI集体‘请假’:故障复盘与防御指南

📅 2026/10/16 15:23:21 | 华诺云谱 👁 阅读
一个配置开关让全司AI集体‘请假’:故障复盘与防御指南
那天上午十点我的工作群被一张截图炸开了推荐系统的点击率曲线、审核系统的误杀率曲线、客服系统的转人工率曲线三条曲线几乎在同一时刻开始失控。有人把三条曲线拼在一起配了一句评论全司AI同时申请产假。老实讲第一次看到这个梗我是想笑的但接下来的四个小时我完全笑不出来。这不是一句玩笑而是我们真的遇到了一个能让所有算法模型集体“摆烂”的故障。这个故障让我第一次认真思考一个问题当全公司的AI服务同时“请假”时我们到底应该先骂算法还是先看依赖链和配置中心这篇文章想完整复盘一次真实的排查过程也把后面补上的防御手段整理出来给同样被“AI集体罢工”折磨过的朋友一点参考。1. 事故日现场推荐、审核、客服在同一天开始“带薪发呆”1.1 三个业务线的异常表现各不相同先说现象。事故那天我们涉及的核心业务线一共有四条推荐、内容审核、智能客服还有一个语音助手。各自表现出来的症状完全不一样这也是最开始我们花了很长时间互相“甩锅”的原因。推荐业务线的反馈是最直观的首页推荐位的点击率一小时之内掉了将近一半而且用户刷出来的品类非常单一大量已经下架的商品重新出现在候选序列里。运营同学一开始以为是商品池出了问题还查了一轮库存同步任务。内容审核那边更吓人。当天上午开始审核系统对普通图片和短文本的误杀率从平时的0.3%直接飙到2.4%也就是大概每一千条正常内容里有二十四条被拦截。很多用户申诉和客诉涌进来审核团队一度以为是最近更新的敏感词库误伤了正常内容。智能客服和语音助手的表现则更“软性”客服机器人开始答非所问用户问退货流程它反复推荐优惠券和会员充值语音助手则表现为响应超时唤醒后要等三四秒才给出反馈而且回答内容明显偏“模板化”像所有句子都从一个默认答案池里捞出来的一样。1.2 “全司AI同时申请产假”这个梗是怎么传开的说实话如果只有一条业务线出问题大家不会往“公共故障”上想。但四路业务同时崩群里就热闹了。A同学在群里发了一张监控拼接图本来是想对比四条曲线没想到一眼看上去四根线几乎都在同一个时间点开始拐头。B同学随口回了一句“这架势是全司AI同时申请产假了吧。”这个梗很快传开因为实在贴切——不是某一块业务不行是每个业务里的AI都在“消极怠工”。但搞笑归搞笑排查还是要继续。我们当时第一反应都是检查自己最近有没有发版、有没有调参、有没有改特征。结果四个团队一通翻日志谁也没有找到自己这边的异常变更。真正让大家警觉的是每个团队都说“我们没动过代码模型也没重新发布过”。于是我们开始意识到问题可能出在大家共同依赖的某个地方。2. 排查链路从各查各的到锁定公共依赖2.1 第一波排查每个团队都在查自己的代码我先说我们当时最容易被带偏的地方。故障发生后推荐团队的第一反应是看快照特征、模型版本、AB实验流量分配。审核团队在看规则引擎的配置和敏感词表。客服团队在看FAQ检索服务和对话状态机。我们四个团队并行排查了两个多小时基本相当于各查各的谁也没往公共层想。这其实是一个很常见的排查误区。当一个系统“看起来”症状各不相同时大家倾向于认为问题在自己的业务代码里。但AI系统有个特点不同业务模型可以共享很多底层组件。比如特征平台、推理网关、模型服务框架甚至一个公共的全局配置项。这些组件如果出了问题表面症状会因为各自模型的输入输出差异而表现得很不一样但根因只有一个。我们开始把四路请求的链路图拉出来对照发现它们确实不是“互不相干”的。推荐模型、审核模型、客服语义模型、语音意图模型虽然部署在不同的服务里但推理时都会去同一个“共享特征服务”拉用户特征和内容特征。也就是说如果特征服务给的数据出了问题四路模型会同时“吃坏肚子”。2.2 共同的异常点模型网关的流量形态不对顺着这个思路我们把第一波调查重点放在模型推理网关上。从网关监控看四路请求的数量都没有明显变化QPS平稳HTTP错误率也很低表面上看不出什么大问题。但仔细看P99时延发现从十点零七分开始所有模型服务的P99时延都不同程度上涨客服模型甚至翻了一倍多。更关键的是请求在网关内部的分支统计出现了一个奇怪现象大量请求没有走“正常推理分支”而是走了“特征缺失兜底分支”。我们的推理框架有一个容错设计当模型请求拿不到特征时不会直接报错而是返回一个基于默认值的低置信度预测结果。这样做本意是防“脏请求”拖垮模型服务但坏处是它把故障静默吞掉了——网关日志里全是“feature_fallback”的标记却没有一条红色错误。到这里事情就清楚了一半四路模型本身没坏坏的是它们上游的特征获取。我们随后直接连到共享特征服务看每条请求日志果然发现所有特征字段都是0或者空字符串。模型拿到一堆空特征自然只能输出“无区分度”的结果表现为点击率下降、审核分数偏移、客服答非所问。2.3 特征服务的输入突变模型没坏是“饭”坏了我当时跟同事打了个比方模型就像厨子特征就像食材。厨子本身没有问题但食材仓库突然给每个订单都发了一箱过期土豆那不管是什么菜系的大厨做出来的东西都不会好吃。接下来要回答的问题是为什么特征服务会返回全零数据我们先查特征服务自身的缓存发现热点用户和内容特征的Redis命中率确实在下降但并没有到完全打空的程度。再往里查发现特征服务在构造每个特征向量的时候会调用一个“特征提取器”组件。而这个组件当前加载的居然是一个用于单元测试的mock实现——它不会访问任何真实数据源只会往每个字段里填默认值。看到这个线索我们立刻去翻特征服务对应的配置中心。这时候距离故障发生已经过去了三个多小时群里早就没有心情再玩“申请产假”的梗了。3. 真正的根因一个全局开关让整套推理链进入“测试态”3.1 配置中心里凌晨两点的一条变更真正的原因最终在配置中心的审计日志里被找到。记录显示当天凌晨两点十四分有人对“生产环境公共配置”做了一次变更变更内容只涉及一个布尔开关use_mock_feature_extractor从 false 改成了 true。这个配置项一看就知道是开发用的测试开关。正常流程里A同学在本地联调特征服务时会用true来绕过真实依赖让整个链路能跑通。但那天凌晨他在公共配置区里改了东西之后没有切回自己的私有配置空间也没有走生产变更审批直接把这个改动提交到了所有人共用的命名空间。他以为自己改的是自己那台开发机的配置实际上改的是全公司所有业务线模型服务都会读取的全局配置。于是从凌晨开始所有新进入推理流程的特征请求全都在走mock提取器。四路业务线因为请求量不同、缓存策略不同才从上午十点左右开始陆续表现出异常。这也解释了为什么事故不是“零点准时爆炸”而是拖到上班高峰期才爆发。3.2 为什么一个布尔开关能让所有模型集体失灵可能有人会问一个Mock开关怎么就让全公司AI集体失灵了这里面有三层原因缺一不可。第一层是公共配置的作用域太大。我们的配置中心支持按命名空间管理业务线的私有配置在各线自己的命名空间里但公共配置在所有服务里优先级最高。A同学改的这个开关正好挂在“公共配置”上所以所有服务都会读到。第二层是各业务线普遍缺乏输入校验。正常来说模型推理前应该检查特征的有效性比如非零率、缺失率、合理范围。但为了推理性能我们没有做全量校验只依赖特征服务返回“一定是对的”。当mock特征返回全零时下游模型根本没有察觉直接拿零向量做前向计算。第三层是之前提到的“静默降级”。推理网关看到特征缺失本应该把请求标记为失败并触发报警但我们的容错逻辑选择了返回默认结果。这个设计本意是防止个别脏请求影响用户体验结果在全局故障时反而让所有异常响应都变成了“正常响应”。这三层叠加在一起的后果就是系统没有报错没有崩溃只是像一群不想上班的员工一样每个人都给出最低质量的产出然后还假装自己干得很好。3.3 从返回内容异常到提交记录的实锤回头梳理时间线整个排查过程大致是这样的时间动作判断10:07监控告警触发各业务群开始处理以为是个别业务故障10:30四路业务交叉对比怀疑公共依赖层11:20定位到模型网关大量走fallback特征服务大概率有问题11:50直接调用特征服务测试接口全量特征全是012:30翻特征服务配置加载日志发现mock提取器被加载13:00查配置中心审计日志确认全局开关被人打开13:30回滚配置切回真实特征提取器指标逐步恢复回滚操作本身只花了几秒钟。但回滚后指标并没有立刻恢复原因是下游模型还在用旧的缓存特征做推理需要等缓存过期。到下午两点左右推荐点击率、审核误杀率、客服转人工率才先后回到故障前水平。整个故障持续了大约四小时影响面覆盖四个业务线直接导致当天数万条内容需要人工重新审核。我后来问A同学他说他当时只是想把联调环境跑通改完就被拉去开会了完全没想起来自己动的是生产公共配置。这个回答听着离谱但其实很典型——每一个配置事故背后几乎都有一个“我就临时改一下”的念头。4. 复盘后的防御体系怎么防止AI再次集体请假4.1 全局配置的权限隔离、审批与灰度事故后的第一件事是把配置中心的权限模型重做了一遍。公共配置命名空间不再允许任何个人直接编辑只能通过“申请-审批-灰度-生效”的流程。流程里强制要求写清楚影响范围、变更原因和回滚方案并且配置生效支持按比例灰度比如先让5%流量走到新配置观察十分钟没有问题再全量。同时我们规定所有带mock、debug、test、dev字样的组件只能在测试环境加载。生产环境的服务启动时会做一次“环境标识检查”如果发现当前环境是生产但配置要求加载mock提取器直接拒绝启动并报错。这个检查看起来很傻但却是最有效的一层保险。这里有一个细节配置中心一定要保留完整的审计日志包括谁改的、什么时间改的、改之前的值和改之后的值。这次事故能在一小时内确认根因靠的就是审计日志里那条清清楚楚的变更对比。如果没有审计日志大家可能要从特征算子包版本一路查到凌晨的发布记录难度会大很多。4.2 给模型输入增加“特征体检”第二项关键改造是在推理链路里增加特征合法性校验。我们加了一个轻量级的“特征体检”逻辑放在特征服务返回结果之前。每次批量特征返回时统计稠密特征的“有效非零字段占比”如果低于某个阈值比如40%就认为这次特征构造异常直接返回显式错误而不是拿着全零特征往下游发。显式错误的好处是下游的推理网关会立即感知到上游异常进而触发熔断和告警而不是走静默降级。也就是说我们允许模型服务不可用但绝不允许模型服务“坏着还假装可用”。可用性可以降数据质量不能被污染这是一个非常重要的取舍。实际做下来这个校验对性能影响很小。我们只对特征向量里的关键字段做统计不需要逐个遍历所有维度。而且校验结果可以写到日志里配合监控平台画一条“特征非零率”曲线一旦数据开始漂移能第一时间看到。4.3 可观测性升级不能只用QPS和错误率判断AI健康这次事故给我们最大的教训之一是AI系统的健康度不能只看QPS、错误率和时延。这三个指标对于传统接口来说够用但模型服务比较特殊——就算QPS正常、错误率为零、时延很低模型也可能在输出一堆垃圾结果。所以我们在监控看板上新增了几个指标模型平均置信度、Top1得分与Top2得分的差距、特征有效字段占比、降级分支调用次数。这些指标能直接反映“模型输出质量”。比如说推荐模型原本Top1和Top2的得分差通常在0.3左右如果某天突然缩到0.01那就说明排序几乎没有区分度很可能特征在退化。这类“输出健康度”指标不用全部建模先挑两三个最敏感的就行。关键是让监控的人能在业务指标异常之前先看到模型输出的异常。我们这次就是太信任业务指标等到点击率掉了才警觉其实模型平均置信度在故障后几分钟内就已经明显下滑了。4.4 应急预案宁可切换人工兜底也不要在有问题的系统上硬撑最后我们重新梳理了全公司各业务线的人工兜底流程。很多团队平时只依赖AI自动化一旦AI故障根本没有快速切换到人工的能力。这次审核业务就是因为没有备用的人工审核队列导致大量内容挤压。现在的预案很简单一旦核心模型服务的“输出健康度”指标连续五分钟异常值班同学有权直接触发“AI停用”开关让业务流量切到规则引擎、人工队列或历史推荐缓存。听起来很粗暴但实践证明与其让AI继续以低质量状态产出不如先停掉它保住用户体验。这个开关平时每季度会做一次演练。第一次演练的时候好几个团队发现自己根本不知道怎么一键切换折腾了半小时才找到对接人。演练完我们把切换操作整理成一张校验表贴在值班文档首页确认上游特征状态、确认数据源可用、确认人工队列水位、一键切换、验证业务指标。5. 最后一点私货算法没有感情但依赖链会记仇这次“全司AI同时申请产假”的事故后来成了我们组里的一个梗。每次有人改配置大家都会开玩笑说“你小心让全司AI集体请假”。玩笑归玩笑背后的教训我记了很久。AI模型本身没有情感不会真的“累”或“罢工”。它只能按照数据、特征和配置去计算。当所有模型同时给出糟糕结果时我们要找的不是某个模型“变笨了”而是它们共同依赖的那条链路里哪个环节被悄悄换掉了。配置开关、特征服务、推理框架任何一个公共组件出问题都足以让整个体系在同一天集体“摆烂”。我现在看任何AI系统都会先问几个问题模型的输入特征有没有校验公共配置有没有权限隔离和审计监控里有没有“输出健康度”指标人工兜底链路能不能一键切换这几个问题问完基本就能判断一个团队是真的在做AI系统还是在裸奔。如果你也遇到过类似的“AI集体请假”事故别急着骂算法先去翻配置中心的审计日志。那个全公司的AI们同时沉默的早晨最后教会我的不是怎么修模型而是怎么尊重依赖链。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑