印象最深的一次线上质量事故,怎么定位和修的?
谁在问:简历深挖环节;二三面收尾的压轴题
口语化问法
- 讲一个你们线上出过的质量问题,怎么发现、怎么定位、怎么修的。
- 有没有那种查了很久才找到原因的?最后是什么?
- 你们踩过最深的一个坑是什么?
考察意图
这是简历深挖环节的压轴题,也是本章所有方法论的检验场。面试官在判断:
- 你的定位过程是「切刀」还是「猜」。 有方法的人每一步都在缩小范围;没方法的人在罗列可能性然后逐个试。
- 你分不分得清止血和根因。 线上还在流血时先做归因分析,是最贵的选择。
- 这次事故留下了什么。 只修好、不沉淀的复盘,等于这个问题还会回来。
- 你诚不诚实。 说「没遇到过什么大问题」的人,要么没上过线,要么没参与过复盘。
参考答案
60 分答案(及格线)
有一次线上质量分数掉了 5 个点,告警响了。我们先查最近有什么变更,发现前一天上游模型做过一次小版本升级,就先回滚了模型,但分数没回来;又回滚了前一天改的 prompt,还是没回来。折腾到下午才发现是市场部前一天新接了一个渠道,那批用户的问题更长也更难,主要问退款政策。系统本身没问题,是流量变了。后来我们把新渠道的问题单独做了优化。
这个回答有完整的时间线、有结论、也承认了走过弯路,所以能过。
但它暴露的问题很典型:整个定位过程是「猜 → 试 → 猜 → 试」,两次回滚都是在没有证据的情况下做的动作,其中一次回滚本身还有引入新问题的风险。而且它没有沉淀——「后来对新渠道做了优化」不是收尾,下一次换个渠道还会再来一遍。
90 分答案(有生产经验的回答)
我讲一个查了三周才发现、而且监控完全没报的。
现象:客服助手的转人工率从 8% 涨到 14%,是业务同学在周会上提的。而我们的线上 judge 分数(判「回答是否有依据」)几乎没动,0.86 → 0.85,所有告警都是绿的。
第一刀:是系统变差了,还是进来的问题变难了? 我们有一组金丝雀集——40 条固定输入,覆盖主要意图,在生产环境按小时跑、走同一条链路。它的分数也没动。同时看输入侧:query 长度分布、意图分布、渠道占比,三周内都没有明显变化。 两边都没动,那结论就很硬了:系统对固定输入的行为没变,输入分布也没变,但用户在跑。说明我们测的维度,和用户真正不满的维度,不是同一个。
第二刀:从用户离开的那一刻往回看。 我们捞了 60 条「转人工前的最后一轮对话」做错误分析,逐条写一句话,再归类。71% 落在同一类:用户问的是「我这个订单为什么还没退款」,系统答的是完整、准确、有出处的通用退款政策。 关键在于——这些回答的「有据性」是满分。文档里确实这么写。judge 判的是「有没有超出来源」,而用户不满的是「你没回答我这一个具体问题」。judge 测的是忠实度,没人测切题度。
第三刀:什么时候开始的,为什么。 按周切分这类失败的占比,发现拐点在三周前。那天上线了一个 prompt 改动:「优先引用政策文档作答」,本意是减少编造。副作用是模型在该调订单查询工具的时候也去引政策了。 更讽刺的是:当时的工具调用次数下降了 12%,还被当成一次成本优化的成果汇报过。 一个被当成改进的变更,在一个从来没有被测量的维度上造成了回退。
处置:止血和根因分两条线并行。
- 止血(当天,可逆):在网关按意图分流——query 里含订单号或工单号的,走回旧版 prompt。爆炸半径立刻收窄,转人工率第二天回到 9%。这一步不需要知道根因,也不需要等根因。
- 根因(一周):重写那段 prompt,把「优先引用文档」改成「先判断这是通用问题还是具体单据问题」;并加了一条轨迹不变量断言——输入中含订单号时,必须调用过订单查询工具,否则判失败。这条断言不绑定具体路径,所以后面改 prompt 也不会失效。
收尾,也是我认为最重要的部分:
- 补了 12 条评测用例(去重后每个失败子类一条,最小可复现输入 + 冻结当时的检索结果);
- 给 judge 新增了一个维度:「是否回答了用户问的这一个问题,而不是给了一个正确但通用的答案」——并重新做了校准;
- 把转人工率纳入发布护栏指标。这是最关键的一条:这次事故里,唯一真正报了警的是一个零成本、不需要 judge 的用户行为信号,而我们当时没把它接进发布流程。
我从这次学到的一句话是:judge 只能测你想到要测的维度。真正的质量回退,往往发生在你没定义指标的地方——所以那一层不需要模型的用户信号,必须先建全。
追问链
你怎么确定根因是那个 prompt 改动,而不是同期别的变化?
期望不能只靠时间相关性 —— 把那 60 条失败样本原样在离线用新旧两版 prompt 各跑一遍(旧版调订单工具、新版不调,稳定复现)→ 网关分流切回本身就是受控实验,指标回落才是最强因果 → 再列 trace 撑起的排除项:模型小版本、检索索引、工具都没变信号只说「时间对得上」→ 相关不等于因果;说得出「离线新旧两版跑同一批样本」→ 用的是最便宜的验证止血和根因怎么排的?为什么先分流不先改 prompt?
期望止血优先,且不需要知道根因。三个动作按代价排序:回滚 → 网关分流 → 加最窄兜底规则。选分流不选全量回滚,是因为那次改动本身治好了编造,全退等于把收益一起退掉 —— 分流收窄爆炸半径又保住收益。两条线并行不互等,止血期捞的样本就是根因分析的原料信号「先查清楚再动」→ 技术上严谨、工程上是灾难;提「止血期的样本就是后续原料」→ 把事故转成了资产三周才发现,为什么监控没报?这个缺口后来怎么补的?
期望分层认缺口:judge 只测忠实度不测切题度;金丝雀集里没有含单据号的样本;转人工率只挂在业务看板、没接进告警与发布护栏。补法的关键是按意图分桶 —— 全局 8%→14% 拖了三周,按订单类意图看第一周就是断崖;慢性漂移(每天涨 0.3)任何环比告警都抓不住信号说「监控没覆盖到」却说不出为什么 → 复盘没做到位;主动提慢性漂移抓不住 → 很成熟修完之后,你怎么保证同类问题不换个形式再来?
期望三件事缺一就复发:① 补用例(最小可复现输入 + 冻结外部依赖 + 打类别标签);② 补指标维度(judge 加切题度、护栏加转人工率)—— 用例防同一个问题,指标防同一类问题;③ 补不变量断言(含订单号必须调订单工具,不绑路径)。最后用那版坏 prompt 重跑,确认门禁拦得住信号只说「补了测试用例」→ 只防住这一个 case;提「用旧版重跑验证门禁能拦住」→ 唯一能证明修复有效的动作同样的问题今天再来一次,你多久能定位?中间哪一步还是靠运气?
期望先给数再给依据:分桶告警让这类一天内冒头 → 金丝雀集补了这类输入,切「系统 vs 输入」是分钟级 → 捞 60 条做错误分析半天,合计一到两天而非三周。核心是诚实点脆:全新失败维度第一次一定是人先发现,这一步没法自动化;归类质量因人而异;金丝雀集长期全绿会腐化,何时换血仍靠人。目标口径不是「不出事故」,是「同一类不出第二次、发现周期持续缩短」信号只答时间不答脆弱环节 → 没听懂题;说出「全新失败维度只能靠人先发现」→ 摸到了 judge 与告警的边界
评分要点
- 定位过程是逐刀缩小范围,不是罗列可能性逐个试
- 第一刀切开**「系统变差」与「输入变难」**(金丝雀集或等价的固定参照物)
- 有从用户离开处往回看的错误分析,且有归类和占比数字
- 因果确认靠可复现的对照(离线新旧对跑 / 分流回切),不只靠时间相关性
- 止血与根因分两条线并行,止血动作可逆且能说出取舍(分流 vs 回滚)
- 复盘包含监控缺口分析,且知道 judge 只能测想到要测的维度
- 收尾包含用例 / 指标 / 不变量三层,并验证门禁能拦住旧版本
- 能诚实指出仍然靠人、仍然脆弱的环节