@sermakarevich:一篇写给所有基于大语言模型(LLM)构建软件的交付者、采购者与签字把关人的文章:工程师、产品经理……

X AI KOLs Timeline 论文

摘要

一份用通俗语言撰写、并附有来源支撑的 LLM 评测指南:如何围绕输入、标准答案(gold answer)与评分器(grader)搭建可复现的评测闭环;为何未经校验的评判模型(judge model)是 AI 团队最常见的一种自我欺骗方式;以及如何为代码评分与模型评分(针对检索系统和智能体系统)给出带误差范围的可信数据。

一篇写给所有基于大语言模型(LLM)构建软件的人——无论你是负责交付、采购,还是最终签字拍板:工程师、产品经理,还是 CEO。全文用通俗易懂的语言撰写,从全局视角层层深入到具体细节。 https://t.co/YaP414vR0u
查看原文
查看缓存全文

缓存时间: 2026/10/04 01:06

Evals:如何判断一个 AI 系统是否真的好用

这是一篇写给所有发布、采购或为基于大语言模型(LLM)的软件签字放行的人看的文章:工程师、产品经理,以及 CEO。用大白话写成,从全局到细节逐层展开。文中每个数字都来自文末列出的来源:我们自己关于一个小客服助手的可运行教程,或已发表的论文。

快速理解(其他都不读,就看这一节)

Eval(evaluation,评测)是一种可重复的测试,它用一个你可信的数字告诉你:这个 AI 系统是否做到了你要的事,以及某次改动是让它变好还是变差。

为什么需要它:语言模型的失效方式和普通软件不同。普通软件要么正常运行,要么崩溃。语言模型却可能给出一段流畅、自信、格式漂亮但完全错误的回答。读完一条好回答,对下一条一百条毫无帮助。Eval 用「在我们关心的用例里它通过了 70%,上下浮动约 12 个百分点,且新版本没有可测量的提升」取代了「demo 里看着挺正常」。

它是怎么运作的,四个步骤:

  • 收集真正重要的输入,并在每条输入旁写下正确答案。以我们的示例为例:一家自行车商店的 80 条客服工单,每条都标注了正确分类,以及一条好回复必须包含的事实。

  • 让系统跑完所有输入,并保留输出。

  • 用评分器(grader)给每条输出打分。评分器可以是代码里的一条规则、一个充当裁判的模型,或者一个人。

  • 把所有分数汇总成一个带误差范围的数字,并与上一版本比较。

什么时候用:发布前(它到底能不能用?)、每次改动前(我们有没有弄坏什么?)、以及发布后(在真实流量上它还在起作用吗?)。

重要提示: 评分器本身就是你必须测试的系统的一部分。一个只在 60% 的情况下和人类判断一致的裁判模型,会在产品不行的时候告诉你一切正常。

对我们的含义: 每个 eval 都要检查两个数字:产品有多好,以及评分器有多好。两个都要看。

为什么重要: AI 团队最常见的自我欺骗方式,就是拿一个未经检验的评分器给出的自信数字。

本文的其余部分会逐层放大,每一层回答上一层的一个问题。

  • 第 0 层 · 完整的闭环,在一条工单上跑一遍

  • 第 1 层 · 我们到底在测量什么?·(输入、标准答案、那个数字)

  • 第 2 层 · 什么会出错?·(先看数据)

  • 第 3 层 · 由代码构成的评分器 ·(便宜、精确、看不见语义)

  • 第 4 层 · 用模型当评分器 ·(灵活、有偏、必须验证)

  • 第 5 层 · 诚实的数字 ·(误差范围、A/B、样本量)

  • 第 6 层 · 由多个部件组成的评分体系 ·(检索、agent、成本、可靠性)

  • 第 7 层 · 公开基准 ·(排行榜能告诉你什么、不能告诉你什么)

  • 第 8 层 · 让它成为习惯 ·(门禁、监控、何时该重新检查)

  • 后记 · 工具与方法、决策指南,以及参考文献

第 0 层:完整的闭环,在一条工单上跑一遍

放大范围:全部内容。问题:当 eval 跑起来的时候,它长什么样?

全文的贯穿示例是一个小型客服助手,服务于一个虚构的在线自行车与露营用品商店。它有三个部分,后面我们会分别用不同方式评分:

  • 分流(triage):读取一条工单,把它归入 12 个类别之一(退货、物流、保修……),并给出优先级。

  • 回答(answer):在商店政策手册中找到相关页面,写出一份引用这些页面的回复。

  • Agent:在政策规则的约束下调用工具,查询订单、发放退款、并进行升级处理。

这是一条工单走完闭环的样子。

输入:「我上班快迟到了,这事必须马上处理。我上周把自行车退了,但退款到现在还没到账。你们的政策白纸黑字写着退款 5 个工作日内处理……」

系统输出(分流): 退货。标准答案: 退货。得分: 1 分,满分 1 分。

系统输出(回答): 一段礼貌的四段式回复,引用了退货条款,同时提到了两项必备事实:退款需 5 个工作日,且二手商品适用 15% 的重新上架费。

现在有三个评分器来看这条回复:

  • 代码规则。它问的问题:回复是否引用了手册章节?结论:是。

  • 代码规则。它问的问题:是否提到了两项必备事实?结论:是,没有遗漏。

  • 模型裁判。它问的问题:回复是否声称了手册中没有写的内容?结论:不通过:它凭空捏造了「最多 15 个工作日的总宽限期」。

这就是全部核心思想。两个廉价的代码检查说这条回复没问题。裁判则发现了一个本来会发给客户的捏造数字。后面所有层要做的,就是让这个闭环在大规模下也值得信任。

从第 0 层带出来的东西:

  • 一个 eval 就是:输入、系统、评分器、数字。不多不少。

  • 不同的评分器回答不同的问题。「引用了章节」和「没有捏造」并不是同一个检查。

  • 一段流畅的回复可以通过所有表面检查,同时依然是错的。

第 1 层:我们到底在测量什么?

放大范围:闭环的第 1 步和第 4 步。问题:输入和「正确答案」从哪里来?那个数字又是什么?

输入。 这些用例应该像真实流量一样,包括那些别扭的用例。我们的 80 条工单是基于「客户画像 × 主题 × 场景」的网格生成的,所以愤怒的客户、含糊的提问、一单多问题的情况都会出现。Anthropic 关于 agent eval 的指南建议从 20 到 50 个任务起步,且这些任务要来自真实的失败案例,而不是想象中的理想路径(Grace et al., 2026)。

标准答案。 对每条输入,我们要写下「正确」意味着什么:正确的分类、回复必须依据的手册章节,以及必须陈述的那两三个事实。由于我们的工单本身就是基于手册生成的,标准答案在构造上就是正确的。在真实产品中,它们来自领域专家。

两堆数据。 我们把用例拆成 dev 集(20 条工单,用于调提示词和评分器)和 test 集(60 条工单,只用于报告结果)。如果你用报告结果的那堆数据来调参,那个数字就会美化你。

那个数字。 对分流来说是准确率(正确分类的工单占比)。对回复来说是通过率(没有失败的回复占比)。对 agent 来说,是以正确数据库状态结束的任务占比。每次实验只报一个数字,永远在 test 集上报告,永远带上误差范围(第 5 层)。

四个经常被搞混的词:

  • Eval(评测)。测量的是:你的系统在你的数据上的表现。例如:我们的助手在 60 条工单上的表现。

  • Benchmark(基准)。测量的是:某个模型在公开任务上的表现。例如:GSM8K 数学、SWE-bench 编程。

  • Test(软件测试)。测量的是:某个函数是否返回了预期值。例如:JSON 能否解析、是否不崩溃。

  • Monitoring(监控)。测量的是:发布后真实流量的表现。例如:每天抽样真实工单并打分。

一个在公开基准上得分很高的模型,依然可能回答错误你的客户。基准测量的是引擎,eval 测量的是这辆车在你自己的路上跑得怎么样(Husain & Shankar, 2025)。

从第 1 层带出来的东西:

  • 带标准答案的输入是整个流程中最宝贵的资产。它们成本高昂,但正是它们让其他一切都成为可能。

  • 保留一堆 dev 数据用于调参,保留一堆 test 数据用于报告。

  • 基准是关于模型的。Eval 是关于你的产品的。

第 2 层:什么会出错?先看数据

放大范围:打分这一步。问题:评分器到底该找什么?

在搭建任何自动评分器之前,先把输出读一遍。每一位有经验的从业者说的都是同一件事(Husain, 2024;Husain, 2025;Shankar et al., 2024)。把一百到两百条输出一条一条读下来,给每个失败写一句简短笔记,然后把这些笔记归类成一份带计数的失败类型清单。这叫 错误分析(error analysis),它有两个步骤,各有名字:开放式编码(open coding,自由笔记)和轴心式编码(axial coding,归类分组)。

这一步在我们 60 条测试回复上的结果:

  • 通过的回复:60 条中有 34 条

  • missing_required_fact · 15

  • unsupported_claim · 12

  • wrong_section_retrieved · 8

  • did_not_answer · 5

  • wrong_value · 2

  • over_promise · 1

勉强过半的回复通过了。最大的两个问题是遗漏事实和捏造主张。从 demo 里谁也猜不到这一点。这份清单就是我们接下来要搭建的每一个评分器的规格说明:按出现频率排序,每种失败类型对应一个评分器。

重要提示: 失败清单来自阅读输出,而不是来自想象。

对我们的含义: 任何 eval 工作的第一周,都应该是人坐在一个专门的查看工具里读对话记录,而不是工程师在搭框架。

为什么重要: 为一个从未发生的失败类型而建的评分器,会给出一个让人安心的数字,却漏掉真正发生的那些。凡是 eval 工作停摆的团队,几乎都是跳过了这一步(Husain, 2025)。

一个相关的发现:你的标准会随着打分而变化。Shankar et al.(2024)称之为 标准漂移(criteria drift)。对样例打分会让评分标准更清晰,而更清晰的标准又会改变之前的评分。预期会有两三轮。这不是流程出了问题。

从第 2 层带出来的东西:

  • 失败类型清单就是计划。先为出现频率最高的失败类型建评分器。

  • 阅读输出是价值最高的活动,也是最常被跳过的活动。

  • 预期标准会在打分过程中发生变化。

第 3 层:由代码构成的评分器

放大范围:评分器的一种。问题:一条普通的规则能测什么、不能测什么?

代码评分器是用普通代码写成的规则。它免费、即时、每次给出同样的答案。凡是它能测的,都用它来测。

精确答案。 分流只有一个正确标签,所以我们数匹配数。

  • accuracy:0.700 · macro F1:0.697

十条工单里有七条被正确分类。Macro F1 在全部 12 个类别上等权平均,所以稀有类别和常见类别一样重要。这两个数字很接近,说明错误是分散的,而不是集中在某一个类别上。

自由文本的规则检查。 对回复来说没有唯一的正确文本,但回复必须遵守一些规则:

  • 非空 · 100% 通过

  • max_words_150 · 17% 通过

  • no_banned_promises · 92% 通过

只有 17% 的回复控制在 150 词以内。这个应用话太多了,而且根本不需要裁判就能发现这一点。像 IFEval(Zhou et al., 2023)这样的公开基准,完全建立在这类可验证规则之上(「答案必须恰好用三个要点」)。

必备事实。 我们检查每个标准事实是否出现在回复中。这能零成本地抓住头号失败类型——遗漏事实。

相似度分数。 重叠度量(ROUGE、BLEU)和 embedding 相似度会把回复和参考文本作比较。在我们的回复上,embedding 相似度区分好回复和坏回复的 AUC 为 0.709(0.5 相当于抛硬币,1.0 是完美)。它适合用来发现版本之间发生了变化,但判断一条回复是否正确则毫无用处。

重要提示: 相似度能发现变化,但它不评判质量。

对我们的含义: 把它当作廉价的漂移警报用,绝不要当作头条数字。

为什么重要: 一条错误回复如果用词和正确回复相同,就会得到高分。Eugene Yan 的综述(2024)以及 ROUGE/BLEU 的原始文献都详细记录了这一局限。

代码评分器的上限,用一个数字就能说明。 我们的回复里只有 11.7% 通过了全部代码检查,而代码检查没有抓到任何一条捏造的主张。第 0 层那条回复通过了所有规则,同时捏造了一个 15 天的宽限期。规则看得见形式;看不见语义。

从第 3 层带出来的东西:

  • 凡是有确定答案的,都用代码评分器:标签、格式、必备事实、禁用措辞。

  • 相似度衡量的是漂移,不是质量。

  • 规则看不见捏造的主张。那需要一个「读者」。

第 4 层:用模型当评分器,以及如何验证它

放大范围:另一种评分器。问题:当评分器本身就是一个模型时,我们怎么知道它是对的?

模型裁判(通常叫 LLM-as-judge)是另一个读取输出并为其打分的模型。它能读出语义,所以能抓到那个捏造的 15 天宽限期。它同样是一个语言模型,所以也具备语言模型的所有失效方式。这一层是最长的,因为大多数 eval 项目正是在这里出问题。

4.1 如何向裁判提问

从业者共识和研究文献对提问方式有一致的看法:

  • 每种失败类型一个问题,答案是或否。 「这份回复是否包含手册摘录中没有支持的主张?」而不是「给质量打 1 到 5 分」。二元问题对人类标注者来说更快、更可复现,也更容易检查(Husain & Shankar, 2025)。只有当所有问题的回答都是「否」时,输出才算通过。

  • 要求给出证据。 裁判要引用出问题的那句话。这样它的结论可以让人在几秒钟内复核。

  • 给它上下文。 看不到手册的裁判,不可能知道什么是「无依据」的。

Cho et al.(2026)在摘要任务上直接验证了这一点(「Ask, Don’t Judge」)。把打分拆解成针对具体错误的是/否问题,在所有数据集上都胜过了流行的整体式 G-Eval 方法(与人类的 Spearman 相关系数:SummEval 上为 0.563 对 0.514)。他们最能说明问题的例子:一条植入了三处事实错误的摘要,在整体式裁判那里拿到了满分 5.0,而在基于问题的裁判那里只有 1.57。他们还发现:往提示词里堆更多指令,最终会让裁判变差,而不是变好。

4.2 验证裁判:我们自己的数字

我们手工标注了全部 60 条测试回复(即「参照标准」),然后运行裁判:

  • 参照标准判定通过:34 · 裁判判定通过:42

  • 两者在 60 条回复中有 36 条一致(60%)

  • 裁判抓到的坏回复:26 条中的 10 条

  • kappa:0.15

60% 的一致率听起来可以接受。其实不行。如果裁判对所有东西都干脆回答「通过」,它与参照标准的一致率也会有 57%,因为大部分回复本来就是通过的。Cohen’s kappa 正是用来修正这一点的:它衡量的是超出随机水平的一致程度。0 是随机水平,1 是完全一致,0.6 是一个可以用来把关发布的裁判的常用门槛,0.8 则是可以让它无人监督运行的门槛。我们的裁判只有 0.15。它过于宽松(本该通过的 34 条里放过了 42 条),而且坏回复里抓到的不到一半。

重要提示: 当大多数输出都通过时,原始一致率会误导人。请报告 kappa,或者分别报告裁判抓到了多少坏输出、以及误判了多少好输出。

对我们的含义: 裁判就是一个分类器。在信任它之前,至少用几十个人类标注的案例来测量它,并且在它产生的每一个产品数字旁边都报告这个测量结果。

为什么重要: 有了这个裁判,一个把捏造主张翻了一倍的版本,在头条通过率上可能看不出任何变化。

补救办法是在 dev 集上迭代:把该失败类型的具体样例加进裁判提示词、收窄问题、把标准事实作为参考给它。教程里针对「遗漏事实」这个问题的裁判就是这样达到了可用水平;而「无依据主张」这个问题没有做到,被交给了一个专门的检测器(4.5)。

4.3 裁判已知的偏误

裁判以可预测的方式失效。每一种偏误都有已发表的测量结果,以及廉价的缓解办法。

  • 位置(Position)。现象:在两两对比中,裁判更偏好先展示的那个回答。证据:交换顺序后,很大一部分配对的结论会发生翻转(Wang et al., 2024);2025 年一项 RAG 与 GraphRAG 的对比发现,GraphRAG 早先的「胜利」有相当一部分在交换顺序后就消失了(Han et al., 2025)。缓解:两种顺序都打分,只有两边一致才算胜出。

  • 长度(Length)。现象:无论内容如何,更长的回答总是赢。证据:……

相似文章