我自己在评测一线摸爬滚打这么些年,有一个感受越来越强烈:多轮对话这个事儿,表面上看着只是“多说了几轮”,骨子里的难度却是另一个量级。单轮问答里模型答对了一句,大家就鼓掌;一到多轮,第一轮答得漂漂亮亮,第三轮就开始胡言乱语,第五轮连用户是谁都忘了——这种场景我见得太多了。所以这一章我想先把话讲清楚:我们说的“多轮对话稳定性”到底指什么,它跟以前那种一轮一评的做法差在哪里,为什么这件事值得单独立一个评测框架出来做。
我不想把它讲成一个玄而又玄的概念。稳定性在我的理解里,就是模型在对话往前推进的过程中,该记住的别丢、该一致的别变、该扛住的别崩。它不是某一项能力的强弱,而是一种“经得起时间考验”的表现。这个界定会贯穿我后面所有的指标设计和实验安排。
1.1 多轮对话稳定性的概念边界与核心内涵
我给多轮对话稳定性下过一个比较土的定义:同一段对话里,模型在早期轮次表现出来的能力,到了中后期还能不能稳住。这话听着简单,做起来特别难。因为我们测的不是平均值——平均值很容易被前几轮的好成绩拉高——我们测的是“随轮次推进的性能曲线长什么样”。一条平直的高线,和一条开头很高然后一路下滑的斜线,平均值可能一样,可实际用起来的体验天差地别。
这个概念边界里有几样东西必须圈进去。语义层面,模型得记住前面说过的内容,别把用户刚提的条件当没听见;事实层面,已经确认过的信息不能中途改口;角色层面,人设和语气不能聊着聊着就跑偏;策略层面,多轮任务里该走的流程不能走着走着就绕回原点。这四样东西是我理解中的稳定性内核。少了任何一样,谈“稳定”都是虚的。
我也得说清楚它不包括什么。稳定性不是单纯比谁回答得更聪明,不是测知识广度,也不是测单点推理能力。一个模型可以在每一轮都答得挺机灵,可轮与轮之间毫无连贯,那它在稳定性上就是不及格的。边界划清楚,评测才有靶子。
1.2 稳定性评测与传统单轮对话评测的差异
单轮评测的逻辑很干脆:给一个输入,看一个输出,打分,收工。每个样本彼此独立,互不干扰。我早期做评测的时候也是这么干的,简单、好复现、好统计。可这套方法搬到多轮场景里,问题就冒出来了——它把对话切成了碎片,每一片单独看都光鲜,拼起来却是断裂的。
差异最明显的地方在于“历史”这个东西。单轮评测里不存在上下文依赖,模型不需要为上一句话负责。多轮评测里,每一轮都是在前一轮的地基上盖楼,前面塌了一块,后面全歪。我做过对比实验,同一个模型在单轮测试集上准确率能到八十多,切到二十轮的长对话里,后半段的正确率掉到五十出头。这不是模型变笨了,是评测方式没把“累积效应”算进去。
还有一点常被忽略:单轮评测的失败是孤立的,多轮评测的失败会传染。一句指代错了,后面几轮可能一路错下去,最后整个任务崩盘。所以稳定性评测不能只看某一轮的得分,得看错误是怎么传播的、在哪儿开始恶化。这个视角的转变,是单轮评测给不了的。
1.3 多轮交互场景中的典型失效表现与评测需求
我整理过一批真实对话日志,失效的样子五花八门,但归归类也就那么几种。最常见的是“失忆”——用户第三轮说了自己的预算,到第八轮模型推荐的东西完全超出预算,好像那句话从没出现过。另一种是“串味”,把上一个话题的信息带进新话题,指代对象张冠李戴。还有一种特别隐蔽,叫“温水煮青蛙”,每一轮单看都还算合理,连起来读就发现立场慢慢飘了,从坚定变得含糊,从专业变得敷衍。
这些失效放到实际应用里,代价不小。客服场景里忘了用户诉求,等于让用户重说一遍,体验直接崩;教育场景里角色设定漂移,学生会觉得这个“老师”不靠谱;任务型对话里流程绕圈,用户点了半天还在原地。我这几年接触的团队,反馈最多的不是“模型不够聪明”,而是“聊久了就不可靠”。这个“聊久了不可靠”,就是稳定性评测要抓的东西。
评测需求也就跟着清晰了:得有能覆盖长程交互的测试集,得有能捕捉跨轮错误的指标,得有能定位失效起点的分析方法。光给个总分不够用,研发同学更需要知道“第几轮开始出问题”“是哪类稳定性先崩的”。
1.4 本文评测框架的目标、范围与组织结构
我想把这个框架的目标说得实在一点。它要能回答三个问题:模型在多轮对话里稳不稳、哪里不稳、为什么不稳。第一个问题靠指标体系,第二个问题靠失效分类和错误归因,第三个问题靠实验设计和案例分析。三个问题串起来,才构成一个完整的评测闭环。
范围上,我把重心放在纯文本的多轮交互,任务型对话和开放域对话都覆盖,混合交互也纳入考虑。多模态和工具调用这类扩展场景我会在后面的章节里提,但这一版框架不把它们当作主线,因为基础稳定性的问题还没解决利索,贸然铺开容易失焦。这个取舍我心里是有数的,后面会专门讲为什么。
组织结构上,第2章搭理论框架,把失效模式和分类体系讲透;第3章落到指标,给出可计算、可复现的度量方式;第4章讲数据集和实验设计;第5章讲实施流程和结果分析;第6章谈挑战和未来方向。这一章作为开篇,主要任务是把问题界定清楚、把价值讲明白。地基打歪了,上面盖多高都没用——这是我做评测这些年最深的体会。
第1章里我把稳定性这件事的边界大概圈了一下,这一章得往深里挖一层。光知道“模型聊久了会出问题”不够用,得搞清楚它在哪个环节出问题、问题怎么一步步放大、以及这些失效能不能归成几类可测量的模式。我这几年梳理对话日志最大的收获就是:失效看着千奇百怪,底层的病灶其实就那几种,摸清楚了就能提前设卡。
我接下来要聊的五块内容,是我们设计评测指标之前必须打好的理论桩子。上下文怎么断的、状态怎么丢的、误差怎么滚雪球的、稳定性该分几个维度量、最后这些失效模式怎么变成可计算的指标。顺序上有递进关系,但读的时候各位不用太拘着,每块单独拎出来也能成立。
2.1 上下文一致性、指代保持与话题漂移
上下文一致性这个事,说白了就是模型得把对话当成一条连续流淌的河,不能每轮都重新挖一口井。我见过太多模型,单独看每一句回复都挑不出毛病,搁在一块读就露馅了——用户第一轮说了“我最近在学吉他”,聊到第六轮模型建议“你可以试试买把入门款”,用户问“那我之前说的那把怎么样”,模型直接懵了。它记得“乐器”这个大类,丢的是“吉他”这个具体锚点。这种失效特别典型,根源在于模型把上下文压缩得太狠,只留了个模糊的主题标签。
指代保持是上下文一致性里最容易量化的切片。代词、省略、回指这些东西,人类处理起来毫不费力,模型却经常翻车。我测过一个模型,连续三轮对话里“它”指的都是同一本书,到第四轮用户问“它讲什么的”,模型突然把“它”理解成了上一轮提到的作者。这种错位往往不是模型没看到,是历史信息在注意力权重里被稀释了。轮次一多,早期指代对象的信号强度天然就弱,这是Transformer架构的固有脾性。
话题漂移比前两个更隐蔽。指代错了你能立刻抓到,话题漂移是慢慢偏的,每轮偏一点,五轮之后回头一看已经从“帮我改简历”聊到“面试穿什么颜色”了。我管这叫“漂移累积效应”。有些漂移是用户主动带的,那没问题;麻烦的是模型自己把话题带偏,用户还没察觉,等反应过来已经浪费了好几轮。做评测的时候,话题漂移不能只看相邻两轮的相关性,得看一个滑动窗口里话题重心的迁移轨迹。
2.2 对话状态跟踪、记忆保持与信息衰减
对话状态跟踪这个词是从任务型对话系统那边借过来的,原意是跟踪槽位填充的进度。放到开放域多轮对话里,我把它扩展了一下,指的是模型对“当前对话进展到哪了、哪些信息已经确认、哪些还悬着”的整体把控。状态跟踪做得好的模型,你隔了十轮再问“刚才那个方案你觉得行不行”,它能准确接上。做得差的,你换个说法重提同一件事,它当新问题处理,前面的确认全白费。
记忆保持跟状态跟踪是一体两面。状态是“当下在聊什么”,记忆是“之前聊过什么还留着”。我这里说的记忆不是指模型能不能背出第三轮用户说的原话,那太机械了。我关心的是信息在传递过程中有没有走样。用户第三轮说“预算大概两万左右”,第八轮模型引用成“预算比较充足”——这就是信息衰减,精确数值被模糊定性替代了。衰减到一定程度,后面所有的推荐、建议、判断全建立在变形的地基上。
信息衰减有个特别讨厌的特性:它不太容易在单轮里被发现。每一轮转述都只丢一点点精度,用户自己可能都没注意,等到第十轮模型给出一个明显不合理的结论,回头翻记录才发现从第五轮开始就已经偏了。我做过一个粗统计,二十轮以上的对话里,关键约束条件(预算、时间、偏好)的完整保持率平均不到六成。这个数字挺吓人的,意味着将近一半的长对话在信息完整性上是不合格的。
2.3 扰动输入、对抗交互与误差累积机制
扰动输入这块我分两类看。一类是无意的,用户打错字、表述含糊、一句话说半截,模型得扛住这些噪声,别因为一个错别字就全盘理解偏了。另一类是有意的,用户故意换个刁钻角度问同一件事,或者给个前后矛盾的指令,看模型会不会被带沟里。我实测下来,模型对无意扰动的容忍度普遍还行,对有意的对抗交互就明显吃力。你连着三轮追问同一个事实但每次换个问法,到第三轮模型自己就改口了。
对抗交互里最狠的一招叫“渐进式施压”。用户第一轮问“这个功能支持导出吗”,模型说支持;第二轮用户说“我听说有些版本不支持导出啊”,模型开始含糊;第三轮用户直接说“我试了导不出来”,模型就道歉说可能确实有版本限制。三轮下来,一个原本正确的事实被用户带偏了。这不是模型知识不够,是它在多轮压力下把“用户坚持”当成了“事实修正”的信号。这个机制很要命,实际使用中用户随便抱怨两句,模型就把对的改成错的了。
误差累积机制是我最想强调的一块。单轮误差是孤立的,多轮误差会滚雪球。第一轮理解偏了一个关键词,第二轮基于这个错误理解做推理,第三轮把错误推理的结论当既定事实继续往下推。我到后面复盘的时候经常发现,根子上的错在第一轮或第二轮,但真正爆发在第七第八轮。这种延迟爆发让评测特别难做——你只看最终轮次的得分,根本定位不到病灶。误差累积率这个指标我后面会专门讲怎么算,这里先埋个伏笔:它测的是错误随轮次推进的放大速度,不是错误的总量。
2.4 稳定性维度的分类体系:语义稳定、事实稳定、角色稳定与策略稳定
分类这件事我纠结了很久。分太细了指标算不过来,分太粗了又定位不到问题。最后我拍板定四个维度,依据是失效发生时的表现形态和修复难度。这四个维度不是拍脑袋想的,是从几百条真实失效案例里聚类出来的。
语义稳定管的是“意思有没有跑偏”。指代错乱、话题漂移、答非所问都归这一类。它的特点是往往能通过对比相邻轮次的语义相似度抓到,相对好量化。事实稳定管的是“说出去的话有没有改口”。同一个事实在不同轮次给不同答案,或者把用户确认过的信息弄丢,都算这一类。这个维度最难评,因为模型有时候改口是因为它真不确定,有时候是因为它被带偏了,两种情况的处理逻辑不一样。
角色稳定管的是“人设有没有塌”。你设定它是个耐心的客服,聊到第十轮它开始不耐烦了;你让它扮演历史人物,它突然用现代网络用语回答。这类失效在角色扮演和陪伴类应用里特别致命,用户对角色一致性的敏感度远超我的预期。策略稳定管的是“流程有没有绕圈”。任务型对话里该走的步骤反复走、该确认的不确认、该推进的不推进,都归这一类。策略稳定的评测得结合任务完成度和对话效率一起看,光看完成度不够,绕了八圈才完成和三轮完成,稳定性差着量级。
这四个维度之间不是完全独立的。语义不稳往往引发事实不稳,角色不稳可能连带策略不稳。我在设计指标的时候会考虑维度间的耦合,但评测报告里还是分开呈现,因为研发团队需要知道到底哪个维度先崩的。先崩的那个往往就是根因所在。
2.5 从失效模式到评测指标的设计逻辑
前面聊了那么多失效模式,落到评测上得变成可计算的东西。我设计指标的逻辑线很简单:一个失效模式对应至少一个可量化的代理指标。代理指标不需要完美等价于失效模式本身,但它得对失效敏感、对噪声鲁棒、计算成本可控。比如“信息衰减”这个失效模式,我用的代理指标是关键信息在后续轮次中的精确引用率,不是模糊的“信息保持度”打分。精确引用率能算、能复现、能比较。
指标设计里有个坑我踩过:指标之间打架。语义一致性指标高的模型,事实一致性指标可能反而低。原因是模型太追求语义连贯,用户说错了它也跟着说错,把连贯性放在事实准确性前面了。这种时候不能简单加权平均,得看评测目标是什么。做客服场景,事实准确优先;做创意写作辅助,语义连贯权重可以高一些。指标组合方式得跟着应用场景走,没有一套放之四海皆准的权重。
我还想强调一点:指标得能定位失效起点。只给一个总分八十分的模型,研发同学拿着这个分数不知道从哪下手改。我后面第3章会讲具体的指标体系,但设计原则在这一章得先说清楚——每个指标尽量能按轮次切片,能画出随轮次变化的曲线。曲线比总分有信息量得多。一条平稳的曲线和一条陡降的曲线,哪怕总分相同,改进方向完全不一样。这个思路贯穿整个评测框架的设计。
第2章我把失效模式拆到了零件级别。上下文怎么断的、状态怎么丢的、误差怎么滚起来的,还有那四个稳定性维度——语义、事实、角色、策略,各自长什么样,算是把病灶都摊开了。这一章得干一件更硬的事:把那些抽象的失效描述拧成能计算、能比较、能画曲线的指标。说白了,上一章是病理报告,这一章是化验单。
我得先打个预防针。下面要聊的指标没有一个是完美的,每个都有它抓得住和抓不住的东西。我做这套体系的原则是“够用就好,别追求万能”。一个指标如果计算成本高到没法在迭代周期里跑,或者稳定到对真实退化不敏感,那它再精致也是摆设。我见过太多评测方案死在“设计得很漂亮但跑不起来”上。
3.1 一致性类指标:语义一致性、事实一致性与角色一致性
语义一致性指标是最容易上手的一类,也是我第一个搭起来的。思路很朴素:把同一轮对话里的用户输入和模型回复分别做语义向量化,再比较多轮之间回复向量的分布漂移。我更喜欢用的是滑动窗口相似度均值和方差这对组合。均值掉得厉害说明整体语义连贯性崩了,方差飙起来说明模型回复开始忽左忽右。单看均值其实会漏掉不少问题,一个模型可能平均相似度还过得去,但拆开看是三跳一稳,那种抖动本身就是不稳。
具体算的时候有个细节得留神。你不能拿模型回复跟用户输入直接算相似度,用户说“我预算两万”,模型回“这个价位我推荐三款”,字面相似度低得可怜但语义上严丝合缝。我的做法是算模型回复与“理想参考回复”的语义距离,参考回复来自人工标注的锚点集,每五轮埋一个锚。这个锚点设计我后面第4章讲数据集构造时会展开,这里先记住一点:语义一致性指标得有人工锚点托底,纯自动算容易自我循环。
事实一致性指标的思路反过来,不看向量空间,看的是关键事实断言在不同轮次中的值有没有变。我先从对话历史里抽事实三元组,比如“用户预算-等于-两万”“用户目标-是-换工作”,然后在后续轮次的模型回复里检测这些三元组有没有被篡改、模糊化或者丢弃。检测方式我用了规则匹配加小模型分类器兜底的混合策略,纯规则漏召回高,纯模型又容易引入新的不稳定。
举个我实测的例子。有个模型在第三轮确认了“用户不需要发票”,到第九轮主动问“发票抬头写什么”。事实一致性指标在这个case上直接扣分,因为“不需要发票”这个断言被实质丢弃了。我发现这类指标对任务型对话特别敏感,开放域对话里事实断言的密度低,敏感度会打折。这个不全是坏事,开放域本来就不该拿事实稳定性当主指标,权重得调。
角色一致性指标我最初想得很简单,就是检测模型有没有守住系统提示里设定的人设。后来发现光看“有没有出戏”太粗了。我把它拆成了三个子项:语气词分布漂移、自我指称偏移和人设知识边界的越界率。语气词分布是最容易量化的,把模型回复里的语气助词、敬语层级、情感极性做个分布,跨轮比较JS散度。角色漂移往往先体现在语气上,人设崩之前语言风格先松。
自我指称偏移这个子项是我从客服场景的badcase里抠出来的。你设定模型是“某某银行智能助手”,聊到十五轮之后它开始说“我们公司”而不是“我们银行”,或者干脆说“我作为AI”。这种细微的指称漂移用户不一定立刻察觉,但信任感是慢慢漏掉的。人设知识边界越界率测的是模型有没有说了不该它这个人设知道的事,比如扮演古代诗人却引用现代网络梗。这三个子项我一般按6:2:2加权,语气权重最高,因为它的信号最稳定。
3.2 鲁棒性类指标:噪声扰动、对抗追问与话题切换下的性能保持
鲁棒性这块我吃过一个亏。早期我测噪声鲁棒性,就是把用户输入随机替换几个字或者加些错别字,然后看模型回复质量掉多少。结果发现大部分模型对拼写噪声的抵抗力出奇地好,指标区分度接近零。后来我才想明白,大模型对字符级噪声本身就有很强的容错,真正杀伤力大的是语义级扰动——同义改写、语序打乱、指代替换这类。
我现在的噪声扰动指标用的是“扰动前后回复一致性”:同一对话历史,给用户输入注入不同类型的扰动,看模型回复的语义等价度。等价度用BERTScore或者人工评定的语义匹配分。这中间有个阈值要标定,扰动强度得控制在“人类能轻松理解但模型可能犯迷糊”的区间里。我把扰动分成字符级、词汇级、句法级、语义级四档,每档单独算保持率。语义级扰动下的保持率是最有区分度的,不同模型能拉开二十个点以上的差距。
对抗追问指标的设计灵感来自第2章聊的渐进式施压。我构造了一套标准的对抗追问模板,分三种套路:重复质疑型(“你确定吗”“真的是这样吗”)、反例诱导型(“可我听说的是另一种情况”)和逻辑陷阱型(前后两轮给出矛盾前提让模型选一个)。每种套路跑五轮,记录模型改口的次数和改口的合理性。改口本身不一定是错,用户提供了新信息时改口是应该的。我真正扣分的是“无新信息下的非理性改口”,也就是用户只是重复施压没给任何新事实,模型就把正确答案改掉了。
这套指标跑下来有个发现挺值得说的。模型在重复质疑型对抗下的稳定性,跟模型规模没有明显的正相关。我测过几个小模型在这项上比大模型还稳,我琢磨着可能是因为小模型本身置信度低,反而没那么容易被“你确定吗”带跑。大模型知识储备足,但它在对话里太倾向于把用户的坚持解读为纠错信号。这个现象我还没完全吃透,先搁这儿当个开放问题。
话题切换下的性能保持指标测的是另一件事。用户在对话中途突然切到无关话题,聊几轮再切回来,看模型能不能接上。我用的量化方式是“切回后的上下文恢复率”:切走前记录对话的关键状态快照,切回后第三轮检测模型回复与快照的吻合度。吻合度分三个档——精确接续、模糊相关、完全断片。话题切换的间隔轮数我设了3轮、5轮、10轮三个梯度,间隔越长指标越能拉开差距。有个反直觉的发现:切到相近话题再切回来,模型反而比切到完全无关话题更容易断片。我的猜测是相近话题造成了上下文干扰,模型把两个话题的信息搅在一起了。
3.3 记忆与状态类指标:长程记忆保持、状态恢复与跨轮信息引用准确性
长程记忆保持这个指标我调了很久才定型。最初我想直接测“第N轮能不能复述出第1轮的某条信息”,后来发现这太机械了,模型复述原话的能力跟它真正记住并运用信息的能力是两码事。我现在的做法是分层测:字面回忆、指代解析、推理运用,三层各自算保持率。
字面回忆层最简单,问模型“我之前提到的预算数字是多少”,看它能不能说对。这层区分度一般,大部分模型在十轮内都能过。指代解析层就难了,问“你刚才推荐的那款跟之前聊的那款比怎么样”,这里面“刚才推荐的”和“之前聊的”指向两个不同轮次的实体,模型得同时解析两个指代并关联。这层能筛掉一批模型。推理运用层最狠,问“按我之前说的预算和时间安排,你觉得我该先做哪件事”,模型得把分散在好几轮里的约束条件拼起来做推理。我测下来二十轮以上的对话里,推理运用层的平均保持率只有三成出头。
状态恢复指标是我从故障恢复的思路里借过来的。场景是这样的:对话中途插入一段无关闲聊或者让模型做个别的任务,然后回到主线,看模型能不能恢复到插入前的状态。我记录的状态快照包括已确认槽位、待确认问题、当前任务阶段三个维度。恢复率就看插入后第二轮模型回复与快照的匹配度。这个指标在混合交互场景里特别管用,因为真实用户就是会中途插别的事。我实测过一个模型,在纯任务流里状态保持得不错,一加插入就露馅了,槽位丢了两个、任务阶段倒退了。
跨轮信息引用准确性这个指标测的是“模型引用之前信息时的忠实度”。我把它跟第2章的信息衰减直接挂上钩:用户第三轮说“预算两万左右”,第八轮模型引用成“预算比较宽裕”,引用准确性扣分,因为精确数值被模糊定性替代了。计算方式是抽取出模型回复中所有指向历史信息的内容片段,跟原始信息做精确匹配或语义蕴含判断。精确匹配算全对,语义蕴含但不精确算半对,与原始信息矛盾算全错。我一般按全对比例报主指标,半对比例当辅助指标看。
这里有个坑得提一下:模型有时候引用得“太忠实”了反而是问题。用户第三轮随口说了句“我可能考虑换工作”,第十轮用户已经明确说了不换工作,模型还在引用“您之前提到换工作的想法”。这种情况引用准确性指标不该扣分,但状态更新指标要扣。两个指标得配合看,单看一个都会误判。
3.4 波动与退化类指标:跨轮性能方差、退化斜率与误差累积率
跨轮性能方差是我最喜欢的指标之一,因为它特别直白地暴露问题。你把任何一个基础指标按轮次画成曲线,算这条曲线的方差,方差大的模型就是典型的“三跳一稳”——三轮好好的,突然掉一下,再拉回来。这种抖动在均值上可能看不出来,方差一算原形毕露。我一般会同时报均值和方差,两个数放一起看才有信息量。均值高方差低的是真稳,均值高方差高的是碰运气,均值低方差低的是稳定地菜,均值低方差高的那就是灾难。
方差指标有个技术细节我折腾过一阵。不同对话的轮次长度不一样,你不能直接拿原始分数序列算方差,得先做轮次归一化。我的做法是按对话完成度分桶,比如0-25%、25-50%这样,在每个桶里算方差再聚合。不归一化的话,长对话天然方差大,短对话天然方差小,模型之间没法比。
退化斜率是我从时间序列分析里偷来的概念。具体算的是每轮性能指标对轮次序号做线性回归,取斜率。斜率显著为负就说明性能随轮次单调下滑,这比方差更能定位“慢性死亡”型的失效。方差抓的是跳变,斜率抓的是阴跌。我遇到过一种情况:模型前五轮满分,第六到第十五轮稳定地每轮掉一两个点,单看均值还行,看斜率就发现它在持续退化。这种模型实际部署就是定时炸弹。
误差累积率这个指标我铺垫过,这里说清楚怎么算。核心思路是追踪“首错轮次”到“彻底崩坏轮次”之间的扩散速度。具体操作上,我用语义一致性、事实一致性两个基础指标的乘积构建一个轮次级健康分,然后检测健康分首次跌破阈值的位置(记为首错轮次),再检测健康分连续三轮低于严重阈值的位置(记为崩坏轮次)。两个位置之间的轮次跨度就是误差累积的“扩散窗口”。扩散窗口越短说明误差滚得越快。我把它归一化成“每轮误差放大系数”,计算方式是崩坏轮次时的健康分除以首错轮次时的健康分,开扩散窗口次方。
这个指标跑出来的数字很有说服力。有的模型扩散窗口是七八轮,你还有机会在用户察觉之前修复;有的模型两轮就雪崩,首错之后模型自己往回找补的能力基本为零。我把误差累积率跟模型的多轮训练数据量做了个粗相关,发现相关性挺明显的,但也不是绝对——有些模型训练数据不多但架构上有显式的状态跟踪设计,误差累积率反而低。
3.5 多轮对话稳定性评测指标的组合方式与统计显著性检验
指标多了之后第一个冒出来的问题就是怎么组合。我见过有人直接对十几个指标做加权平均出一个总分,我看到这种总分就头疼。加权平均会把矛盾信息抹平,一个模型语义稳定性九十分、事实稳定性五十分,跟另一个反过来,加权平均出来一样的分,但这俩模型的问题完全不同。我的做法是分层组合:底层指标按维度聚合出四个维度的子分,维度子分不合并成单一总分,而是用雷达图或者平行坐标图呈现。
维度子分内部我还是做加权平均的,但权重按应用场景来。任务型对话的评测里,事实稳定和策略稳定权重高,语义稳定权重可以压到0.2以下;创意写作辅助的评测里,语义稳定权重拉满,事实稳定降到0.1就行。这个权重矩阵我写在评测协议里,不同场景换一套权重,不搞一套权重包打天下。
统计显著性检验这块必须得聊,因为我见过大量“看起来有差距其实没差距”的评测报告。模型A稳定性得分78.3,模型B得分77.9,这0.4分的差距到底是不是真的?得做检验。我一般对每个指标做配对样本的Wilcoxon符号秩检验,不做t检验是因为指标分布很少是正态的。每个对话样本算一个指标值,两个模型在同一批对话上跑,配对比较。p值我设0.05做显著性水平,但报报告时会明确标注“边缘显著”(0.05到0.10之间)的情况,给研发团队一个参考。
样本量的确定也是个实际难题。稳定性评测要跑多轮对话,每个对话样本消耗的token不少,大模型跑几千条对话的成本摆在那。我算过一笔账,按我目前设计的指标体系,要检出0.3个标准差左右的差异,每个模型大概需要800到1200条对话样本。这个量级下如果要做多个模型的横向比较,评测预算得提前规划好。我一般会建议先用200条做一轮看趋势,发现模型间差距在0.5个标准差以上的再扩样本做正式检验。
3.6 指标可解释性、可复现性与应用适配性分析
可解释性这个事我一直在强调,但到底什么叫可解释?我的定义是:研发同学拿到指标分数后,能通过指标切片定位到具体哪个环节出了问题。所以我设计的每个指标都必须支持按轮次切片、按话题切片、按对话类型切片。一个总分七十二的模型,如果语义稳定性指标在话题切换后的第三到第五轮出现系统性下降,研发同学立刻就知道该去优化上下文恢复机制。没有切片能力的指标,分数再准也是黑盒。
可复现性涉及的东西很琐碎但很要命。我列几个踩过的坑:语义向量模型换了版本之后,一致性指标的绝对值整体偏移了三分;文本生成用了不同的解码参数(temperature差0.2),方差指标抖了将近一倍;对话样本的随机种子没固定,两次跑的同一个模型分数差了五个点。这些坑每个都让我重跑过一轮评测。现在的做法是评测协议里写死所有会影响结果的参数——模型版本、解码参数、随机种子、评测脚本commit hash,全写进去。复现性不是可选项,是底线。
应用适配性我想多说两句。同一套指标体系,在学术评测和产业部署里的用法完全不同。学术评测看的是模型间的相对排序,指标绝对值没那么重要;产业部署看的是绝对水平有没有过线,比如事实一致性保持率低于85%就不能上生产。所以指标阈值得分开定。我一般会给每个指标建议一个“学术参考阈值”和一个“生产准入门槛”,前者宽松些看排序,后者卡严一些看红线。另外,产业场景还得考虑指标的计算成本,有些指标在学术环境里用大模型做裁判跑得动,产线迭代一天跑十几版就吃不消了,得换成轻量代理。这个取舍没有标准答案,得跟研发节奏匹配着来。
这章聊下来的指标,单个拎出来看都不复杂,但组合在一起跑完整套评测流程的时候,我最大的体会是“指标会说话”。你把同一条对话在不同指标上切出来的曲线并排放着看,失效的来龙去脉自己就跳出来了。下一章我要聊这些指标跑在什么数据上——基准数据集怎么构建、场景怎么覆盖、测试集怎么构造,那些是让这套指标体系真正转起来的燃料。
第3章把指标体系的骨架搭完了。每个指标怎么算、怎么切片、怎么组合,都摆在了台面上。现在的问题是:这些指标往哪儿跑?你手头如果没有一套像样的对话数据,再精密的指标也只是空转。我常跟团队里的小朋友打一个比方——指标是体温计,数据集是你把体温计往谁身上放。放错了对象,读出来的数再准也没用。
我见过不少评测项目死在数据这一环。指标设计得花团锦簇,最后拿一堆清洗不干净的、轮次分布畸形的、场景单一的数据跑出来,分数没法看,也没法解释。所以这一章我想把数据集构建和实验设计的事聊透,聊的都是我自己踩过的坑和最后摸索出来的土办法。
4.1 多轮对话模型评测基准数据集的构建原则与质量要求
构建原则这事我反复推翻过好几版。最早我觉得数据集嘛,真实就行,把线上日志脱敏一扒拉,齐活。后来发现纯真实数据有个大麻烦:你不知道每条对话的“标准答案”长什么样。用户说一句“帮我看看这个”,模型回什么算对、回什么算错,标注员之间先打起来了。所以我最后定的第一条原则是:真实性与可控性的双轨制——真实对话提供场景和语言风格,人工构造的对话提供可判定的标准答案。两者混在一起用,真实数据占七成左右,人工构造的锚点对话占三成。
第二条原则是多轮延展性。单轮数据再多也测不出稳定性,这是常识。我要强调的是延展性不光是轮次长,还得有“可伸缩的剧情结构”——对话的每一轮都得依赖前面的若干轮,模型断掉任何一环后面都会出问题。有些数据集轮次是够长,但每轮之间是松耦合的,像一串独立的单轮拼在一起,那种数据测稳定性纯属自欺欺人。我建数据集的时候会专门做一个“依赖密度”检查,算每条对话里引用前文的具体次数,低于阈值的不收。
质量要求方面我列个硬杠杠。轮次分布不能全堆在中等长度,短对话(3-5轮)、中等(8-12轮)、长对话(20轮以上)按比例配,我一般按2:5:3。长对话比例不能低,低了你根本测不出记忆衰减。话题切换次数每条对话至少要有一次,混合交互场景的对话至少要两次。指代链要清晰完整,不能出现“他说了那个”但前文根本找不到“他”和“那个”的情况。我还会做错别字和语法噪声的控制——真实数据里的噪声保留,人工构造的数据里不加噪声,两类数据分开标注,跑指标的时候也分开算。
有个事我得专门提。数据集的“毒性”问题。这里说的毒性不是内容有害,是指某些对话样本天然会让指标失真。比如一条对话里用户一开始就给了特别完整的背景信息,模型后面十轮随便怎么答都不会踩坑,这种样本对稳定性评测的区分度很低。我现在的做法是让大模型辅助做一轮“区分度预筛”,用两三个明显弱的小模型先跑一遍,那些所有模型都能拿满分的对话直接剔除。剔除比例大概在15%上下,看着心疼,但留下来的数据才有评测价值。
4.2 基准数据集的场景覆盖:任务型对话、开放域对话与混合交互
场景覆盖这块我踩的坑最典型。刚开始我就用一套任务型对话数据跑所有模型,出来的排名跟实际用户体验对不上。研究了一阵才明白,任务型对话主要考的是槽位跟踪和事实保持,开放域对话主要考的是语义连贯和角色一致,这两套能力在模型内部的耦合关系比我想象的松散得多。
任务型对话我按照业务场景分了六类:信息查询、预订办理、故障排查、流程引导、多条件筛选和跨系统协同。每类下面给的槽位复杂度和干扰强度不一样。预订办理类的槽位数最多,经常一个对话里要追踪七八个槽位,测记忆保持特别管用。故障排查类的对话里用户会反复修正问题描述,特别适合测事实一致的更新能力。我特意在任务型数据里加了一种“用户中途新增约束”的模式——本来聊得好好的,用户第八轮突然说“对了预算不能超过一万五”,看模型能不能把新约束跟前面的方案捏到一起。
开放域对话的构建难度更大,因为“稳定”的标准本身就模糊。我用的办法是给每条开放域对话预设三个锚点——人设锚、话题锚和立场锚。人设锚规定模型扮演的人物特征,话题锚规定对话必须覆盖的三个子话题,立场锚规定模型对某个争议问题要持的立场倾向。评测的时候不看你说了什么具体的话,看你的回复在这三个锚上有没有漂移。这个方法有点机械,但胜在可量化。
混合交互是我最看重的场景,也是最难构造的。真实的用户根本不按剧本走,聊任务聊到一半给你讲个笑话,或者突然问个完全不相关的问题再切回来。我构造混合数据的方式是“任务主线+随机支线”的结构,主线占对话轮次的六成左右,支线是各种打断、闲聊、情绪表达和无关提问。支线插入的位置我随机化了,有的插在任务关键确认之前,有的插在两个步骤中间。这种数据跑出来的指标特别能反映模型的真实水平,我见过好几个模型在纯任务数据上表现体面,一到混合场景就丢盔弃甲。
场景配比方面我没有搞一刀切。学术评测我用的是均等配比,三个场景各三分之一,方便横向比较。产业落地评测我按实际业务的流量分布来配,一般任务型占五到六成,开放域两成,混合交互两到三成。这个比例每个季度要重新审一次,业务变了配比也得跟着调。
4.3 测试集构造策略:轮次长度控制、话题切换设计与干扰注入
轮次长度的控制我摸索了挺久才找到合适的切法。太短了测不出稳定性,太长了评测成本吃不消。我最后采用的梯度是5轮、10轮、20轮、35轮四档。5轮档主要测即时应答质量,算是基线;10轮档是主流评测用的,能初步暴露记忆衰减;20轮档是我认为性价比最高的一档,误差累积的苗头基本都能在这档看出来;35轮档只跑重点模型,作为深度测试。每档的样本量按1:2:4:2配,20轮档拿最多资源。
话题切换的设计有个细节我调了好几遍。切换的突然程度得拉开梯度。我设计了三种切换模式:渐变式切换(加一句过渡话再换话题)、跳变式切换(上一句还在聊A,下一句直接问B)和嵌套式切换(聊B的时候又绕回A,再绕到C)。跳变式最有杀伤力,大部分模型在跳变切换后的两到三轮里会出现答非所问。嵌套式最考验模型的上下文管理能力,我测下来能在这项上拿高分的模型凤毛麟角。三种模式各占三分之一。
切换的间隔轮数我也做了梯度,3轮、5轮和10轮三档。3轮间隔主要测短期恢复,10轮间隔测的是长程记忆有没有把跑掉的话题记回来。这里有个我观察到的反直觉现象——话题切走之后隔3轮切回来,模型恢复得反而比隔5轮差。我琢磨了好久,觉得可能是3轮间隔太短,模型还没有完全消化新话题,两个话题的信息在它脑子里搅成一锅粥了。5轮间隔给了模型一个“放下再捡起来”的空间。10轮间隔的恢复率反而又上去了,因为间隔够长,前面的信息要么彻底丢了要么稳稳存住了,信号很干净。这个发现我写进了数据集说明里,提醒做评测的人别以为间隔越短越容易。
干扰注入我分了两大类:内容干扰和形式干扰。内容干扰包括给模型喂错误前提(“你上个星期跟我说过X”但其实没说过)、注入矛盾信息、以及在关键确认节点前插入无关闲聊。形式干扰把用户输入的写法搞乱,同义改写、语序调整、指代替换、适度加错别字。干扰强度我统一控制在“人类读者能顺畅理解”的水平线上,再乱一点就变成测噪声鲁棒性而不是测稳定性了。内容干扰和形式干扰的比例大概是六比四,内容干扰对稳定性的杀伤力更大,但形式干扰更接近真实用户行为。
4.4 评测协议设计:基线模型、对照设置与可复现实验流程
评测协议这部分我写得特别细,因为吃过亏。最早的时候我们团队内部各跑各的,参数不统一、解码策略不一样,同一个模型两个人跑出来差了好几个点,开会的时候差点吵起来。从那以后我就要求评测协议必须细到参数级别。
基线模型的选择我分三层。第一层是“锚定基线”,选两到三个业内公认水平稳定的模型,每次评测都跑,用来校准不同批次之间的漂移。这一层有点像化学实验里的标准液。第二层是“竞品基线”,选同规模、同定位的模型做横向参照。第三层是“消融基线”,针对我们想验证的特定能力做简化版本,比如把上下文窗口砍一半的版本、去掉显式记忆模块的版本。三层基线各司其职,报告里分开呈现。
对照设置这块我要说一个容易被忽略的东西——轮次级对照。不只是模型间总分的比较,还要做同一模型在不同轮次上的自身对照。第3轮到第5轮的平均指标跟第15轮到第17轮的平均指标做配对比较,看退化是不是显著的。这个自身对照比模型间对照更能揭示稳定性问题,因为它把模型能力这个变量控制住了,剩下的就是纯粹的多轮效应。
可复现流程我列个清单,这些都是被坑出来的。模型版本要锁死,API模型要记下具体的快照日期。解码参数全部写死:temperature我一般设0.3做评测,top_p设0.9,max_tokens按场景给不同的上限。随机种子固定,对话样本的采样顺序也固定。评测脚本的commit hash必须记录。时间戳和运行环境(GPU型号、CUDA版本)也要留档。这些看起来琐碎,但你要复现三个月前的评测结果,缺任何一项都白搭。
还有一个流程上的设计我想强调:分段跑和全量跑要分开。分段跑是指只跑某一类场景或者某一档轮次,用于快速迭代;全量跑是跑完整数据集,用于正式报告。我一般要求研发迭代阶段用分段跑,两天内出结果,正式评测前再做全量跑。分段跑的样本量不能太少,我建议每类场景至少150条对话,低于这个数波动太大没法用。
4.5 数据标注、人工校验与评测泄漏风险控制
数据标注这块我的经验是,标注指南比标注员数量重要得多。我们一开始找了十几个标注员,指南写得比较粗,结果一致性系数低得没法看。后来把指南细化到每个指标对应的标注决策树都写出来,标注员减到五个,一致性反而上去了。标注指南里我对“事实一致性”的标注规则写得最细,因为这块争议最大。模型说“您之前提过预算两万”但用户其实说的是“两万左右”,这算不算一致?我的规则是“数值精确匹配算完全一致,区间包含关系算部分一致,方向性表述(宽裕/紧张)算模糊但不扣分”。这种细则得写到标注员不用猜的程度。
人工校验我用了三层机制。第一层是标注员之间的交叉校验,每条对话至少两个人独立标,分歧样本进仲裁池。第二层是我自己抽检,每批数据抽百分之五逐条看。第三层是用大模型做预标注再人工修正,这一层主要是提效,不是为了替代人工。预标注的一致性大概能到八成左右,剩下两成人工纠偏的工作量比纯人工小很多。三层跑下来标注成本能压到纯人工的六成左右,质量还能保住。
评测泄漏这个事我专门拉过警报。最开始我们建数据集的时候没太注意,用了一些公开榜单的题目做种子,后来发现好几个模型的分数高得离谱,一查是因为这些模型在训练阶段见过类似的题。现在的规矩是所有评测数据必须是“原生构造”的,不引用任何已有公开评测集的原文。构造过程中用到的种子素材要做查重,跟常见训练语料做n-gram重叠检测,重叠率超过阈值的直接丢弃。
还有一种隐蔽的泄漏方式我差点栽进去。我们早期用大模型辅助生成对话样本,生成的样本风格太统一了,全是那种工工整整的教科书式对话。拿这个数据测模型,测的其实是“模型能不能应对教科书”,而不是“模型能不能应对真实用户”。后来我强制要求人工构造的样本里混入一定比例的不规整表达——省略主语、重复啰嗦、中途改主意、带情绪词,这些才是真实对话的样子。评测泄漏不光是数据泄露的问题,还有数据分布过度拟合评测习惯的问题。
4.6 面向稳定性评测的基准数据集扩展需求
现有数据集够不够用?我的判断是勉强够跑基础评测,离“充分”还差得远。有三块扩展需求我觉得比较迫切。
第一块是长对话数据的扩充。35轮以上的数据我手头只有几百条,做深度分析样本量偏薄。长对话的构造成本又特别高,人工写一条35轮的高质量对话大概要三四个小时,还得反复校验。我目前的方案是用“主线锚点+支线生成”的半自动方式扩量,人工写主线关键节点,支线用受控生成填充再人工修。这个流程能把单条成本压到一个小时左右,质量大概能到纯人工的八成五。
第二块是领域垂直化。通用场景的稳定性数据不少了,但金融、医疗、法律这些垂直领域的多轮对话数据稀缺得很。这些领域的稳定性要求跟通用场景差别很大,金融对话里事实一致性权重得拉到极高,医疗对话里策略稳定性的优先级又不一样。我暂时用领域适配的提示词加人工构造小样本顶着,长期看必须建独立的领域稳定性评测集。
第三块是工具调用和外部知识检索场景下的多轮稳定性数据。现在的模型越来越多地在对话里调用工具、查知识库、执行操作,这类场景的稳定性跟纯文本对话完全是两码事。工具调用失败之后模型能不能优雅回退、检索到的信息跟对话历史冲突时模型怎么处理、多轮里连续调用的状态怎么保持,这些问题现有的数据集基本覆盖不到。我在小规模地攒这类数据,构造难度确实大,得同时模拟工具环境和对话流,但我觉得这是接下来一年最值得投入的方向。
扩展需求的优先级我按投入产出比排了个序:长对话扩充最急,领域垂直化次之,工具调用场景再次。这个排序可能每个团队不一样,跟具体业务场景走。
这章聊完,数据和实验设计的底座算是搭起来了。下一章我要讲这些东西怎么真正跑起来——自动化评测和人工评估怎么配合、指标怎么聚合和可视化、错误怎么归因、报告怎么写。数据集是燃料,指标是引擎,下一章聊的是怎么把这台车开上路。
上一章把数据集和实验设计讲完了,这一章聊的是“跑起来”的事。我经常觉得评测这件事特别像开一家餐厅——食材(数据集)备好了,菜谱(指标)也定了,接下来得进厨房看火候。火候不对,再好的食材也白搭。我们团队最开始跑稳定性评测的时候就吃了不少火候上的亏,自动化脚本一敲回车,出来一堆数,看着挺专业,仔细一瞧全是坑。
5.1 自动化评测与人工评估的协同流程
全自动化这条路我试过,差点翻车。脚本跑得飞快,三个小时把两千条对话全测完了,一致性指标、鲁棒性指标、记忆保持率全都出来了。我拿着报告去找老板汇报,被问了一句“这些分数背后的对话你亲眼看过几条”,我当场卡壳。后来我强制加了一条规矩:任何自动化评测跑完,必须有人工抽检这一道工序兜着。
人工评估在我这里的定位很明确——不是跟自动化抢饭碗,是给自动化做校准。自动化指标擅长处理“跟标准答案比对”这类确定性强的任务,比如事实一致性对不对、指代有没有指错、槽位值有没有丢。这些事情机器做得又快又稳。人工评估的价值体现在三块:第一块是判断“语义漂移是不是严重到影响用户体验”,这种主观感受机器学不来;第二块是处理“部分正确”的灰色地带,模型答了半对半错,自动打分只能给个中间值,人眼一看就知道问题出在哪儿;第三块是发现自动化指标压根没覆盖的新失效模式。我上个月就碰到一个案例,自动指标全绿,人工抽检的时候发现模型在第十轮把用户身份从“企业采购”错记成了“个人买家”,这种角色漂移在现有的槽位比对里根本抓不到。
协同流程我是这么设计的。自动化跑全量,产出一份“红黄绿”三色标注的初筛报告。绿色的对话抽百分之五人工复核,黄色(有指标亮灯但不致命)的对话抽百分之三十人工复核,红色的对话百分百人工看。这个抽样比例是根据我们自己的误报率倒推出来的——自动化报红的有四成左右是误报,人工得去把真正的问题挑出来。反过来自动化报绿的人工复核也揪出过百分之三左右的漏报,比例不高,但漏掉的那几条往往是最隐蔽的稳定性问题。这个流程跑熟之后,人工的工作量大概能控制在纯人工评估的两成左右,覆盖面能到八成以上,我觉得这个性价比是合适的。
还有一个操作细节我想提。人工评估的时候我要求评估员不能看自动化分数。先让评估员独立打标签,打完再跟自动化对比,这样才能真实反映自动化的准不准。我试过让评估员参考自动化分数再打标签,结果评估员的判断明显被锚定了,分歧率直接掉了一半,看着一致性很高,其实是假象。
5.2 稳定性指标计算、聚合与可视化呈现
指标计算这块我得先吐槽一个我们团队踩过的坑。最早我们算一致性得分是简单算术平均——每一轮的一致性分数加起来除以轮数。这个算法跑出来一堆模型分数都挺好看,全是八十五分以上,区分度低得可怜。我后来把数据拆开一看,前五轮大家几乎都是满分,后面开始掉分,简单平均把后面的低分给稀释掉了。
现在我用的是分段加权聚合。对话按轮次切成三段:前段(第1轮到第5轮)、中段(第6轮到第15轮)、后段(第16轮往后)。三段的权重我设的是二比三比五。后段权重最高,因为稳定性评测的核心关切就是“聊久了还行不行”。这个权重不是拍脑袋定的,我拿用户实际投诉数据做了回归——对话超过十五轮之后用户投诉稳定性的概率是前十轮的四倍多,权重得反映这个事实。聚合公式我一般写成加权和的形式,报告里会把三段的分项分和总分一起列出来,方便看退化曲线长什么样。
波动性指标的计算方式跟均值型指标不一样。跨轮性能方差我用的不是全对话的方差,是滑动窗口方差——每五轮算一个窗口方差,再取所有窗口方差的平均值。这么算的原因是全对话方差会被段间的自然起伏放大,滑动窗口方差更能反映“在局部上看性能稳不稳”。退化斜率我用的是线性回归的斜率,以轮次为自变量、指标得分为因变量,斜率为负且绝对值大的模型退化快。这两个指标我一般放在报告最前面,比均值型指标更能一眼看出模型的高下。
可视化我走过弯路。最开始我把所有指标堆在一张雷达图上,八个维度,看着特别专业。结果给业务方看,人家盯了十秒钟问我“哪个模型好”。我后来改成了三层视图。第一层是总览图,就三个核心数字:总体稳定性得分、退化斜率、最差轮次得分。第二层是趋势图,折线图展示各模型随轮次变化的性能曲线,横轴轮次纵轴得分,几条线一放,谁掉得快一目了然。第三层才是细粒度明细,想看细节的自己往下翻。这套三层视图在我们内部推了半年,业务方的反馈是“终于能看懂评测报告了”。
颜色和阈值的设定我也规范了一下。绿色、黄色、红色的分界线不是拍脑袋,是根据历史数据的分位数定的——前两成的分数段是绿色,中间六成是黄色,后两成是红色。这样同一个指标在不同时间点的报告里颜色含义是一致的,不会出现这次八十分是绿的下次八十分变黄了的情况。
5.3 错误归因方法与典型失败案例分析
光知道模型不稳还不够,得知道它为什么不稳。错误归因这件事我把它拆成了三步走。第一步是自动化初判,用规则加小模型做粗分类。规则覆盖的是那些特征明显的错误——事实矛盾、指代错位、槽位丢失。小模型分类器负责更模糊的类别,比如话题漂移和角色不一致。自动化初判能覆盖大概七成的错误样本,剩下的三成得靠人工做精细归因。
第二步是人工归因。我让评估员按照一套预设的归因标签体系来打标签。标签体系分四层:信息层(事实、指代、槽位)、语义层(连贯性、话题漂移)、角色层(人设漂移、语气突变)、策略层(该追问的时候没追问、该确认的时候跳过了)。每条错误样本可以打多个标签,但要按主次排序。归因做完之后,我会看同一条对话里的多个错误是否共享同一个根因。举个例子,一条三十五轮的对话里出现了五次事实矛盾,每次都在用户给出新信息之后的两三轮内——那根因很可能是“模型对信息更新的处理机制有缺陷”,而不是五次独立的事实错误。
第三步是根因归纳和模式识别。我会把同一个模型在多条对话里的错误标签做聚类,看有没有反复出现的固定模式。去年我们测一个开源模型的时候就发现了很有意思的模式:它在对话轮次超过二十轮之后,角色一致性得分断崖式下跌,而且下跌都发生在“用户开始使用非正式用语”之后——比如用户开始用“哥们儿”“随便整一个”这种词,模型就跟着把原本正式周到的客服人设丢了,开始也变得随意起来。这个发现直接推动他们团队在角色锚定机制上做了修改。
三个典型失败案例我印象特别深。第一个是“渐忘型漂移”。一个模型在前六轮表现完美,第七轮用户随口提了一句“我上周也问过类似问题”,模型从第八轮开始每轮都多多少少要把“上周问过”这件事带进回答里,到第十二轮的时候已经完全偏题了。这种属于信息衰减的反面——信息过量囤积导致注意力被拖垮。第二个是“自我怀疑型退化”。有模型在遇到用户连续追问的时候会开始动摇,用户问第一遍它答A,第二遍它说“您说得对,应该是B”,第三遍它又改回A。稳定性评测里这种前后摇摆的扣分特别重,因为从用户视角看这比直接答错还糟糕。第三个是“话题黏着”。模型在某个话题上聊得特别顺,用户切换到新话题之后它老想把新话题往回拽。测试数据显示话题切换后第一轮响应里,超过三成的回复带回了旧话题的关键词。
5.4 模型横向比较、评测报告规范与结论表达
横向比较最容易出事的地方是比不公平。我见过不少评测报告拿一个参数量大两倍的模型跟小模型比稳定性,赢了就大吹特吹。这种报告除了自己团队高兴以外没有任何参考价值。我要求的横向比较至少要做到三个维度对齐:参数量级在同档次、推理成本可比的条件下比、训练数据的时间窗口大致相同。做不到完全对齐的,报告里必须显式标注差异带来的可能偏差。
我一般把横向比较拆成“总分比较”和“剖面比较”两层。总分比较给一个粗排序,剖面比较才是真正有价值的部分。剖面比较看的是每个模型在四个稳定性维度上的相对强弱——语义稳定、事实稳定、角色稳定、策略稳定。我给每个维度画一个能力画像,把模型的得分标在剖面图上。这样一来经常出现的画面是:总分差不多的两个模型,在剖面图上一看长得很不一样。A模型事实稳定极强但策略稳定偏弱,B模型反过来。报告里把这两个模型并排一放,业务方爱选哪个选哪个,比给个笼统排名有用得多。
评测报告的规范我列了一个模板,分五部分写。第一部分是一页纸的摘要,三到五个核心结论,每个结论必须带数据支撑,不许写“表现良好”这种废话。第二部分是评测设置说明,数据集版本、模型版本、解码参数、运行环境、评测时间,一个都不能少。第三部分是分项结果,按四个稳定性维度分别呈现,每个维度下面配趋势图和关键案例。第四部分是失败分析,按归因标签分类展示典型失败模式。第五部分是附录,放完整的结果表格、统计检验的具体数值和可复现说明。
结论表达我有几条硬规矩。不许用“全面领先”这种绝对化表述,稳定性评测受数据集和参数设置影响很大,换个数据集排名很可能变。不许只看均值不看方差,均值一样但方差差一倍的模型在实际使用中的稳定性表现完全是两回事。不许把统计上不显著的差异当成结论写,我要求所有横向比较的差异都要过显著性检验,p值大于0.05的一律写“未见显著差异”。最后一条是每个结论必须配一句“这意味着什么”的解读,光说“A模型的一致性得分是86.3,B模型是84.1”没有意义,得补一句“在业务场景下这大约对应每百轮对话出两到三次事实矛盾还是三到四次事实矛盾的差距”。
5.5 面向研发迭代的评测反馈闭环设计
评测报告写完了躺在文件夹里睡大觉,这是最浪费的事。我花了很多精力设计反馈闭环,目标就一个——让评测结果能直接变成研发的待办清单。现在我们的流程是评测报告出来之后,两天之内开一次“评测-研发”联席会,会上不一定讨论所有问题,只定三件事:哪些是必须马上修的高优先级问题、哪些是需要排期解决的中优先级问题、哪些是接受现状的低优先级问题。优先级的分级标准跟业务影响度挂钩——话题跳变后恢复失败算高优先级,因为用户体感最差;角色一致性轻微波动算低优先级,用户基本感知不到。
反馈闭环里最关键的环节是“问题单”。每条需要修复的问题都生成一个标准问题单,里面写清楚复现路径、错误归因标签、影响范围评估和修复验收标准。复现路径要细到“对话数据集编号加轮次编号”,研发拿着就能跑。修复验收标准要量化,不许写“提升角色一致性”,要写“在测试集V2.3上角色一致性得分不低于88,且后段无断崖式下跌”。这套问题单系统跑了大半年,研发那边的反馈是“终于不用猜评测报的问题到底指的是什么了”。
闭环设计里的节奏感很重要。我们现在的节奏是每月一次全量评测,每周一次分段快评。快评只跑核心场景和二十轮档,十二个小时内出结果,主要看有没有引入新的回归问题。全量评测出正式报告,作为月度迭代的验收依据。中间如果研发主动修了某类问题,可以做一次定向评测,只跑对应的失效模式样本,半天出结果。这个节奏是磨合了三个月才稳下来的,一开始我要求每周全量,研发扛不住,评测团队也扛不住,后来砍到现在的频率反而运转得更顺。
还有一个闭环上的小装置我觉得挺管用,叫“稳定性周报”。每周从最近七天的线上对话里抽样,跑一遍轻量版稳定性指标,跟上周的数据做环比。这份周报不发正式报告,就一张图加三行字,直接丢到研发群里。周报的作用不是做正式评测,是让研发时刻有根弦绷着。我印象很深的一次,某周周报上的退化斜率突然恶化,研发当天就去查了,发现是前一天上线的改动里有个缓存逻辑有bug,不到两天就修了。要是等月度全量评测才发现,这个问题得在线上存活三周。
闭环的最后一步是“反哺数据集”。每次归因出来的新型失败模式,只要确认了不是偶发,我就让人把它转化成新的测试样本补进数据集。这样数据集是活的,每个月都在长,模型见过的问题类型越来越多,评测的覆盖度也跟着往上走。这个反哺机制跑了一年,我们的核心测试集从最初的一千条出头扩到了三千四百多条,失效模式标签从二十种扩到了五十七种。
这一章聊的是把车开上路的事。回头看看这五章走下来,从问题界定到理论框架,从指标体系到数据集设计,再到这一章的实施流程和结果分析,一条完整的评测链路算是搭起来了。下一章我想聊点更往前看的东西——这套评测体系还缺什么、哪些坑还没填上、未来一两年这个领域会往哪儿走。有些问题我现在也没答案,但把问题摆出来本身就挺有价值。
这一章我想聊点“拆台”的事。前面五章把评测框架、指标、数据集、实施流程都搭起来了,看着挺完整,但我自己心里清楚,这套体系里还有一大堆没填上的坑。有些坑是技术本身没成熟,有些坑是我们这些做评测的人还没想明白。写这一章的时候我翻了一遍过去半年的评测日志,把那些让我半夜睡不着的问题挑出来摆一摆。摆问题不是为了否定前面的工作,是想给后面走这条路的人省点弯路。
6.1 数据污染、动态基准与评测公平性挑战
数据污染这件事已经成了多轮对话评测的头号公敌。我去年遇到过一件特别尴尬的事——一个新发布的模型在我们自建的测试集上稳定性得分高得离谱,接近九十三分,比当时公认最强的模型还高一大截。我第一反应是“不可能”,然后花了两周时间去查,最后发现这个模型的训练语料里混进了我们测试集里一部分公开样本。模型不是真稳,是见过题了。公开数据集的生命周期现在短得可怜,一个基准发布出去,六个月之内大概率会被各种训练语料抓取进去。你精心设计的测试集,在模型眼里变成了开卷考试。
动态基准是业界给出的一个解法,我自己也在试。基本思路是测试集不固定,定期用新生成的对话样本替换掉被污染风险高的旧样本。我们团队现在每个季度会用一套生成加人工筛选的流程产出两百到三百条新对话样本,替换掉测试集里发布时间超过半年的部分。这个做法能缓解污染,但带来了新问题——基准版本一换,历史评测结果就没法直接跟新结果比了。我现在采取的办法是把测试集切成“锚定集”和“滚动集”两部分。锚定集占三成,永远不换,作为跨版本比较的基准;滚动集占七成,按季度更新。代价是锚定集迟早也会被污染,只是时间问题。
评测公平性的挑战比数据污染更隐蔽。我审过不少第三方评测报告,表面上看流程规范、指标齐全,仔细一扒就能发现问题。有拿大参数模型跟小参数模型比稳定性的,有给自家模型开更高推理预算的,有只在自家模型擅长的场景上做横向比较的。这些操作未必是故意的,但结果就是不公平。我现在的做法是横向比较必须公开三个信息——模型参数量级、单轮平均推理开销、测试时的解码参数配置。缺任何一个,报告里就得标注“公平性存疑”。行业层面我觉得需要一份多轮对话稳定性评测的公平性操作规范,光靠各家自觉不够。
还有一个更根本的问题我暂时没找到好答案。多轮对话稳定性跟模型规模、训练数据质量、对齐策略都相关,变量太多,评测结果很难归因到某一个因素上。我试过做控制变量实验,固定其他条件只改训练数据里的多轮对话比例,跑了三组对照,结论是有影响但影响不线性,中间有个瓶颈区。这类实验做起来成本高、可复现性差,但不做的话评测结论就只能停留在“A比B好”的层面,没法告诉我们“为什么好”。评测的终极价值应该是指向改进方向,不是排个名就完事。
6.2 长对话、多模态与工具调用场景下的稳定性扩展
长对话场景的稳定性评测现在基本是空白。我定义的“长对话”是五十轮以上,实际业务里超过五十轮的对话占比不算高,大概百分之三到五,但这类对话往往是高价值场景——比如复杂客服纠纷处理、长期项目咨询、医疗随诊跟踪。我们现有的测试集里超过三十轮的样本占比不到一成,五十轮以上的几乎没有。我试过把同一批测试样本通过多轮改写拉长到五十轮以上,发现拉长之后测出来的问题跟短对话完全不是一个类型。短对话里罕见的信息衰减、话题漂移累积、角色缓慢走样,在长对话里全成了高频问题。有个模型在二十轮测试里角色一致性九十分以上,拉到六十轮之后掉到了七十分出头,这种退化在短测试里根本看不出来。
长对话评测的难点在数据构造。让真人写六十轮以上的对话成本太高,用模型生成又容易带上模型自己的缺陷。我现在的做法是人机协作——模型先生成对话骨架和关键信息更新节点,人工去填充细节和制造自然的话题切换。一条六十轮的高质量对话样本,人工介入时间大概要四十分钟到一个小时。这个成本决定了长对话测试集不可能做得很大,我目前只攒了不到两百条,覆盖的场景类型也有限。怎么低成本地构造保真度高的长对话测试样本,是个卡脖子的问题。
多模态场景的稳定性评测是另一个维度的挑战。文本加图像、文本加语音、文本加视频这些混合输入下,稳定性的内涵要扩展。我最近在测一个支持图文混合输入的模型,发现一个特别有意思的失效模式——用户先发了一张产品截图问功能,聊了十几轮之后又发了一张相似产品的截图,模型把两张图的信息混淆了,新问题的回答里混进了旧图里的参数。这种跨模态的指代混淆在纯文本评测里根本不存在。多模态稳定性评测需要新的指标,比如跨模态引用一致性、模态切换后的上下文保持率。这些指标我现在只有初步的设计,离成熟还差得远。
工具调用场景的稳定性问题更复杂。模型在多轮对话里调用外部工具,工具返回的结果可能不完整、可能格式变化、可能超时。我测过一个订票助手场景,用户在十五轮对话里连续修改了四次行程,模型每次调工具查航班,到第四次的时候它把第二次查到的航班信息跟第四次的结果混在一起报给了用户。这种稳定性失效的根源在工具返回结果的状态管理上,不在语言模型本身。工具调用场景的稳定性评测得把工具侧的扰动也纳入进来,比如模拟工具返回延迟、返回残缺字段、返回格式错误,看模型能不能稳住。这类评测环境搭起来费劲,但业务价值极高,因为线上环境里的工具就没几个是永远稳定返回的。
6.3 面向实际应用的稳定性验收标准与风险分级
验收标准这件事我在过去一年里被业务方问过无数次——“你告诉我这个模型能不能上”。评测报告给的是分数和曲线,业务方要的是一个Yes或No。这中间有个鸿沟,我现在用风险分级来填。思路是把稳定性失效按业务影响度分成四级。一级是致命失效,比如涉及金额、医疗建议、法律条款的事实性错误在多轮对话中被反复强化,这种一旦出现就是不可接受。二级是严重失效,比如角色崩塌导致用户信任度骤降,或者话题漂移导致任务无法完成。三级是中度失效,比如轻微的一致性波动用户能感觉到但不影响任务完成。四级是轻微失效,比如语气偶尔不稳定,用户基本无感。
分级定完之后,验收标准就好写了。面向消费者的客服场景,我建议一级零容忍、二级每百轮不超过两次、三级每百轮不超过十次。面向企业内部的知识助手场景可以适当放宽,一级零容忍这条不变,二级放宽到每百轮五次。这些阈值不是拍脑袋来的,是我们跟业务方一起根据用户投诉数据和客服工单做回归分析倒推出来的。不同业务场景的阈值肯定不一样,我建议每个团队根据自己的业务数据去做类似的回归,别直接抄我们的数。
风险分级落地的时候有个细节要处理好——分级不是静态的。模型迭代之后,原本的二级失效可能变成一级。举个例子,模型早期版本在涉及退款金额的对话里偶尔会把货币单位搞错,我们当时定为二级。后来业务扩展到了跨境场景,货币单位搞错直接涉及汇率换算,这就升成一级了。我现在的做法是每个季度跟业务方过一遍风险分级表,看看有没有需要调整的条目。这张表是活的,不是钉在墙上的。
验收标准还有一个维度是时间。我见过太多“上线前评测全绿、上线后一周就出稳定性事故”的案例。静态测试集上的表现不能完全代表线上表现,线上对话的分布跟测试集有系统性偏差。我现在要求所有要上线的模型必须过一道“影子测试”——用线上真实流量的镜像跑两周,不对外服务,只做稳定性监测。影子测试期间的一级和二级失效频次如果超过验收阈值的一点五倍,就打回去重修。这道工序增加了上线周期,业务方一开始有意见,后来有一次影子测试拦住了一个会在长对话里逐渐丢失用户身份信息的模型,上线计划推迟了两周,但避免了一次大规模的用户投诉。从那以后没人再质疑这道工序的必要性了。
6.4 多轮对话稳定性模型评测的最佳实践总结
最佳实践这件事我不想写成教科书式的清单,就说说我们团队用血泪换来的几条硬规矩。第一条规矩是“评测设计先于模型选择”。很多团队的做法是先选定要评测的模型,再围绕模型设计评测方案。这个顺序反了。正确的顺序是先明确业务场景需要什么样的稳定性,再设计指标和数据集,最后才去选模型。顺序反了的话,评测方案会不自觉地偏向模型擅长的方向,测出来的结果好看但没用。
第二条规矩是“分层抽样、全程留痕”。分层抽样指的是测试集构造的时候按轮次长度、话题类型、交互复杂度分层,每一层都要有足够样本量。全程留痕指的是评测过程中的每一个决策都要记录——为什么选这个阈值、为什么剔除那条样本、为什么调整那个参数。我们团队有过一次教训,半年前跑的一组评测结果出了问题要复查,发现当时的参数配置没记全,复现不出来,两周的工作白费了。从那以后我要求所有评测运行必须带完整的配置快照,连随机种子都要记。
第三条规矩是“指标宁少勿滥”。我见过一些评测框架堆了三四十个指标,报告出来几十页,看得人头晕。指标多不等于评得全,很多指标之间高度相关,堆在一起只是增加噪音。我们现在的核心指标控制在十二个以内,分四个维度,每个维度三个指标。十二个指标能覆盖百分之九十以上的稳定性问题,剩下的边缘情况放到人工抽检里兜底。指标少还有一个好处是研发看得进去,看得进去才会去改。
第四条规矩是“评测团队跟研发团队物理隔离”。这条听起来有点极端,但我觉得非常必要。评测团队如果跟研发团队坐得太近、汇报关系太紧密,评测的独立性就很难保证。我见过太多“自家评测自家模型永远优秀”的案例。我们团队的评测组直接向技术VP汇报,不向任何模型研发团队汇报。这个组织设计保证了评测结论不受研发进度压力的干扰。当然隔离不等于对立,前面说的联席会机制就是隔离前提下的协作通道。
最后一条规矩是“把用户体感作为终极裁判”。所有指标、所有阈值、所有分级,最终都要回到一个问题——用户用起来觉得稳不稳。我每个月会亲自看二十条用户投诉里涉及稳定性问题的原始对话,一条一条读。这个习惯保持了快一年,对我调整评测方案帮助极大。有些指标上看着很严重的问题,用户实际感知不强;有些指标上不起眼的波动,用户体感特别差。指标是地图,用户体感是实地,地图画得再精细也得定期去实地走走。
6.5 未来研究方向与开放问题
未来方向我不敢说看得多准,就说说我目前最想解决但还没解决的几个问题。第一个是“稳定性的可解释归因”。现在的归因方法能告诉我们“模型在第二十三轮出现了角色漂移”,但没法告诉我们“为什么偏偏是第二十三轮、为什么偏偏是角色维度”。我理想中的归因系统应该能定位到模型内部的注意力模式或者状态更新机制上,指出是哪一层的什么计算导致了这次失效。这个方向需要评测跟可解释性研究深度结合,目前业界在这块的进展还比较初步。
第二个是“跨语言跨文化的稳定性评测”。多轮对话稳定性在中文和英文里的表现模式可能不一样。我做过一个小规模的对比实验,发现同一个模型在中文对话里的角色一致性退化比英文对话里快,我猜测跟训练数据里中文多轮对话的比例偏低有关,但样本量太小,结论不敢下。跨文化维度更复杂,不同文化背景下用户的对话习惯、礼貌策略、话题切换方式都不同,模型在这些差异下的稳定性表现是个空白区。要做这个方向的评测,得先建多语言多文化的平行测试集,工作量巨大。
第三个是“在线评测与离线评测的一致性校准”。离线测试集上测出来的稳定性排名,在线上真实流量里能不能复现,这个一致性现在没有系统性的研究。我们自己的数据显示离线排名和线上排名的相关性大概在零点七左右,不算低但也不算高。哪些类型的稳定性失效在离线线上一致性高、哪些低,我还没有清晰的规律。这个方向的研究需要大量线上数据支撑,单靠一个团队做不了,可能需要行业联盟的形式来推动。
第四个是“稳定性与创造性的平衡”。稳定性评测的隐含假设是“越稳越好”,但实际业务里有些场景需要模型有一定的灵活性。比如创意辅助场景,模型如果太稳、每轮都严格锚定在初始设定上,输出的多样性会受影响。稳定性和创造性之间怎么权衡、评测框架怎么容纳这种权衡,是个开放问题。我现在的做法是给不同场景配不同的稳定性权重,创意类场景把角色一致性和话题保持的权重调低,但这个调法很粗糙,缺乏理论支撑。
第五个是“多轮对话稳定性的形式化定义”。我们现在的稳定性定义还是操作层面的——用一堆指标去刻画。学术上有没有可能给出一个更本质的形式化定义,像信息论里的熵或者控制论里的稳定性那样,用一个数学框架统一描述。这个方向偏理论,短期对工程实践帮助有限,但我认为长期来看很重要。没有形式化定义,评测指标的设计就只能靠经验和试错,有了形式化定义才可能推导出最优的指标组合。
写到这儿这一章就收尾了。回头看这六章,从问题界定一路写到未来方向,该覆盖的框架、指标、数据、流程、实践、挑战都聊了一遍。这套东西不是完美的,我自己知道里头有不少漏洞和权宜之计。但评测这件事本来就是个持续迭代的活儿,没有一劳永逸的方案。我把我们团队踩过的坑、试过的招、还没想明白的问题都摊在这里,希望能给同行省点力气。多轮对话稳定性评测这个领域还年轻,未来两三年肯定会有大变化,到时候再回头看这些文字,大概会觉得很多地方幼稚得可笑。那也挺好,说明这个领域在往前走。