1. 长时对话评测基准到底在测什么
大模型评测这件事,过去两年大家见得最多的就是"单轮问答刷榜"。给一道题,模型答对了,分数加一,最后算个准确率。这套玩法在短对话场景下勉强够用,但一旦把对话拉长到几十轮、上百轮,问题就全暴露出来了——模型在前面说过的话,后面忘得一干二净;用户第三轮提到的偏好,到第二十轮已经彻底丢失;更离谱的是,有些模型会把用户早就否定的方案重新拿出来推荐,仿佛中间那段对话从未发生过。
长时对话人类理解评测基准,针对的正是这个痛点。它要测的不是模型"能不能答对一道题",而是模型"能不能在跨越大量轮次之后,依然记得住、理得清、用得对之前聊过的内容"。这个区别很关键。单轮评测考的是知识储备和推理能力,长时对话评测考的是记忆保持、信息检索、指代消解、意图一致性这四项能力的综合表现。
我先把这四项能力拆开说清楚,不然后面聊评测设计的时候容易糊。
记忆保持指的是模型能否在长上下文中稳定保留早期出现的关键信息。比如用户在第五轮说自己对花生过敏,到第四十轮推荐餐厅时,模型必须避开所有含花生的菜品。这不是知识问题,是记忆问题。
信息检索指的是当对话历史很长时,模型能否准确找到与当前问题相关的那几条历史消息,而不是被大量无关内容干扰。人类聊天时天然会做这件事——朋友提到"上次那个事",你立刻能想起是哪件事。模型要做到这一点,需要在长上下文里做有效的注意力分配。
指代消解是长对话里最容易翻车的环节。"它""那个""之前说的那个方案",这些指代在短对话里靠邻近上下文就能解决,但在长对话里,指代对象可能出现在几十轮之前,中间还夹杂着大量其他话题。模型如果搞错了指代对象,后面的回答就全歪了。
意图一致性指的是模型在整个对话过程中是否始终围绕用户的核心目标推进,而不是聊着聊着就跑偏了。人类长对话里经常有话题漂移,但最终会回到主线。模型如果缺乏这种主线意识,就会变成"每轮都在回答当前问题,但整体看毫无连贯性"。
这个评测基准的价值在于,它把上述四项能力变成了可量化、可复现的测试项。不是靠感觉说"这个模型记性不好",而是用具体的对话脚本、具体的追问、具体的评分标准,把记忆能力变成一个可以打分的数字。这对于模型选型、产品迭代、学术研究都有直接参考意义。
2. 评测集是怎么构造出来的
2.1 对话脚本的设计逻辑
构造长时对话评测集,最核心的难点在于:对话必须足够长,但又不能是随机拼凑的废话。如果只是把一百条无关的问答串在一起,那测的就不是记忆能力,而是模型在噪声中找信号的能力——这虽然也有价值,但和"人类理解"这个目标有偏差。
真实的人类长对话有一个特点:话题会自然演化,但核心信息会反复出现或被引用。比如两个人聊旅行计划,中间可能穿插聊了天气、聊了工作、聊了最近看的电影,但最终还是会回到"到底去哪玩"这个主线上。评测集的对话脚本需要模拟这种结构。
具体做法通常是:先设定一个核心任务或核心话题,然后围绕它设计多条支线对话,支线之间要有自然的过渡,不能太生硬。每条支线里埋入若干关键信息点,这些信息点会在后续对话中被再次引用或追问。关键信息点的类型包括:用户的个人偏好、用户明确否定过的选项、用户提供的具体数据、用户设定的约束条件。
我举个例子说明这种设计。假设核心话题是"帮用户规划一次周末短途出行"。对话可能这样展开:
- 第3轮:用户提到自己不开车,只能坐公共交通
- 第7轮:用户说预算控制在人均500以内
- 第12轮:聊到天气,用户说讨厌下雨天
- 第18轮:用户提到同行有一位老人,走路不太方便
- 第25轮:用户问"之前说的那个预算,如果包含住宿的话够吗"
到第25轮的时候,模型需要同时调用第7轮的预算信息、第3轮的交通约束、第18轮的老人同行信息,才能给出合理回答。如果模型只记得最近几轮的内容,就会给出一个忽略约束条件的泛泛建议。这就是评测要抓的点。
2.2 关键信息点的埋设密度
埋设密度是个需要仔细权衡的参数。埋得太密,对话会显得刻意,而且模型即使只记住一部分也能拿不错的分;埋得太疏,又容易变成"大海捞针",区分度反而下降。
根据我看到的类似评测集的设计经验,比较合理的密度是每5到8轮埋一个关键信息点,整段对话长度控制在60到120轮之间。这样一段对话里大约有10到20个关键信息点,足以区分不同模型的记忆能力层次。
关键信息点还需要分类。有些是"硬约束",比如预算上限、时间限制、人数;有些是"软偏好",比如喜欢安静的地方、不喜欢排队。硬约束如果被遗忘,回答基本就是错的;软偏好如果被遗忘,回答可能仍然合理,但不够贴心。评测时这两类要分开计分,否则会掩盖模型在某一类上的短板。
2.3 追问问题的设计
对话脚本写完之后,需要设计追问问题来检验模型是否记住了关键信息。追问问题的设计有几个原则:
第一,不能直接问"你还记得我说过什么吗"。这种问法太直白,模型只要把历史消息复述一遍就能得分,测不出真正的理解能力。
第二,追问要嵌入在自然对话中。比如不要问"用户的预算是多少",而要问"如果我想加一个住宿选项,总价大概会到多少"。模型需要自己意识到这里涉及预算约束,并主动调用之前的信息。
第三,追问要设置干扰项。比如用户之前说过"不开车",追问时可以问"如果自驾的话路线怎么走",看模型会不会盲目回答自驾路线,还是先指出用户之前说过不开车。这种"陷阱题"能有效区分"真记住"和"假装记住"。
第四,追问要有层次。同一个关键信息点,可以在不同轮次用不同方式追问,看模型的一致性。如果模型第一次答对了,第二次却答错了,说明它的记忆不稳定,可能是靠上下文窗口的偶然命中,而不是真正的长时记忆。
2.4 评分标准的制定
评分标准直接决定了评测结果的可信度。长时对话评测的评分不能只看最终答案对不对,还要看推理过程是否引用了正确的历史信息。
比较合理的评分维度包括:
| 评分维度 | 说明 | 权重建议 |
|---|---|---|
| 信息召回准确率 | 回答中正确引用的历史信息点数量 / 应引用的信息点总数 | 30% |
| 约束遵守率 | 回答是否违反了用户设定的硬约束 | 25% |
| 指代消解正确率 | 对历史消息中指代对象的识别是否正确 | 20% |
| 意图一致性 | 回答是否始终围绕用户核心目标 | 15% |
| 自然度 | 回答是否像人类一样自然,而非机械复述 | 10% |
这个权重分配不是固定的,可以根据评测目的调整。如果重点是测记忆能力,信息召回和约束遵守的权重可以调高;如果重点是测对话体验,自然度和意图一致性的权重可以调高。
评分方式上,纯自动评分和人工评分各有优劣。自动评分效率高、可复现,但难以判断"自然度"这种主观维度;人工评分准确度高,但成本高、一致性难保证。实践中通常是自动评分做初筛,人工评分做精评,两者结合。
3. 实测中模型暴露出的典型问题
3.1 中期遗忘:最普遍的翻车方式
我拿几个主流模型跑过类似的评测脚本,发现一个非常一致的现象:模型对最近5到10轮的记忆通常没问题,对最开头几轮的记忆也还行,但中间那段——大概第15轮到第40轮之间的内容——遗忘率最高。
这个现象和人类记忆的"首因效应+近因效应"有点像,但成因不同。人类是记忆容量有限导致的,模型则是注意力机制在长上下文中的衰减。Transformer架构的注意力计算复杂度随序列长度平方增长,实际部署时往往会对长上下文做各种近似或截断处理,导致中间部分的信息被"稀释"。
这个问题的实际影响很大。真实的长对话场景里,用户往往是在中间某几轮透露了最关键的信息——因为聊到一半的时候人才会放松,才会说出真实需求。如果模型恰好对中间部分记忆最差,那用户体验就会非常糟糕。
3.2 指代消解错误引发的连锁反应
指代消解错误是另一个高频问题,而且它的破坏性比单纯遗忘更大。遗忘只是"少了一条信息",指代错误则是"用错了信息",后者会导致回答完全跑偏。
我遇到过这样一个案例:对话前段用户提到了两个方案,方案A和方案B。聊到中段时用户说"那个方案我觉得不太行",但没有明确说是A还是B。到后段用户问"如果按之前说的调整一下,需要多长时间"。模型需要判断"之前说的"指的是哪个方案,以及"不太行"否定的是哪个方案。
实测中,不少模型会把否定的对象搞反,或者把两个方案的属性混在一起。更麻烦的是,模型往往不会意识到自己搞错了,而是非常自信地给出一个基于错误前提的回答。用户如果不仔细看,可能就被带偏了。
这类问题的根源在于,长对话中的指代消解需要跨越多轮建立实体追踪表,而很多模型并没有显式地做这件事。它们依赖注意力机制隐式地关联指代对象,在短对话里够用,在长对话里就不稳定了。
3.3 约束遗忘与"自我矛盾"
约束遗忘指的是模型忘记了用户设定的限制条件,给出违反约束的建议。比如用户说了预算500,模型推荐了一个800的方案。这种错误在单轮评测里很少见,因为约束就在同一轮里;但在长对话里,约束是几十轮之前说的,模型很容易忘。
比约束遗忘更隐蔽的是"自我矛盾"。模型在第20轮说"根据您之前提到的预算限制,我推荐A方案",到第35轮却说"B方案虽然贵一些但更合适",完全忘了自己之前已经确认过预算约束。这种前后不一致会让用户觉得模型"没在认真听"。
我观察到的一个规律是:模型在长对话中倾向于"讨好当前轮次",即优先满足当前问题的表面需求,而牺牲与历史信息的一致性。这可能和训练时的奖励机制有关——模型被训练成"每轮都给出有用回答",但没有被充分训练成"保持跨轮次的一致性"。
3.4 长上下文窗口不等于长时记忆
这里要澄清一个常见误解:很多人以为只要模型的上下文窗口够大(比如128K、200K),长时对话就没问题。实测下来完全不是这么回事。
上下文窗口大,只意味着模型"能装下"更多内容,不意味着它"能用好"这些内容。我做过对比测试,同一个模型在32K窗口和128K窗口下跑同一段长对话,128K窗口的准确率确实高一些,但提升幅度远没有窗口扩大倍数那么大。而且当对话长度接近窗口上限时,性能下降非常明显。
这说明"装得下"和"记得住"是两回事。真正决定长时对话表现的,是模型在长上下文中检索和利用信息的能力,这涉及到注意力机制的设计、位置编码的方式、训练数据的分布等多个因素。窗口大小只是其中一个变量,而且不是最关键的变量。
4. 提升长时对话表现的实操思路
4.1 显式记忆摘要的工程方案
如果你在做对话产品,不能只依赖模型自身的记忆能力,需要在工程层面做补充。最直接的办法是维护一个显式的记忆摘要。
具体做法是:每隔若干轮,让模型对之前的对话做一次摘要,提取出关键信息点(用户偏好、约束条件、已确认的决策等),存成一个结构化的小抄。后续对话时,把这个小抄作为系统提示的一部分注入,而不是把全部历史消息都塞进去。
这样做的好处有三个:一是减少上下文长度,降低计算成本;二是把关键信息从大量噪声中提出来,提高模型利用效率;三是摘要可以人工审核和修正,避免模型记错。
摘要的更新频率需要权衡。太频繁会增加延迟和成本,太稀疏会丢失信息。我的经验是每10到15轮做一次摘要比较合适,同时在检测到关键信息点出现时(比如用户明确说"记住""注意""必须"等词)立即触发一次摘要更新。
摘要的格式也很重要。不要用自然语言大段描述,而要用结构化的键值对。比如:
{ "user_preferences": ["不喜欢排队", "偏好安静环境"], "hard_constraints": ["预算500以内", "不开车", "有老人同行"], "confirmed_decisions": ["目的地选在近郊", "出行时间定在周六上午"], "rejected_options": ["方案A(太远)", "方案B(超预算)"] }这种格式模型解析起来更准确,也不容易产生歧义。
4.2 关键信息点的主动追问策略
除了被动记忆,还可以让模型主动确认关键信息。在对话进行到一定轮次后,模型可以主动问一句"我确认一下,您之前提到的预算是不超过500,对吗"。这种主动确认有两个好处:一是强化模型自身的记忆,二是给用户一个纠正的机会。
主动追问的时机需要设计。不能每轮都问,那样很烦;也不能一直不问,那样错了都不知道。比较合理的做法是在话题切换时、在即将给出重要建议前、在检测到潜在冲突时主动确认。
比如模型准备推荐一个方案,但这个方案涉及预算,而预算信息是30轮之前提到的,这时候就应该先确认一下预算是否还有效。用户可能已经改了预算,也可能没改,确认一下成本很低,但能避免大错。
4.3 分块检索加相关性排序
如果对话特别长,即使用了摘要也不够,可以考虑分块检索的方案。把历史对话切成若干块,每块做一个向量化索引。当前轮次的问题来了之后,先检索最相关的几块,再把这几块和当前问题一起送给模型。
这个方案的核心是检索的准确性。检索错了,后面全错。所以检索模型的选择很关键,不能只用简单的关键词匹配,要用语义检索。同时检索的块大小也要调,太大则噪声多,太小则信息不完整。
我试过的比较有效的配置是:块大小设为5到8轮对话,检索返回top 3到5块,然后在送给模型之前做一个重排序,把最相关的块放在最前面。这样模型在生成回答时,注意力会优先落在最相关的历史上。
4.4 训练层面的改进方向
如果是从模型训练的角度考虑,提升长时对话能力需要在数据构造和训练目标上做文章。
数据方面,需要构造大量长对话训练样本,而且这些样本要包含"关键信息在中间出现、在后期被引用"的模式。不能只是把短对话拼长,那样模型学不到跨轮次的关联。
训练目标方面,除了标准的下一词预测,可以增加辅助任务,比如"指代消解预测""关键信息召回预测"。这些辅助任务能迫使模型显式地学习长距离依赖关系,而不是依赖注意力机制的隐式关联。
还有一个方向是位置编码的改进。传统的位置编码在长序列上会出现衰减,导致中间部分的信息被弱化。一些新的位置编码方案试图解决这个问题,让模型在长序列的各个位置都能保持较好的注意力。这个方向目前还在研究中,但已经有了一些有希望的结果。
5. 评测基准对产品选型的实际参考价值
5.1 不同场景对记忆能力的要求差异
长时对话评测的分数不是越高越好,关键看你的产品场景需要什么级别的记忆能力。
如果是客服机器人,对话通常在10到20轮以内,核心信息是订单号、问题描述、用户身份,这些信息往往在开头几轮就出现了。这种场景对"中期记忆"的要求不高,但对"开头信息保持"的要求很高。选型时应该重点看评测中"早期信息召回率"这个指标。
如果是个人助理类产品,对话可能持续几十轮甚至跨天,核心信息是用户偏好、日程安排、历史决策。这种场景对全时段的记忆能力都有要求,而且对"意图一致性"的要求特别高。选型时要看综合分数,不能只看某一项。
如果是教育辅导类产品,对话围绕一个学习目标展开,可能持续很长时间。核心信息是学生的知识薄弱点、学习进度、之前的错误。这种场景对"约束遵守"和"指代消解"的要求很高,因为辅导过程中经常需要引用之前讲过的内容。
5.2 评测分数与实际体验的差距
需要提醒的是,评测分数和实际用户体验之间往往有差距。评测是在受控条件下跑的,对话脚本是设计好的,关键信息点是明确标注的。真实用户的对话更随意、更跳跃、更不按套路出牌。
我见过评测分数很高的模型,在实际产品里被用户吐槽"记性差"。原因往往是真实对话里的关键信息不像评测脚本里那么显眼,用户可能在一句闲聊里顺带提了一个约束,模型没识别出来那是关键信息。
所以评测分数只能作为参考,不能作为唯一依据。实际选型时,最好用自己产品的真实对话数据做一轮测试,看看模型在真实分布下的表现。如果条件允许,做A/B测试是最可靠的。
5.3 成本与效果的平衡
长时对话能力越强,通常意味着模型越大、推理成本越高。如果产品对成本敏感,就需要在效果和成本之间找平衡。
一个实用的策略是分层处理。对于短对话场景,用轻量模型就够了;对于长对话场景,切换到重量模型。或者在同一段对话里,前几轮用轻量模型,检测到对话变长后自动切换。
另一个策略是用工程手段弥补模型能力的不足。前面提到的记忆摘要、分块检索,都是用工程换效果的办法。这些方案会增加系统复杂度,但能显著降低对模型本身记忆能力的要求,从而可以用更便宜的模型。
6. 自己动手搭一套简易长时对话测试
6.1 测试脚本的快速构造方法
如果你不想等现成的评测集,可以自己快速构造一套测试脚本。方法比想象中简单。
先确定一个核心任务,比如"帮用户选一台笔记本电脑"。然后围绕这个任务,设计20到30轮对话,中间穿插3到5个支线话题(比如聊到最近的工作、聊到桌面布置、聊到预算来源)。在支线里埋入关键信息点:预算上限、必须支持某类软件、重量要求、屏幕尺寸偏好、之前用过的品牌及不满意的点。
关键信息点要分散在不同位置:有的放在开头几轮,有的放在中间,有的放在接近结尾。然后设计5到8个追问,每个追问都需要调用至少两个关键信息点才能正确回答。
这样一套脚本,一个人半天就能写出来。虽然不如专业评测集那么严谨,但用来做模型间的横向对比足够了。
6.2 自动化跑测的注意事项
写脚本跑测的时候,有几个坑要注意。
第一,要控制变量。同一段对话脚本,在不同模型上跑的时候,系统提示、温度参数、最大生成长度这些都要保持一致,否则比较不公平。
第二,要记录完整对话日志。不能只记录最终回答,中间每一轮的输入输出都要存下来,方便事后分析模型是在哪一轮开始出错的。
第三,要多次运行取平均。大模型有随机性,单次运行的结果可能偶然性很大。同一段脚本至少跑3到5次,看平均表现和方差。方差大的模型说明稳定性差,实际产品里风险更高。
第四,要设计好评分脚本。如果完全靠人工评分,成本太高。可以先用规则做自动评分(比如检查回答里是否包含了正确的预算数字、是否避开了被否定的选项),然后对自动评分存疑的案例做人工复核。
6.3 结果分析的几个关键指标
跑完测试之后,不要只看一个总分。要拆开看几个关键指标:
- 早期信息召回率:对话前10轮的关键信息,在后续追问中的正确引用比例
- 中期信息召回率:第10到30轮的关键信息召回比例
- 晚期信息召回率:最后10轮的信息召回比例
- 约束违反次数:整个对话中,回答违反用户硬约束的次数
- 指代错误次数:指代消解错误的次数
- 一致性得分:同一信息点在不同轮次被追问时,回答是否一致
这几个指标能帮你定位模型的短板在哪里。如果早期召回率高但中期低,说明模型有"中间遗忘"问题;如果约束违反次数多,说明模型对硬约束的跟踪能力弱;如果一致性得分低,说明模型的记忆不稳定。
根据短板来选择改进方案。中间遗忘严重就上分块检索,约束跟踪弱就上显式约束列表,一致性差就上记忆摘要加主动确认。对症下药,比盲目换模型有效得多。
我在实际项目里用过这套方法,最深的体会是:长时对话能力不是靠单一技术点解决的,而是模型能力、工程方案、产品设计三者配合的结果。评测基准的价值在于给你一个客观的尺子,让你知道当前方案处在什么水平,以及改进的方向在哪里。但最终能不能做好,还是要回到具体场景里去打磨。