你的评估仪表盘是一片绿色。单轮准确率(turn-level accuracy)保持在 95%,LLM 裁判(LLM judge)与你的标注人员意见一致,每一项回归测试在上线前都顺利通过。然后,一名用户提交了一个 bug:在第九轮对话中,智能体推荐了一个 Postgres 索引,但这直接违反了用户在第一轮中设定的“我们使用的是 DynamoDB”这一约束。你调出对话记录。每一轮对话如果拆开来看,都是合理的回复。但如果把整个对话作为一个整体来看,那就是一场灾难。
这是单轮评估(turn-level evaluation)的核心谎言。它对“请求-响应”对进行评分,因为这是标注成本最低的单位,并且它默认假设一段对话仅仅是你可以取平均值的独立轮次的组合。事实并非如此。第九轮的响应是以之前发生的一切为条件的,而那些真正触达用户的失败几乎从未存在于单轮对话内部——它们存在于轮次之间的缝隙中,在那里状态丢失、假设变得僵化,微小的错误复合成一个完全错误的最终答案。
如果你只记住一件事:一个单轮准确率为 95% 的系统,其每个会话(session)的准确率并不是 95%。它要糟糕得多,而且随着交流的增加,差距会不断扩大。大多数评估框架在结构上对定义多轮智能体是否可用的故障模式是完全盲目的。
将 95% 变为 77% 的算术题
从累积效应开始。如果每一轮独立成功的概率是 0.95,那么一个五轮的会话成功的概率是 0.95⁵ ≈ 0.77。将单轮准确率提高到 99%,五轮成功的概率会回升到 0.95 左右。一旦你将足够多的轮次串联在一起,那 1% 的单轮可靠性差距,就是“通常可用”与“通常失败”之间的天壤之别。
而且,独立性还是一个乐观的假设。实际对话的情况比乘法计算的还要糟糕,因为错误不仅会累加,还会传播。在第二轮引入的 2% 的偏差不会仅仅停留在 2%。如果模型在错误的假设上继续构建而不是重新审视它,那么这个种子到第十轮时可能会演变成 40% 的失败率。审计生产环境对话记录的从业者一致发现,70–90% 的多轮错误都可以直接追溯到 之前 的某次回复,而不是当前的这一轮。模型会死磕早期提到的某些信息——比如在第一轮中提到过一次“我正在做一个 Python 项目”——并在用户早已切换到另一个文件、另一个服务、甚至完全不同的问题之后,仍然在沿用那个信息。
单轮评估无法察觉到这些。每一轮都根据其直接的提示词进行评分,错误的第九轮在继承了中毒的上下文后,局部看起来并无大碍,评分依然稳步通过。你衡量了局部正确性,并将其称之为质量。但两者并非一回事。
为什么平均单轮得分在统计学上是行不通的
还有一个更微妙的问题,这不仅仅是覆盖范围的缺失,而是一个数学错误。主流范式是计算每一轮的得分,然后在整个对话中取平均值。这种平均处理默认假设每一轮都是独立样本。但事实恰恰相反:第 t 轮是以到 t 为止的全部历史为条件的,而用户的下一条消息又是由模型刚刚说了什么而决定的。
当你像对待独立观察样本一样,对单轮得分进行标准的统计分析时,自相关性(autocorrelation)会破坏你的结论。最近的一项分析估计,对话分析中 42% 的单轮发现可能是伪造的——这是将相关轮次视为独立抽取样本的结果。你不仅错失了失败案例,还在产生关于哪些提示词更改有效、哪些无效的错误结论,并基于此发布产品。
聚合也会在结构上掩盖灾难。一个前九轮表现完美、但在第十轮犯下致命错误的会话,在平均分下会得到 90 分。但那次对话是彻底失败的——用户得到了错误答案并离开了。平均分奖励了局部的流畅性,却埋没了那个真正决定结果的轮次。看起来最令人安心的指标,往往是最具欺骗性的。
轨迹级评估究竟在衡量什么
解决办法是将“对话”作为评估单位,而不是单轮。具体来说,这意味着根据仅存在于轨迹级别(trajectory level)的特征来对完整的对话记录进行评分:
- 目标达成(Goal completion)。 会话是否完成了用户最初想要做的事情,而不管单轮得分如何?这是与用户留存率相关的指标。令人鼓舞的是,当领域专家标注目标达成情况,并以此校准 LLM 裁判时,三方一致率在 82–83% 左右——这足以实现大部分自动评估,同时对尾部案例进行人工抽检。
- 跨轮次一致性(Consistency across turns)。 第九轮是否违反了第一轮设定的约束?这恰恰是 LLM 裁判最薄弱的地方:它们奖励局部的流畅和文风的一致,却系统性地低估了跨轮次的语义矛盾,尤其是在长对话中。一个简单的“给这段对话打 1–10 分”的裁判会忽略 DynamoDB 的冲突,因为每一轮读起来都很顺畅。你必须明确提示裁判去寻找矛盾,或者将状态外部化,使矛盾的检测变得机械化。
- 状态追踪(State tracking)。 智能体是否保留了早先确立的事实、约束和实体?一个有前景的方向是将对话状态外部化到一个持久化结构中——一个随轮次更新的增量语义知识图谱——这样“智能体是否违反了已知约束”就变成了针对明确状态的检索,而不是裁判必须从序列化历史中感知的某种直觉。
- 里程碑 / 部分分(Milestone / partial credit)。 在一个十轮的任务中采用二进制的通过/失败会丢掉你最需要的信号。根据达到的最远里程碑给予评分,这样一来,一个在偏离轨道前已经完成了 80% 目标的会话,就能与一个在第二轮就彻底失败的会话区分开来。这种梯度数据能告诉你 哪里 需要修改提示词或工具。
基准测试生态系统一直在向这一方向靠拢。像 MT-Eval、MultiChallenge、StructFlowBench 和 DynaEval 这样的测试集分别探测不同的轨迹级属性——指令保留、多约束遵循、结构流向、对话连贯性——正是因为单轮得分无法预测其中任何一项。这些文献中反复出现的实证结果非常直接:多轮性能的下降方式是单轮估算完全无法预见的。你无法从单轮质量中推断出整个会话的质量。
在不烧钱的情况下构建对话级评估 (Evals)
显而易见的异议是成本。轨迹级 (Trajectory-level) 的标注听起来意味着要付钱让人工阅读整个对话,这比标注孤立的对话轮次 (Turns) 要昂贵得多。但事实并非必须如此。只需几招就能让成本保持在可控范围内:
重放真实会话记录,而不是手动编写测试用例。 这是最具杠杆作用的改变。大多数团队手动编写单轮 (Single-shot) 评估提示词,是因为多轮案例编写起来很繁琐 —— 但这其实是本末倒置。你的日志中已经存有数千个真实的多轮会话。对它们进行采样,通过候选模型或提示词进行重放,并评估生成的轨迹。这样,你的评估集就会成为生产环境分布的忠实镜像,而不是一堆测试用户从未真正创建过的情景的合成单轮用例。会话记录是免费的;你已经在推理成本中支付过这笔费用了。
对轨迹进行监测,而不仅仅是评判文本。 许多轨迹质量在完全不需要 LLM 评判的情况下就可以通过机械化检查。记录工具调用参数,并根据目标 JSON Schema 进行验证。跟踪 Agent 是否在下一步规划中真正使用了工具的输出,还是忽略了它并产生幻觉。观察每轮的输入 Token 数 —— 在健康的会话中,它们大致呈线性增长;二次增长则预示着历史记录正在膨胀,状态即将崩溃。统计步骤并检测循环。这种遥测手段成本低廉、具有确定性,并且能在你花费任何评判调用之前捕捉到大量失败情况。
将 LLM 作为评判者 (LLM-as-judge) 的用法保留给只有判断力才能评估的方面,并在信任它之前,先对照一小部分人工标注的数据集进行校准。将其用于目标完成度和跨轮一致性 —— 这些模糊的、整体的属性 —— 而对于所有机械性的东西,则依赖确定性检查和状态查找。由于评判者默认会低估矛盾的严重性,因此应给它提供明确的先前状态进行对比,而不是要求它从头开始重新推导整个对话。
对尾部数据采样,而不是平均值。 你不需要对每个会话都进行轨迹评估。你需要对长会话、包含大量工具调用的会话以及轮次级评分互不一致的会话进行过度采样 —— 这些正是轨迹失效集中的地方。几百个精心挑选的重放会话带给你的启发,将远超一万个平均轮次评分。
为旅程评分,而非仅为脚步评分
一个令人不安的结论是,一个漂亮的轮次级仪表盘可能会产生负面影响。它带给你的信心与你彻底衡量错误事物的程度成正比,它将不断累积的、丢失状态的、易产生矛盾的行为洗白成一个令人安心的绿色数字。该指标不仅是不完整的 —— 它的聚合方式在统计学上也是不可靠的,它掩盖了决定会话成败的那些灾难性的单轮错误。
如果你的 Agent 进行的是真实的对话,那么你的评估套件中至少有一个评估必须将对话视为原子单位:重放真实会话记录,对目标完成度和跨轮一致性进行评分,显式地跟踪状态,并根据会话进行的程度给予部分分数。保留轮次级指标 —— 它们对于调试轨迹在 哪里 断裂非常有用。但不要再误以为它们的平均值就是唯一重要问题的答案,即用户是否得到了他们想要的东西。你的用户体验的是整个对话。你的评估也应该如此。
会员专享
余下内容仅对会员开放。
会员可读完整内容 —— 每一个公开发布的观点背后,那些框架、决策与推理的全貌。
- —完整文章,包含未公开存档的部分
- —可落地的工作框架,附带权衡与决策依据
- —新文章抢先看,先于公开发布
随时取消 · 一次订阅,畅读全部