
先交代背景。我们这套多平台电商客服接待工具,跑在 Windows 桌面上,接管千牛、咚咚、拼多多商家版这类客服工作台:监听买家消息、生成拟答、把文本填进当前会话的输入框、触发发送。整条发送链是"拟答 - 打开消息弹窗 - 预览会话 - 校验 - 定位会话 - 粘贴 - 发送"。2026-08 中旬,有人在发送链里加了一道"发送前防错"校验,动机非常正当:怕回错会话。逻辑朴素得无可指摘——消息弹窗里列着待回复的买家消息,点开某一条,弹窗会预览这条消息所在会话的末尾内容;同时从屏幕会话列表里读那条买家消息的原文;两边文本一致,说明预览确实停在这位买家这里,可以发送;不一致,宁可取消也绝不发错人。上线两周后,这道防错闸把自己玩死了。事故特征一句话可以概括:**只要买家连着发多条消息,末条的自动回复就回不出去。**日志统计更难看:这道校验共触发 4 次,4 次全部取消发送,0 次复核成功进入发送。按设计意图,它是"偶尔拦一下可疑情况"的兜底;实际行为是"每逢连发必杀"。更要命的是第二层伤害:取消发送这个动作,会把弹窗里那条消息点成已读,条目从待回复列表消失,该买家此后这条消息再也不会被自动接待系统投进重试队列。上线到下线,被这道校验拦掉的那 4 位买家,后续自动回复次数全部为零。这篇复盘把三件事讲清楚:怎么在跨天混杂日志里把它归因出来;这个判据为什么在构造上就注定误杀,而不是某个参数没调好;以及收口的三步——判定改纯函数 verdict、拿蜂答式三档判定做对照说明"自创更严判据反而更危险"、断言加真机回归钉死,外加旧链新链双改的注意点。## 事故现场### 证据复盘起点是一单客诉:买家当晚连发三条,人工只看到系统回了头两条,第三条晾了一夜。翻接待日志,第三条的拟答早就生成好了,发送链也走到位,停在弹窗校验这一步:log[2026-09-04 22:54:07] preview_check session=S7 target_msg="我付了,记得今天发"[2026-09-04 22:54:08] popup_preview_text="什么时候发货?"[2026-09-04 22:54:08] preview_check result=MISMATCH - cancel_send弹窗预览读到"什么时候发货?“,屏幕上要回的那条是"我付了,记得今天发”。文本不相等,取消。当时值守同学的解释很自然:买家两条消息中间隔了十分钟,弹窗内容"过期"了。这个解释撑了三天,直到我们把所有 MISMATCH 记录归拢——没有一条是间隔造成的,4 次全部发生在买家几秒内连发的窗口里。把这 4 单归拢成一张表,共性一目了然:| 会话 | 买家连发条数 | 弹窗预览停留位置 | 校验裁决 | 取消后该消息再投递次数 || — | — | — | — | — || S7 | 3 条 | 停在第 1 条 | MISMATCH 取消 | 0 || S11 | 2 条 | 停在第 1 条 | MISMATCH 取消 | 0 || S15 | 4 条 | 停在第 2 条 | MISMATCH 取消 | 0 || S24 | 3 条 | 停在第 1 条 | MISMATCH 取消 | 0 |触发 4 次、取消 4 次、复核救回 0 次、涉事买家后续再投递 0 次,四列数字把这行代码的判决书写完了。### 时间窗归拢数据时先踩了个坑:日志工具的筛选面板只暴露时间窗选择。复盘习惯性地框了 22:00-23:00,想看看"那晚的回帖链路":log$ log-export --platform all --window 22:00-23:00[2026-09-04 22:47:59] msg_inbound S7 "什么时候发货?"[2026-09-04 22:48:01] draft_ok S7[2026-09-04 22:54:07] preview_check session=S7 ...[2026-09-04 22:54:08] preview_check result=MISMATCH - cancel_send按这个窗口看,校验只触发了一回,像是偶发。换成自然日全量再看:log$ log-export --platform all --day 2026-09-04 | grep -c "preview_check result=MISMATCH"4$ log-export --platform all --day 2026-09-04 | grep -c "preview_check result=OK"0同一个校验,框一小时是"偶发",放一天是 4:0。原因不神秘:客服工具的日志是全天连续滚动写入的,一次会话的完整链路经常横跨整点边界,22:59 进来的消息,23:01 才走到校验,按小时框窗口必然把同一会话的记录截成两半。时间窗会把单会话翻车对折,这不是建议,是取证工具的物理属性。所以后面所有统计,一律按会话和消息归拢,时间窗只用来看节奏,不用来做计数