一家做在线客服的团队遇到过一个不大不小的麻烦:系统把某位用户的申诉自动转给了人工,运营想知道为什么。工程师打开日志,看到的是一串分数。分数能回答“多少”,回答不了“为什么”。于是有人提议,加一个解释模块。
这个提议听起来顺理成章,真正做起来却常常卡在第一句话上——解释是给谁看的。
三种“为什么”,不是同一个问题
运营想知道下次怎么改流程,工程师想知道输入里哪一段起了作用,用户只想知道自己有没有被草率对待。这三个问题指向不同的输出形式,也很难用同一份说明同时满足。不少团队在动手前没把这件事拆开,做出来的面板谁看都觉得差点意思,问题往往不在技术选型,而在提问本身没定义清楚。
事后归因给出的是一种近似
常见的做法是事后归因:遮住一部分输入,观察输出怎么变化,再把这些变化折算成特征的重要程度。这类方法描述的是模型行为的一个侧面,并不等于模型内部的推理路径。参数完全不同的两个模型,可能给出长得几乎一样的归因图。因此把归因结果直接讲成“模型的想法”,容易说过头。更稳妥的表述是:在这个输入上,这几处特征对结果的影响比较大。
还有一条更朴素的路径:换用本身结构就好读的模型,或者把复杂模型限制在边界清晰的场景里。它牺牲了一部分表达空间,但省掉了“解释和原模型对不上”的长期麻烦。可解释性在这里不是附加功能,而是选型时就要付的代价。
把它当成交付清单上的一项
我倾向于把可解释性从研究话题挪到工程验收里。具体可以落到几件不漂亮但管用的事上:
- 先写清楚这份解释要回答哪个问题、谁来看、用来支持什么决定;
- 固定输出形式,是特征贡献、是对比样例,还是一句自然语言,不要混着来;
- 把解释和当次输入、模型版本绑在一起留存,事后能复现;
- 定期抽查,拿一批已知答案的输入去问,看解释会不会自相矛盾。
这些动作挡不住所有问题,但能过滤掉大部分“看起来很有道理、实际没法用”的情况。
也要承认解释不了的地方
边界需要提前说清楚。模型规模大到一定程度之后,要给出既忠实于模型行为、又能被人读懂的说明,目前没有通用办法。这不是工程没做好,而是问题本身难。更现实的目标是“够用”:在需要有人担责的环节,解释要能支撑一次复核;在无关紧要的环节,不必强求。把这两类场景分开,争论会少很多。
回到那个客服工单。后来他们没做花哨的解释面板,只是在转人工时附上三条最相关的原文片段,运营扫一眼就知道该改哪条规则。可解释性在这里不是模型能力的展示,而是一条能走通的路径——从“系统这么做了”走到“我可以据此做点什么”。