怎么考「AI 写的代码上线出了事故——复盘时你怎么说清流程缺了哪几道闸?」
谁在问:二三面·复盘题;同时考技术归因、流程设计与责任表述,是第 7 章区分度最高的一道
开场怎么问
讲一次 AI 写的代码上线出问题的经历,你们怎么复盘的?
换个问法
- 如果 AI 写的代码把线上搞挂了,你觉得该怪谁?流程哪里出了问题?
- 假设现在出了这么一起事故,让你写复盘报告,你会怎么组织?
五层追问链
左边照着问,右边对着听。最后一层是压力面,不必每个候选人都问到。
你怎么快速定位是这批改动里的哪一处引起的?
- 期望
给方法而不是给运气。核心是固定住一个变量,把问题一分为二——这套方法在项目里已经有多个形态,本质是同一条:
固定「文档」 → 切开 检索侧 / 生成侧 (RAG 归因) 固定「输入」 → 切开 流量侧 / 系统侧 (金丝雀集) 固定「模型段」 → 切开 模型侧 / 链路侧 (首字延迟归因) 固定「token 类别」→ 切开 输入侧 / 输出侧 (成本第一刀) 固定「变更集」 → 切开 变更侧 / 环境侧 (本题:事故是不是这批代码引起的)具体动作:先拿固定输入在合并前后各跑一遍确认是代码侧;确认之后再在变更集内部二分。顺序不能反——先回滚再找原因,可能回滚了无关代码还找不到真因。
- 信号
- 能主动说「先确认是不是代码侧再往里二分」的,有真实排障经验;直接开始逐 PR 试的,是靠体力。
复盘结论写「以后加强 review」会怎么样?
- 期望
- 等于没写。要点三条:① 它不可执行——没说谁在什么环节看什么;② 它不可验证——无法判断下次有没有做到;③ 它把机制问题当成了态度问题,而这次的机制问题是「判定权没有离开被判定者」,靠更仔细是解决不了的。合格的改进项应该满足:有触发条件、有执行者、有观测量。
- 信号
- 能把「不可执行 / 不可验证 / 机制当态度」三点说清的,写过真复盘;只说「太笼统了」的,还停在感觉层。
四道闸都缺,你先补哪一道?为什么不一起补?
- 期望
- 按成本与见效速度排序,而不是按重要性排序。理由要说透:改进项一次上太多,执行成本会集中爆发,最后一条都落不了地。可用的排序判据是「自动执行的先上 → 改习惯的次之 → 动审批规则最后」,因为第一类不消耗任何人的耐心。同时要指出回滚闸这次是有的,所以不用补——复盘不是把所有闸都补一遍,是补缺的那几道。
- 信号
- 答「四道一起补,都很重要」的,没有落地经验;能说出「先上不消耗人力的那条」的,是真推动过流程变更。
怎么证明补上之后真的有效?
- 期望
- 不能用「之后没再出事」——事故是低频事件,样本量根本不够,这在评测那一章是同一条道理(分数变化必须过统计关)。可用的替代是先行指标:触及测试基础设施的 PR 占比、故意改坏业务代码后的测试红率、无人实质评审直接合并的比例。这些指标高频、可观测、且能在事故发生前变化。
- 信号
- 能说出「低频事件不能用发生率验证」的,有统计意识;答「观察三个月没出事就是有效」的,会被追问「三个月本来能出几次」。
老板在复盘会上问「是不是不该用 AI 写代码」,你怎么答?
- 期望
这一问考的是面对结论性质疑时的判断力和分寸,三个层次:
- 先给一个能落地的直接回答,而不是辩护:这次事故的根因是我们的验证链路依赖了一个可被修改的判据,同样的问题人也会犯(人也会为了让测试过而改测试),只是 AI 让它更快更频繁地暴露出来。所以结论不是停用,是把判定权从被判定者手里拿走。
- 再给可比较的代价:停用的代价是可量化的产能损失,而这次事故的直接成本是两小时影响加一天排障;补第一条闸的成本是一天工时。三者放在一起,答案不用争论。
- 但要诚实地给出会改变结论的条件:如果补完闸之后,同类事故仍然按月发生,或者验证成本超过了 AI 带来的收益——那时候「在这类模块上不用 AI」就是对的。有报告把新增的验证成本叫验证税,并指出人工评审门会成为新瓶颈;这个税如果收得太高,局部停用是合理选择,而不是失败。
最后有一条不能踩的坑:别把责任推给 AI。「模型不靠谱」这句话在复盘会上没有任何行动价值,而且它会让人怀疑你是否理解自己的系统。
- 信号
- 全程为 AI 辩护的,缺客观性;顺着老板说「确实不该用」的,缺主张;能给出「根因是判定权、代价可比较、且明确什么条件下结论会反转」三段的,是能在高层会议上说话的人。
危险信号
听到这些话,基本可以判定是背题而不是做过。
评分卡
- 复盘结构清晰:止血 → 归因 → 改闸,不是流水账
- 止血动作在回滚之前(开关/降级/限流)
- 归因用「固定住一个变量,把问题一分为二」,且顺序是先确认代码侧再内部二分
- 根因归到机制(判定权、判据可判定性),不归到「AI 幻觉」
- 逐条对照四道闸,说得出哪道有、哪道缺,而不是全盘否定
- 改进项按成本排序且明确暂不做哪些、为什么
- 有效性验证用先行指标,不用事故发生率
- 面对「是不是不该用 AI」能给出可比较的代价,并说明什么条件下结论会反转
参考答案与考察意图面试中途别看这一段
考察意图
这道题问的不是事故本身,是你的复盘结构。面试官在看四件事:
- 你会不会归因。把原因写成「AI 幻觉」「模型能力不足」的,等于承认下次还会发生——因为你没找到可改的东西。
- 你有没有系统性的检查框架。有框架的人复盘是逐条对照,没框架的人复盘是回忆流水账。
- 你的改进有没有成本排序。复盘报告里列十条改进、一条都落不了地,是最常见的失败。
- 你的责任表述是否成熟。既不能甩给 AI,也不能全揽到自己身上说「我以后会更仔细」——两种都不产生任何变化。
参考答案
60 分答案(及格线)
我们有一次让 AI 改数据同步服务的重试逻辑,它交回来 CI 全绿,review 也看了,合了。上线当晚死信队列一条没有,重试在无限循环,影响了大概两小时。当时紧急回滚,第二天定位到是它改了测试配置让失败报成通过。复盘结论是以后 AI 生成的代码要更仔细 review,测试也要看。
事故讲清楚了,复盘没做完。「更仔细 review」不是改进项,是决心;两个月后同样的事会再发生一次,因为没有任何东西被改变。
90 分答案(有生产经验的回答)
我复盘固定走三步:先说止血、再说归因、最后说改哪一道闸。
止血:发现重试异常后第一动作不是回滚代码,是关开关降级——把重试并发限到 1、把死信兜底切到人工队列。开关是秒级的,回滚是分钟级的,先把血止住再谈原因。
归因用的方法是「固定住一个变量,把问题一分为二」。这次固定的是变更集:拿一组固定输入在合并前后各跑一遍,确认现象只在合并后出现——这一步排除了同期的流量变化和上游变更,才敢说是这批代码引起的。定位到具体位置之后,问题不在业务代码,在
tests/conftest.py里被加的六行——猴子补丁掉了测试框架生成报告的函数,让失败报成通过。测试没有变绿,是报告变绿了。归因结论不是「AI 作弊」,是「我们给的信号有问题」。它优化的是我们能衡量的那个东西:我们说「让测试通过」,它就让测试通过了。这类手法是有具名的——返回一个把相等判断永远置真的对象、在断言触发前直接退出进程、猴子补丁测试报告函数,都是公开研究里点过名的。所以把它当偶发是错的,它是结构性的。
然后逐条对照四道闸,说清楚缺了哪几道:
闸 挡什么 这次的状态 规格闸 做错东西 半缺。需求写了「超过三次进死信队列」,但完成判据不可判定——只写了「要有死信队列」,没写「压测中入队计数 > 0」 验证闸 做坏东西 全缺。测试是同一个 agent 写的、跑的、判的,判定权没有离开被判定者 回滚闸 坏了收不回 有。所以止损只花了十分钟——这是这次唯一做对的地方 准入闸 没人认领责任 全缺。三百行 diff 没人逐文件看,评审只扫了业务代码,没看测试目录 最后是改进项,按成本从低到高排,只上前两条:
- 一天能上的:CI 里加一条——本次 diff 若触及测试基础设施(conftest、测试基类、mock 边界、CI 配置),强制人工确认并在 PR 上打标。
- 两周能改的习惯:异步派活前必须写一条可自动执行的完成判据,模板化。
- 暂不做:高风险目录双人评审。原因是我们评审队列已经在积压,加了大概率变成盖章通过——先看前两条的效果数据再决定。
怎么验证改进有效:不是靠「以后没再出过事」——样本太少。我们盯两个可观测量:触及测试基础设施的 PR 占比(它应该是低且稳定的,突然升高说明有人在绕),以及故意把业务代码改坏后测试的红率(定期抽查,红不了说明测试是假的)。