速成课 · No. 13
AI 功能建立在一个非确定性组件之上——同样的输入可能给出不同的输出,而「我试的时候看着挺好」并不是测试。评测就是为这个组件准备的测试套件:已知的输入、被打分的输出、每次改动都跑一遍。它是一门不光鲜的纪律,把一个你「但愿能行」的 demo,和一个你「知道它能行」的产品区分开来。
24 个概念 · 25 张图 · 结尾附速查表
普通代码可以做单元测试,因为同样的输入给出同样的输出。LLM 打破了这一点,所以你需要另一种测试——没有它,你就是在盲飞。
地图:七组共 24 个概念
一张地铁线路图:先看清整条线路,再一站一站地坐过去。
先是三个基础——评测是什么、为什么凭感觉调参行不通、为什么最后那 15% 的质量是大部分的活儿。然后是六组,每章一组:该测什么、评测集、如何打分、agent、离线与在线,以及把它做好。
后面的每个概念都是同一个样子:它的英文名(记住它——这就是术语)、一幅现实生活里的画面、一张图,以及一张带字段的卡片:问题、思路、例子、代价、何时使用和关联。
Eval——给「猜测者」的测试
给一篇作文评分,不像核对一道加法题——没有唯一正确的字符串可以去对照,而且同一个提示词每次产出的作文都略有不同。
普通测试断言的是 output === expected。LLM 是非确定性且开放式的:同一个提示词给出变化的文本,而「正确」往往是一种质量,不是某个精确的字符串。所以断言这套模型就失效了。**评测(eval)**取而代之:一组输入,每个都配有一种方法去评分输出有多好,反复运行——为一个「不会两次返回同样东西」的组件而生的测试。
- 问题
- LLM 是非确定性的:
output === expected会失败,而「正确」是一种质量。 - 思路
- 一组输入 + 给每个输出打分的方法 + 每次改动都跑一遍。
- 例子
- 给客服机器人准备一百个问题,每个都有好答案的标志;结果:「84% 通过」。
- 代价
- 收集用例、搭建打分方法要花时间。
- 何时使用
- 任何链条里有 LLM 的功能。
- 关联
- 建立在 golden set 之上,由 grader 打分,在 CI gate 里运行。
Tuning by Vibes——凭感觉调参的陷阱
一个从不尝菜、只是反复改配方然后碰运气的厨师——他根本分不清昨晚的改动是帮了忙,还是悄悄毁了这道菜。
没有评测,你就凭感觉调提示词:试点什么,瞄一眼几条输出,觉得更好了就发布。陷阱在于你看不见回退——一个修好了某个用例的改动,常常会弄坏你没回头去查的另外三个。评测把「感觉更好了」变成「打了 84 分对 79 分」,这就是工程与猜测之间的区别。
- 是什么
- 改提示词,瞄几条输出,觉得「更好了」就发布。
- 为何糟糕
- 回退是看不见的:修好一个用例,弄坏三个。
- 例子
- 用「看着好点了」代替「84% 对 79%」。
- 解药
- 哪怕是很小的 eval,在改动前后各跑一遍。
- 关联
- Eval-driven Development 的反面。
The Last Mile——80% 很快,95% 才是整个项目
任何东西的初稿都出得很快。把一份粗糙的草稿变成可靠的东西,时间才真正花在这里。
评测要处理的就是这条残酷的事实:一个80% 情况下正确的 demo 一个下午就能做出来;从那里一路磨到 95%,才是大部分的活儿。最后这一段,即最后一英里(last mile),要一个用例一个用例地找——边缘输入、罕见失败——而且只有你在度量时,才能找到并修好它们。评测就是让这段漫长攀登变得可见的仪器。
- 是什么
- 前 80% 的质量来得很快;剩下的 15% 是大部分的活儿。
- 为什么
- 剩下的是边缘输入和罕见失败,只能一个一个地找。
- 例子
- 一个下午的 demo 能跑;在它之上做出产品要几周。
- 后果
- 没有度量,这段攀登是看不见、也管不住的。
- 关联
- 靠 eval、hard cases 和 slicing 变得可见。
评测是你的回退防护网,也是你的规格说明
安全绳让攀岩者敢于尝试难度大的动作,因为失手不会致命——它让大胆的改动变得安全。
一旦有了评测,你就可以改提示词、换模型或重构流水线,并且立刻看出是帮了忙还是添了乱。它在用户之前抓住回退,还悄悄成为你这个功能「好是什么样」的真正规格说明。没有它,每次改动都是一场赌博;有了它,改进就成了一个你真能跑起来的循环。
你没法给非确定性组件做单元测试。评测改为给它打分——而没有评测,每次改动都是猜。
「它好吗?」是没法度量的。评测的第一项真正工作,是把这个含糊的问题变成你能真正打分的具体事项——并且要与你这个功能的任务相匹配。
Eval Criteria——把「好」变成具体的检查
驾照考试不会问「你是个好司机吗?」——它给具体的事项打分:打转向灯了吗、保持在车道里了吗、完全停稳了吗、停进线内了吗。
「质量」太含糊,没法优化。把它拆成可度量的属性——评测标准(eval criteria):答案对不对、是否有来源依据、格式是否有效、是否调用了正确的工具、长度和语气是否合适?每一项都是你能打分的东西。关键功夫在于:挑出对你的任务真正重要的那几项,而不是什么都去测。
- 问题
- 「它好吗?」既没法度量,也没法优化。
- 思路
- 把质量拆成属性:正确性、依据、格式、工具使用、长度和语气。
- 例子
- 「JSON 符合 schema」、「答案依赖检索到的文档」。
- 代价
- 你必须决定什么重要——并诚实地舍弃其余的。
- 关联
- 选标准就是 task-specific metrics;由 grader 去检查。
Task-specific Metrics——让指标与任务相匹配
评价译者看忠实与流畅,评价收银员看速度与准确——量尺用错了,评价就没用。
不同的功能需要不同的指标。RAG 系统:检索到的片段对不对,答案是否忠实于它们?分类器:对照标签的准确率。agent:选对工具了吗,达成目标了吗?摘要:忠实、完整、简洁。挑那些对应你的任务里「失败究竟意味着什么」的指标,否则你优化的就是一个不重要的数字。
- 问题
- 一刀切的指标,测的并不是真正会坏的东西。
- 思路
- 指标反映「失败」对这个具体功能意味着什么。
- 例子
- RAG——片段是否正确与忠实度;分类器——准确率;agent——工具与目标。
- 代价
- 你得针对每个功能把指标想清楚。
- 关联
- 让 eval criteria 落到实处;agent 再加上 trajectory。
Faithfulness vs Correctness——两件不同的事
学生可以写出论证漂亮但错误的答案,也可以写出笨拙但正确的答案。文采和真相是分开的两项分数。
最重要的两个属性常被混为一谈。**正确性(correctness)**是答案究竟对不对;**忠实性(faithfulness)**是它是否有所给上下文的支持、没有凭空编造。一个有依据的系统可以是忠实的(用了来源)却是错的(来源本身就错了),也可以是正确的却不忠实(蒙对了,而不是出自上下文)。把二者分开度量,才能告诉你失败出在哪里。
- 是什么
- Correctness——答案是对的。Faithfulness——它出自所给的上下文,没有编造。
- 为何重要
- 不同的失败要在不同的地方修。
- 例子
- 忠实但错误——修数据或检索。答对了但不忠实——修依据。
- 坑
- 一个笼统的「质量」总分把两者混在一起,掩盖了原因。
- 关联
- RAG 的关键指标对;常由 LLM-as-judge 打分。
Slicing——一个数字隐藏得太多
「舒适」的平均气温,可能掩盖了一间冻人的屋子和一间闷热的屋子。汇总会抹掉你最需要看到的那些情况。
单一的总分是起点,不是全貌。把结果拆开——切片(slicing)——按类别和难度:简单与困难、每种问题类型、每种失败模式——因为一个平平的 85% 可能是简单用例 100%、关键用例 40%。评测的价值在于这种拆解,它告诉你下一步该瞄准哪里。
- 问题
- 平均值抹掉了系统真正出错的那些用例。
- 思路
- 按类别、难度和失败模式分别打分。
- 例子
- 总体 85% = 简单 100% + 困难 40%。
- 代价
- 集合里的用例需要带类别标签。
- 关联
- 指出 last mile 该往哪走;依赖带标签的 golden set。
「它好吗?」不是指标。把质量拆成为你的任务挑选的具体、可打分的属性——并且永远不要相信单一的汇总数字。
评测的诚实程度,取决于里面的样例。数据集——输入及其已知为好的结果——才是真正的资产,大部分用心都花在这里。
Golden Set——带有已知为好结果的输入
老师的标准答案——题目与「正确回答是什么样」配成对,这样评分才一致,而不是看心情。
评测的核心是 golden set:一批有代表性的输入,每个都配有已知为好的答案,或对成功的清晰定义。你就是对着它打分。建它是实打实的活儿——正是在这里你才确定「正确」对你的功能究竟意味着什么——它也是让今后每次改动都可度量的资产。
- 问题
- 没有参照,输出就按心情评分。
- 思路
- 有代表性的输入,每个配一个好答案或清晰的成功标准。
- 例子
「取消我的订阅」→ 必须调用
cancel_subscription;「asdf??」→ 一个澄清问题。- 代价
- 实打实的活儿:为每个用例决定「正确」是什么。
- 关联
- 由 hard cases 和 production sampling 充实;由离线评测运行。
Hard Cases——覆盖边缘和已知的失败
桥梁要用最重的卡车和最糟的风暴来做压力测试,而不只是晴天里的一辆普通轿车。
只有简单、典型输入的集合,会给你一个好看却没用的分数。要刻意放进困难用例(hard cases):含糊的问题、边缘用例、对抗性提示词,尤其是你已经见过的那些失败。每当有 bug 进了生产环境,就把它作为**回归用例(regression case)**加进评测,让它永远不能悄悄回来。集合应当集中在系统最可能出问题的地方。
- 问题
- 一堆简单用例给出的是好看却没用的分数。
- 思路
- 刻意加入含糊的、边缘的、对抗性的,以及所有已经坏过的。
- 例子
- 一个 bug 进了生产环境 → 它的输入成为集合里的永久用例。
- 代价
- 分数会掉——但变得诚实了。
- 关联
- golden set 的一部分;来源是 production sampling。
Production Sampling——采集真实样例
最好的考题来自学生真正考过的那场考试,而不是老师想象他们会问什么。
评测用例最丰富的来源是真实使用:用户实际问了什么,尤其是问了却出了错的。从日志和反馈里挖出真实输入,并入集合。凭空编的样例反映的是你以为会发生什么;生产里的样例反映的是真正发生了什么,包括你绝对想不到的那些凌乱措辞和古怪请求。
- 问题
- 编出来的样例反映的是你的想法,而不是现实。
- 思路
- 从日志和反馈里取输入,尤其是出过问题的地方。
- 例子
- 用户那种你永远想不出来的凌乱措辞。
- 代价
- 你需要有日志,而且用户数据必须先清除个人信息。
- 关联
- 喂给 golden set;信号来自 user feedback。
小而锋利,胜过大而陈旧
五十个精心挑选、直戳真实弱点的问题,比一千个你从不细看的随机问题教给你的更多。
起步不需要成千上万个用例——几十个精心挑选的,覆盖主要行为和已知的失败模式,就足以抓住大部分回退并指导调参。从小处开始,保持诚实,随着你了解系统在哪里出问题再让它长大。一个你真会去跑的评测,胜过一个庞大却不去跑的。
golden set 就是资产。把真实输入与已知为好的结果配对,集中在困难的和坏过的上面,并随着你的了解让它长大。
有了输入和预期之后,你需要一种给每个输出打分的方法。这些方法从廉价精确到灵活易错一字排开——你要选能满足需要的最便宜的那个。
Code-based Graders——精确的、基于规则的检查
批改选择题不需要判断力——答案要么对要么错,机器瞬间就能打分。
当输出受到约束时,用代码做确定性的打分——基于代码的 grader(code-based grader):分类用精确匹配,格式用正则或 schema 检查,agent 看是否调用了正确的工具,抽取看数字是否正确。这些检查便宜、快速、无可争辩。要尽可能多地把你的评测放进这一类——它是最可靠的打分方式。
- 问题
- 明明可以直接比对,却用了昂贵且有争议的判断。
- 思路
- 用代码检查输出:匹配、正则、schema、正确的调用。
- 例子
- 类别标签匹配;JSON 通过 schema;agent 调用了正确的工具。
- 代价
- 只适用于受约束的输出——你没法这样给一篇作文打分。
- 关联
阶梯的第一级;模糊的输出用 LLM-as-judge;agent 用步骤级检查(step-level checks)。
LLM-as-Judge——让模型给模糊的东西打分
一篇作文请来第二位考官,拿着清晰的评分细则——是判断,但有明确标准做引导,所以是一致的。
对开放式输出——这个摘要忠实吗?这个回答有用吗?——没有精确匹配可用,所以你用一个模型来打分,即 LLM-as-judge:把输出、上下文和一份清晰的**评分细则(rubric)**交给第二个模型,让它打分。它能把接近人的判断扩展到成千上万个用例。对于你没法用规则检查的质量,它是标准工具——但也有需要注意的地方。
- 问题
- 开放式输出没法做字符串匹配,而人力没法扩展到成千上万个。
- 思路
- 第二个模型对照上下文和明确的评分细则给输出打分。
- 例子
- 「摘要忠实于来源吗?打 1–5 分,并用一句话解释。」
- 代价
- judge 自己也会出错、也有偏见——必须检验它。
- 关联
- 没有 judge validation 就不可信;常用来度量 faithfulness。
Judge Validation——judge 也得被评判
第二位裁判也可能有偏见——偏爱更长的答案,或听起来更自信的那个——所以你在信任他之前,先拿几个人工判定来检验这位裁判。
LLM judge 有它的失败模式:它可能偏好冗长的答案(verbosity bias),被自信的语气左右,或偏离你的本意。所以要在一个样本上对照人工打分来验证 judge,给它一份带例子的锐利细则,并保持简单。一个你没检验过的 judge,不过是又一个没被度量的模型——在确认它的分数确实跟着你真正在乎的东西走之前,别信它。
- 问题
- judge 喜欢又长又自信的答案,还可能偏离你的本意。
- 思路
- 在信任它之前,先在样本上把 judge 的分数和人工分数做比较。
- 例子
- 几十个用例由人来打分;judge 与之一致——所以可以信任它。
- 代价
- 要做一些人工标注,而且每当 judge 或细则变了,就得重新检验。
- 关联
- LLM-as-judge 的必备搭档;用到人工复核(human review)。
Human Review——人在回路,小剂量
即便有自动打分,厨师依然要尝尝菜——快速抽查一下仪器有没有悄悄出错。
自动打分能规模化,但要定期**亲自去读真实的输出——人工复核(human review)。**抽查一个样本,重点看那些失败,并核对你的指标是否仍然反映真实的质量。人工复核没法覆盖每个用例,但小而定期的一剂,能抓住你的自动分数漏掉的东西——并避免你去优化一个已经偏离现实的数字。
- 问题
- 自动分数可能悄悄偏离真实质量。
- 思路
- 定期读一个真实输出的样本,尤其是失败的那些。
- 例子
- 每周一次,读那些分数掉了的用例,看看你是否同意。
- 代价
- 人的时间——所以小剂量,不是每个用例都做。
- 关联
- grader 阶梯的最后一级;judge validation 的基础。
能确定性打分的地方就确定性打分,其余模糊的交给 LLM judge——并且要验证 judge,因为一个没检验过的评分员不过是又一个猜测。
agent 需要的不只是对最终答案的一个分数,因为它们可能经由一个有问题的过程,得出一个干净的答案。要信任一个 agent,你得度量旅程,而不只是终点。
干净的最终答案,可能藏着一个坏掉的中间
只按最终数字评分的数学考试,会让那个靠两个相互抵消的错误得到结果的学生过关——你对到底发生了什么一无所知。
在多步骤的 agent 里,中间的错误可以通过最终输出的检查,同时却污染了整个过程——它检索到了正确的来源,中途把一个事实张冠李戴,然后写出一份干净却是错的摘要。只给最终答案打分,你就把它放行了。你最需要抓住的那些失败,恰恰是只看终点的检查最看不见的。
Trajectory Evaluation——给路径打分
驾考官会看整段驾驶——每次打灯、每次看后视镜、每次变道——而不只是看你有没有到达那个地址。
对 agent 你要评估它的轨迹(trajectory):每一步,它是否选对了工具、传对了参数、检索到了正确的上下文、推理是否站得住?这能抓住只看最终结果漏掉的坏中间,还能告诉你是哪一步出了问题——比只知道结尾错了要有用得多。agent 的可靠性,正是在这些步骤里建成或丢掉的。
- 问题
- 正确的结尾可能藏着错误的步骤。
- 思路
- 给每一步打分:工具、参数、检索到的上下文、推理。
- 例子
- 第 1–2 步对;第 3 步 agent 取错了上下文——评测点出了第 3 步。
- 代价
- 你得记录并标注每一步,而不只是答案。
- 关联
由**步骤级检查(step-level checks)**构成;由 operational metrics 补充。
Step-level Checks——直接检查工具调用和检索
审计一位研究助理,就是检查他实际调取了哪些来源、发出了哪些调用——而不只是读他最后的备忘录。
agent 的很多行为是具体的,不用判断就能打分:该调用 send_email 时它调用了吗,收件人对吗?它检索到相关文档了吗?它是否守在自己的工具权限之内?这些就是对步骤的确定性检查——步骤级检查(step-level checks),廉价而精确,能精确定位很大一部分 agent 的失败。
- 是什么
- 对 agent 具体步骤的代码检查,不需要 judge。
- 怎么做
- 核对调用了哪个工具、用了哪些参数、检索到了哪份文档。
- 例子
- 调用了
send_email,收件人正确,没有超出任何权限。 - 好处
- 便宜、精确,并且直指出问题的那一步。
- 关联
- 应用在 trajectory 上的 code-based graders。
Operational Metrics——也要度量那些乏味的真相
评价一家快递,不只看包裹到没到,还要看用了多久、试了几次、花了多少钱。
除了正确性,还要追踪 agent 的运行指标(operational metrics):它走了多少步、多频繁地陷入循环或重试、延迟(latency),以及每个任务的成本。一个循环用二十个昂贵的步骤得出正确答案,而三步就够了,这是一个可靠性与成本的问题,你的最终答案分数是显示不出来的。这些数字揭示出那些能跑、却撑不过生产环境的 agent。
- 问题
- 最终答案的分数看不到这个答案花了什么代价。
- 思路
- 统计每个任务的步数、循环和重试、延迟与成本。
- 例子
- 三步就够的地方,用 20 个昂贵的步骤得出正确答案。
- 代价
- 每次运行都需要做追踪。
- 关联
- 补充 trajectory evaluation;在生产中由在线评测盯着。
agent 可能经由一个坏掉的过程,得出一个干净的答案。给轨迹打分——工具、检索、步骤——而不只是终点。
评测有两种,各干不同的活儿:发布之前跑的测试套件,和在生产里持续运行的度量。两者你都需要,因为世界并不等于你的测试集。
Offline Eval——发布之前的闸门
一条试车道,让一辆车在载上第一位乘客之前先经受考验——受控、可重复、在发布前运行。
**离线评测(offline eval)**就是在改动发布之前,拿你的 golden set 去跑:这个新提示词或新模型,在你精心挑选的那些用例上得分更高吗?它受控且可重复,是你抓回退、安全地比较各种方案的地方。这是你要接进开发循环的评测——最好做成 CI 里的闸门,这样任何让分数下降的东西都发布不出去。
- 问题
- 你需要在用户看到之前,就知道一个改动是安全的。
- 思路
- 在新版本上跑 golden set,并与基线比较。
- 例子
- 新提示词:84%,旧的是 79%——可以安全发布。
- 代价
- 它只能看到集合里有的东西——世界要宽广得多。
- 关联
- 在 golden set 上运行;由 CI gate 自动化;与在线评测配对。
Online Eval——度量真实世界
不管试车道多好,车上了真实的路,你仍然要监控——因为真实的路上有试车道从没有过的坑洼。
生产环境的表现,没有哪个离线集合能完全预测:真实用户的措辞你想象不到,输入分布也会漂移。所以你也要在线度量——在线评测(online eval):对线上输出抽样并打分,盯着质量指标,收集用户信号。离线集合证明一个改动可以安全发布;在线度量则告诉你,它上线之后实际在发生什么。
- 问题
- 真实的用户和输入与测试集并不一致。
- 思路
- 对线上输出抽样、打分,并盯着指标。
- 例子
- 一部分生产环境的回答交给 judge;结果显示在仪表盘上。
- 代价
- 生产环境里的打分基础设施,以及 judge 在流量上的成本。
- 关联
- 抓住 drift;收集 user feedback;发现新的 hard cases。
User Feedback——免费的评测信号
一个点赞按钮和一个投诉邮箱,就是一份持续、免费的调查,告诉你这东西对使用它的人是否真的管用。
不管你收不收集,你的用户都在给你打分。把用户反馈信号(user feedback signals)——点赞/点踩、修改、重试、放弃、转人工——抓起来并喂回去。重试或点踩的突增是早期预警;那些具体的失败,会成为明天的评测用例。这就闭合了循环:生产环境教会评测集现实是什么样,评测集又保护下一次发布。
- 是什么
- 点赞/点踩、修改、重试、放弃、转人工。
- 为什么
- 来自真正在用的人的、免费而持续的评分。
- 例子
- 发布后重试的突增,是早期预警。
- 坑
- 信号是有噪声的:是个该去看看的理由,而不是现成的分数。
- 关联
- 在线评测的一部分;转化为 golden set 里的 hard cases。
Drift——盯住缓慢的衰退
一台秤慢慢偏离校准——没有什么戏剧性,只是每次读数都多错一点,直到某天数字就错了。
一个曾经得分很高的系统,会悄无声息地退化——这就是 drift:模型提供方更新了,你的数据变了,使用模式变了。没有持续的在线度量,你是从愤怒的用户而不是从仪表盘那里得知的。随时间追踪质量,让 drift 显现为一个你能采取行动的趋势,而不是一个意外。评测不是一次性的闸门;它是你要持续读取的生命体征。
- 是什么
- 在你这边没有任何改动的情况下,质量缓慢、悄悄地下降。
- 成因
- 提供方的模型更新、数据变化、新的使用模式。
- 例子
- 每周差一点——直到投诉比仪表盘先到。
- 解药
- 随时间追踪质量,并设一个告警阈值。
- 关联
- 由在线评测抓住;新的失败进入 golden set。
离线评测把守发布;在线评测盯着现实。前者证明一个改动是安全的,后者告诉你实际在发生什么。
评测是一种实践,不是一次性的事。功夫在于:在你觉得准备好之前就开始,把度量接进循环,并且不让那个数字变成一个对你撒谎的目标。
Eval-driven Development——先写评测,再调参
你得先校准温度计,再去调烤箱——否则每次调整都是披着进步外衣的猜测。
常见的错误是无休止地调提示词,到后来也许才去建评测。把它倒过来:在优化之前先写一个小评测,让每次改动从一开始就被度量——这就是 eval-driven development。哪怕十个用例也胜过零个。没有评测的调参感觉很有成效,其实多半没有——你在挪动你看不见的数字。
- 问题
- 提示词被调了几周;评测是「以后再说,也许」。
- 思路
- 在第一次优化之前先有个小评测;每次改动都被度量。
- 例子
- 今天十个用例,每次改提示词前都跑一遍。
- 代价
- 起步花一小时,而那时一切还「不能用」。
- 关联
- tuning by vibes 的解药;会长成 CI gate。
CI Gate——把评测做成 CI 里的闸门
测试不通过,代码就不能合并——同样的纪律,也能防止一个悄悄变差的提示词到达用户手里。
有了评测,就在每次改动时自动运行它,分数跌破门槛就拦住发布——这就是 CI gate。它把评测从「想起来才做的事」变成一道始终开着的护栏——AI 版的「测试套件全绿」。「没有评测就不发布」是值得坚持的标准:对 AI 功能做一个没被度量的改动,就是一次没测过的部署。
- 问题
- 「谁想起来才跑」的评测,抓不住一个悄悄变差的提示词。
- 思路
- 每次改动都跑;分数低于门槛就拦住发布。
- 例子
- 改了提示词的 PR,评测通过之前不能合并。
- 代价
- 每个 PR 都跑一遍集合要花时间和钱。
- 关联
- 让离线评测自动化;在生产之前抓住回退。
Goodhart's Law——别让指标变成目标
只为考试而教,会教出考试拿高分却干不了活的学生——分数上去了,它所衡量的东西却没有。
当一个度量变成目标,它就不再是一个好的度量——这就是古德哈特定律(Goodhart's law)。你可能把提示词对你那些具体的评测用例过拟合(overfit),眼看着分数上升而真实质量原地不动。要防范:留出一部分用例不参与调参(held out),用新的生产失败刷新集合,并记住评测只是用户价值的一个代理,而不是价值本身。一个在涨、而用户却没有感觉的数字,是个警告,不是胜利。
- 是什么
- 当一个度量变成目标,它就不再是一个好的度量。
- 表现
- 提示词被拟合到评测用例上:分数上升,质量不涨。
- 例子
- 在集合上涨了 10 分,而用户感觉不到任何差别。
- 防范
- 留出不参与调参的用例、新鲜的生产失败、记住分数只是个代理。
- 关联
- 由 production sampling 和 human review 来制衡。
从小处开始,随失败而成长
好的测试套件不是一次写成的——它是积累出来的,一个 bug 一个用例,直到悄悄覆盖了所有出过错的地方。
别等一个完美、全面的评测——那样你永远发布不了。先为核心行为准备一把用例,然后**每次有东西坏了就加一个。**久而久之,集合恰好沿着你的系统真正出错的轮廓长大,而这正是你想要覆盖的地方。评测随产品一起成熟,它永远不算真正完成。
这些概念如何连在一起
一只不断转动的轮子:每转一圈,集合就更诚实,发布就更安全。
这门课里的一切都属于同一个循环。criteria 说明测什么;golden set 说明拿什么来测;grader(代码、judge、人)给出分数。带 CI gate 的离线评测把守发布,在线评测盯着现实——反馈和 drift——它发现的失败变成新用例,回到集合里。对 agent,你给轨迹打分,而 Goodhart 定律提醒你:分数只是个代理。
- 到底有没有评测——一组带有给输出打分方法的输入?
- 指标是否与任务匹配,按难度和失败类型拆开,而不是一个平平的总分?
- 集合里是否包含那些困难的、怪异的、以前坏过的用例,并且取自真实使用?
- 打分用的是不是最便宜的可靠方法——能确定性的就确定性,不能的就用经过验证的 judge?
- 对 agent,是否给步骤打分了,而不只是最终答案?
- 它是否在 CI 里运行,上线之后你又怎么度量质量?
- 靠读几条输出来调提示词,觉得更好了就发布。
- 只有一个汇总分数,没有按用例类型或难度的拆分。
- 评测集只有简单、典型的输入——没有边缘用例,没有过去的失败。
- 一个从没拿人工打分验证过的 LLM judge。
- 没有生产监控——质量下降你只会从一封投诉里得知。
- 一个由真实输入和已知为好的结果构成的 golden set,集中在困难用例上。
- 与任务匹配的指标,用最便宜的可靠方法打分,并且做了拆分。
- 对 agent 做步骤级打分,对模糊的部分用经过验证的 judge。
- 评测是一个 CI gate,回退会新增一个用例,而不是溜过去。
- 在线度量和用户反馈把新的失败喂回集合。
速查表:全部 24 个概念
基础
- Eval评测
输入 + 给输出打分的方法 + 每次改动都跑一遍。
- Tuning by Vibes凭感觉调参
瞄几条输出就发布。回退依然看不见。
- The Last Mile80% → 95%
80% 一个下午;95% 是大部分的活儿,一个用例一个用例地来。
该测什么
- Eval Criteria可度量的属性
把「好」拆成具体、可检查的属性。
- Task-specific Metrics与任务匹配的指标
RAG、分类器、agent、摘要——各有各的量尺。
- Faithfulness vs Correctness有依据 vs 答得对
是出自上下文吗——又对不对?分开度量。
- Slicing拆解
按类别和难度打分:平均值会藏住失败。
评测集
- Golden Set评测数据集
真实输入加已知为好的结果。核心资产。
- Hard Cases边缘、对抗、回归
困难的、怪异的、已经坏过的——特意放进集合里。
- Production Sampling来自生产的用例
来自日志和反馈的输入,尤其是失败。
如何打分
- Code-based Grader确定性检查
匹配、正则、schema、正确的调用。便宜而精确。
- LLM-as-Judge用模型当评分员
第二个模型对照细则给模糊的东西打分。
- Judge Validation检验 judge
信任 judge 之前,先把它与人比一比。
- Human Review人工抽查
小而定期的一剂:读真实的输出。
Agent
- Trajectory Evaluation给路径打分
给每一步打分,而不只是最终答案。
- Step-level Checks工具调用检查
对工具调用、参数和检索的代码检查。
- Operational Metrics步数、延迟、成本
一个任务花了多少步、循环、秒数和美元。
离线与在线
- Offline Eval发布前
在新版本上跑 golden set——发布前的闸门。
- Online Eval在生产中
对线上输出抽样、打分,盯着质量指标。
- User Feedback Signals用户信号
点赞、修改、重试、放弃——免费的评测信号。
- Drift质量漂移
质量随时间悄悄下降。只有监控能抓住它。
把它做好
- Eval-driven Development先写评测
在第一次优化之前先有个小评测。
- CI GateCI 里的评测
每次改动都跑评测;分数下降——发布被拦住。
- Goodhart's Law度量变成目标
变成目标的度量就不再度量。分数只是个代理。
评测不是一次性的测试。它是那个循环——度量、找出失败、把它们叠回去——把一个非确定性组件变成你能信任并能改进的东西。