跳至主要内容
AI 产物的验收标准得由产品来定

AI 产物的验收标准得由产品来定

上线评审上,有人报了一句「准确率九十二」,会议室安静了几秒。没人说能上,也没人说不能上——因为从头到尾没人定义过及格线在哪。后来这个功能还是发了,靠的是负责人拍板,不是靠评估结果。

我一直记着这个场面。它让我明白,AI 产品的验收不是测试环节的延伸,而是一个提前做的决定:我们接受哪种错,接受多少,错了以后谁来接。

确定性的东西和概率性的东西不是一套验收

传统功能可以验收,因为它有确定的输入输出。登录按钮点下去,要么跳转,要么报错,验收就是穷举路径。

模型不是这样。它给的是分布,同一句输入多跑几次可能给出不同的回答,测试集上的表现也不等于线上。所以「有没有 bug」这个问题在这里失效了,能问的只剩「错到什么程度还算能用」。

这个转换听着简单,做起来很别扭。因为它要求产品在还没有数据的时候就先说一句:这条业务线能容忍多少错。客服机器人答错一句可以重问,医疗或者合同的场景答错一次就没有第二次。同一个模型,两套及格线。

我见过不少团队在这里偷懒,把及格线交给算法同学定,理由是「他们更懂指标」。指标他们确实更懂,但错误的代价只有业务侧清楚。这两件事分开以后,验收就退化成了看跑分。

我自己会把验收拆成三层来看,但排序是从上往下定、从下往上验。

最上面是业务能不能成立:这个功能上线以后,有没有人真的用,用完之后那个卡住的环节有没有松动。中间是体验:它错的时候,用户能不能察觉、能不能纠正,纠正的成本高不高。最下面是技术指标:测试集上的表现、延迟、失败率。

这三层里,最容易量化的是最下面那层,也最容易被当成全部。我参加过一些评审,整页都是准确率和召回率,没有一行写「用户会怎么遇到这个错」。这样的评审过与不过,其实都不说明问题。

测试集是我少数能自己动手的地方

模型训练我插不上手,推理优化我也不懂,但测试集是我能真正负责的部分。

我比较反感直接拿验证集当验收集。验证集是从训练数据里切出来的,分布和训练同源,天然偏乐观。真正该用的是另一套东西:从真实日志里抽,保留错别字、口语、前后矛盾,还有那些用户自己都没说清楚的模糊指令。

抽样也不是随机的。核心高频场景要占大头,长尾要留出足够的位置,历史上出过事的案例要单独收一份。我自己的习惯是给这几类各留一个独立的小集合,跑分的时候分开看。合在一起看总分最省事,也最容易掩盖问题——一个在长尾上崩掉的版本,可能因为高频场景撑住了,总分依然好看。

这套东西做起来很枯燥,要人工标注,要反复对齐口径。口径这件事比想象中重要:同样一条回答,两个人一个判对、一个判错,往往不是谁错了,是他们对「对」的定义不同。所以标注之前得先把标准写成几句话,遇到边界情况再补,补完回头重标一批。不做这件事,测试集本身就是一个新的噪声源。

样本量也值得说一句。几十条样本跑出来的差异基本没有意义,尤其是生成式任务,同一个版本跑两次结果都可能不一样。要么把样本量堆到几百条,要么接受「这次改动没有可测出的影响」这个结论,而不是从一个点的波动里读出一个趋势。

生成式任务还有一个额外的麻烦:没有唯一答案,就没法逐字比对。我试过几种替代方式。语义相似度能判断意思是否接近,但对「数字错了」「引用编造了」这类问题不敏感,两句话向量距离很近,事实却完全相反。用模型当裁判更灵活,能按维度打分,但裁判本身也有偏好,换一个模型排序就可能变。我现在的做法是把两者混着用,再用一小批人工标注校准裁判,看它和人的判断偏离多少。这套东西远不完美,但比一个孤零零的准确率可信。

坏案例要靠归类修,不靠逐条打补丁

刚接触这类产品的时候,我的处理方式很原始:用户报一个错,我就让算法改一个。改完看起来好了,过两周另一个场景又坏,而且坏得更隐蔽。

后来才想明白,单点修复在这个系统里几乎必然引发别处的退化。调了语气让它更活泼,严肃投诉的场景就开始显得轻浮;放宽了安全过滤,误伤少了,真正的恶意输入也开始漏。

所以我现在看坏案例,第一件事是归类,而不是修。

  • 数据里根本没有这类样本,模型没见过
  • 知识有,但表达或格式跑偏,通常是提示词和上下文组织的问题
  • 能力边界,这类事它本来就不该做

这三类的处理方式完全不同。第一类补数据,第二类改提示词或者加约束,第三类只能靠产品设计绕开,比如接一个计算器、接一个检索。最怕的是把第三类当第一类治,投入很多,最后发现方向就错了。

有个例子我印象很深。用户问怎么结束一个进程,模型拒绝了,理由是「不能提供伤害性建议」。这是典型的误报:过滤器只看到了词,没看语境。归类上它属于第二类,提示词里没有说清楚技术语境和现实暴力的区别。改法是加约束,不是补数据。

但改完还得验证另一头。放宽之后,真正询问暴力的输入是不是还能拦住。如果只测被修好的那一条,就等于用一个漏洞换另一个漏洞。这类回归测试在安全相关的功能里不能省,因为它的失败代价不是体验差,是事故。

归类之后还有一步,跑回归。修一个案例不算修好,得确认原来那批好案例没有被连带弄坏。这一步很多团队会跳过,因为慢。但跳过它的代价,通常在下一次发版时一次性还回来。

上线只是验收的后半段

我很不喜欢「验收通过,发布上线」这种说法,它暗示验收是一个有终点的动作。

模型上线以后,用户会用它没见过的说法提问,业务规则会变,上游模型供应商会悄悄更新版本。这些都不在测试集里。上线前跑得再好,也只能覆盖当时想得到的部分。

所以验收里必须包含退路:置信度低的时候转人工,服务不可用的时候降级到规则,出问题时能在几分钟内回滚。这些不是加分项,是让我敢点发布的前提。一个没有退路的模型,就算指标再漂亮,我也不会签字。

退路之外还有节奏。灰度发布的意义不是形式,是把「全量用户一起踩坑」换成「一小部分人先踩」。灰度期间要看的也不是总分,是错误类型的分布有没有变化——有些问题在全量之后才会显形,因为流量结构变了。

至于指标本身,我现在越来越不信任单一的准确率。它太容易被样本分布哄住。真要判断,我会同时看两类东西:模型侧的错误类型分布,和业务侧的采纳、修改、放弃。前者告诉我它怎么错,后者告诉我这些错有没有被人接住。

这两者不一致的时候,我倾向相信后者。模型说它答对了,用户却把答案整段删掉重写,那这次就是失败,不管跑分多少。

成本也要算进去。为了两个点的提升换更贵的模型,值不值,取决于这两个点落在哪。如果落在高频路径上,可能值得;如果落在几乎没人走的长尾上,那就是在为一个漂亮的数字付钱。这种判断没有公式,只能回到业务里看。

上线之后的反馈怎么回来,也要在设计时就定。用户点踩、直接修改、关掉窗口,这些行为如果不记录,就等于每次迭代都从零开始。我比较在意的不是收集多少数据,而是收集回来的东西能不能对应到具体的问题类型——一条「不满意」没有信息,一条「答案引用的是过期文档」才有。

我暂时还没有一套能套用到所有场景的验收模板。每个业务对错误的容忍度不一样,能拿到的数据也不一样。能确定的只有一点:及格线得由对结果负责的人来画,画完还得愿意为它承担后果。

关于本文

由 Lu's Blog 撰写,采用 CC BY-NC 4.0 许可协议。

#AI 产品 #评估 #验收

评论