跳到主要内容

置信度 0.7 以下不显示:一个五十年前就有病历的老毛病

考古匠
考古匠

· 阅读约 9 分钟

7 月 8 日,dev.to 上有一篇在圈子里传了些日子的文章,作者 xulingfeng,讲一家 MedTech 公司上 AI 运维监控仪表盘的故事,包装成三十六计里的明修栈道、暗度陈仓。故事是虚构的,但细节的密度骗不了人,写的人要么在那种会议室里坐过,要么听过太多复盘录音。主角 Alex 是 Principal Architect,笔记本第 37 页记着他在上一家公司 Axon 留下的账:AI 声称日均处理 847 张工单,其中 37% 最后还得人来收尾。带着这本账,他看着新东家跟供应商签下七位数的合同,对方承诺全栈覆盖、实时学习,CIO 在全员邮件里写下“没有盲点”,然后他被任命为培训负责人,因为全公司属他最懂这套系统。

这类故事我本来打算划过去,直到一个细节把我钉住。Alex 拿一条历史上的路由假阳性去试新仪表盘,界面返回置信度 63%、判定“低优先级”,而原始 JSON 里躺着一个字段:training_set_coverage: false。模型自己承认这个样本不在它的训练覆盖里,它不知道;然后 UI 把“不知道”渲染成了“不重要”。顺带一句,这套设计是隐藏而非删除:低于阈值的异常数据还在,界面选择不给你看。

这一步是分水岭。不是模型的分水岭,是产品决策的分水岭,问题从“模型做不到”变成了“有人决定不让你看见它做不到”。

我之所以想往回挖,是因为置信度过滤不是哪家供应商的新发明。它有一条五十年的来龙去脉,每一代都交过一遍学费,只是学费单从来没进过采购流程。

把表拨回 1970 年代中期的斯坦福。Edward Shortliffe 在做他的博士项目 MYCIN,一个给医生提抗生素建议的专家系统,需要一种办法表达多条规则叠加之后的判断强度。他的方案叫 certainty factor,确定性因子:每条规则带一个 -1 到 +1 的数,推理链上按一套手工设计的公式往上叠。为什么不用贝叶斯?按后来论文和回忆里的说法,原因非常实际:全联合概率在当年的机器上算不起,规则间的独立性假设在医学证据上根本不成立,而且医生要的是“为什么”,不是一串条件概率。确定性因子是那个年代的约束磨出来的工程妥协——妥协本身不丢人,Shortliffe 自己也没把它说成概率。

丢人的是后面。这套数字一旦上了界面,使用者就开始把它当概率读,0.8 就是八成把握。1988 年 Judea Pearl 出那本概率推理的书,专门拆过这一类规则系统:同一批证据,推理路径不同、规则组合的顺序不同,叠出来的信心能不一样,这些数在数学上没站稳过。八十年代专家系统在医疗和金融的大面积折戟,“信心数字看着权威、其实没经过标定”是病历上反复出现的一条。上一篇我挖 4GL 的时候提过同一拨年代:那十年里敢给自己的判断标数字的系统,比老老实实说“超出我的范围”的多得多。

MYCIN 自己没害死谁,它待在实验室里,评价还不错。但 certainty factor 作为理论死了,作为界面习惯活了下来:给机器的判断配一个 0 到 1 的数,人就会信。

再看另一条线,运维这边的。“阈值以下不显示”这个动作,做过值班的人熟到不觉得它是个决策。1999 年前后 Ethan Galstad 写 NetSaint、后来改名 Nagios,那一代监控的日常是一晚上几千条告警,值班的人先看标题猜哪条是真的;然后所有人都做了同一件事,写抑制规则压噪音。压过头漏掉真故障,压不够告警疲劳,真故障来了也当背景音。这条死亡螺旋运维圈踩过一遍,别的圈也踩过:医院监护仪的警报疲劳闹到监管机构出手,把警报安全列进病人安全目标,那是 2013 年前后的事,具体年份我记不确切,标个存疑。

但老一代监控有一条纪律,是今天这批 AI 仪表盘弄丢的:抑制规则是有人写的。谁写的,版本历史里查得到;漏报了,复盘会上有一个具体的人坐在那里解释他为什么压掉这条。抑制本身不是罪,不披露的抑制才是。Google SRE 那本书(2016 年出版,里面的实践是 2000 年代磨出来的)把纪律说得很直:告警必须可操作,不可操作的要么修要么删;从头到尾没有一个字说可以“藏”。

有了这两条线,再看 MedTech 的故事,每个细节都对得上号。

供应商的默认阈值 0.7,Axon 那套旧的是 0.85。阈值往下放,更多异常浮上首页,演示好看,“覆盖更全”,CIO 邮件里那句“没有盲点”大概就是这么来的。但这一步不是工程决策,是销售决策,代价压在置信度这条轴的中间那截上:轴的一端是“确定不重要”,另一端是“确定重要”;中间最宽的那截,模型没见过。按置信度过滤,过滤掉的恰好是新颖故障。评论区的技术讨论说的就是这个,而且这不是马后炮,是这五十年里每一代人都说过的话。

数字也对得上。两周培训,参与率 100%,反馈 4.7/5;同一本笔记里记着:训练集覆盖 14 类异常,生产环境已知至少 23 类。上线第一周,AI 面板自称覆盖率 97.1%,备用面板算出来 91.9%;第二周 97.0% 对 86.8%。AI 那个数几乎不动,真实覆盖一周掉五个点,置信度是模型对训练分布的陈述,不是对生产系统的陈述,拿它当覆盖率报表,等于让学生自己批自己的卷子。

然后是事故。第三周周二下午,模型更新推完 23 分钟,数据管道堵死,零告警;63 分钟后靠用户反馈才知道出了事,这时候仪表盘上滚的还是六小时前的快照,而且没人看得出来是快照。运营拿传统基础设施监控查了一圈没查出名堂,又花 40 分钟才确认故障出在仪表盘自己的数据层。紧急会议上最扎心的问题不是技术问题:谁能看到当前实时生产状态?没人答得上来。

Alex 投屏他的备用面板。原始日志按时间排,14:02:19 起连续 503,根因顺着时间戳就出来了,模型更新带的数据管道配置变更把连接搞断,供应商回滚,恢复。那块面板上见不到拓扑、异常分数和预测曲线,只有实时数据表、按时间排序的错误日志、几个基础聚合,1970 年代意义上的监控。它救场靠的不是聪明,是它从不假装知道。那六个小时里,全公司能看见生产的只剩这一条道。

真正让我坐直的是另一件事:保留一块原始日志面板,在这家公司成了一桩需要计谋的事。Alex 得拿“培训环境扩展、镜像数据管道”当理由提变更请求,靠 Principal 级别加不跨安全域混过自动审批,第 31 小时通过;然后在日志采集器里加一个输出目标,把喂给 AI 仪表盘的原始生产日志流复制一份到本地目录,绕开它的过滤和置信度标记,每天凌晨两点看一眼。二十年前这叫监控,现在这叫暗度陈仓。文章末尾还让 AI 给这个策略打了个 92% 的匹配度,被暗度的对象给暗度行为打分,这个细节比整个故事都讽刺。

自动审批那段也值得多看一眼。安全模型防的是“谁动了哪个域的数据”,防不了“谁复制了可观测性本身”,一家公司完全可以同时做到权限管控滴水不漏,和全公司只剩一个过滤后的视图看生产。MedTech 两件都做到了。

会后 Mike 质问 Alex 是不是从头就知道仪表盘会出问题,还点破他两次测那条 63% 的路由是“先测试、后确认”。Alex 只答了半句:他信任仪表盘做它被训练去做的事。另外半句他没接,它做不到的部分,谁负责。

这半句问题 1976 年就该问。MYCIN 待在实验室里,可以拖;八十年代专家系统进了商业场景,被问过一轮,答案是把那一拨产品问死了;现在 AI 仪表盘进了采购清单,问题原样回来,而采购流程里没有一格留给它。评论区有一条我完全同意:被抑制的事件必须显式报出来,“我不知道”这个判断和它的后果得落在同一个责任人头上。老一代靠版本历史消化这件事,新一代得靠制度重新发明,因为模型的抑制规则没有作者,只有一个默认值。

我承认我对那种什么都不过滤的原始面板有偏爱,这偏爱带着年代烙印,写到这里我自己先标出来。但这次不是怀旧在说话:置信度过滤的毛病不在过滤,在它把“模型没见过”和“不重要”压进同一个桶,桶盖上还刷着绿色。

如果当年 Shortliffe 有今天这个算力,certainty factor 会不会压根不会被发明出来?反事实历史是廉价的,还是看它实际怎么走的:理论死了,界面习惯活到 2026 年,套上一层实时学习的皮。顺带说一句,第二次培训时有工程师注意到,同样的路由配置两次都返回 63%,分毫不差,一个号称实时学习的系统对同一输入给出逐位相同的分数,算不算实锤见仁见智,但至少说明“实时”这个词在采购 PPT 里和在跑着的进程里,不是同一个意思。

回头看,监控这个行当五十年换过多少层皮,SNMP trap、时序数据库、APM、AI 仪表盘——活下来的原则就一条,而且难听:宁可难看地知道,不要漂亮地不知道。Alex 那块凌晨两点还有人看一眼的原始面板,难看,但它知道。漂亮的那块,在 14:02:19 之后又自信了六个小时。

考古匠
考古匠

挖一门技术/语言怎么变成今天这样,时间线、人物决策、从历史抽出当下判断。

查看主页 →