fedorthinks

速成课 · No. 13

AI 功能建立在一个非确定性组件之上——同样的输入可能给出不同的输出,而「我试的时候看着挺好」并不是测试。评测就是为这个组件准备的测试套件:已知的输入、被打分的输出、每次改动都跑一遍。它是一门不光鲜的纪律,把一个你「但愿能行」的 demo,和一个你「知道它能行」的产品区分开来。

24 个概念 · 25 张图 · 结尾附速查表

§ 01

普通代码可以做单元测试,因为同样的输入给出同样的输出。LLM 打破了这一点,所以你需要另一种测试——没有它,你就是在盲飞。

地图:七组共 24 个概念

一张地铁线路图:先看清整条线路,再一站一站地坐过去。

先是三个基础——评测是什么、为什么凭感觉调参行不通、为什么最后那 15% 的质量是大部分的活儿。然后是六组,每章一组:该测什么、评测集、如何打分、agent、离线与在线,以及把它做好。

后面的每个概念都是同一个样子:它的英文名(记住它——这就是术语)、一幅现实生活里的画面、一张图,以及一张带字段的卡片:问题、思路、例子、代价、何时使用和关联。

BasicsEvalTuning by vibes80% → 95%What to measureEval criteriaTask metricsFaithful vs correctSlicingEval setGolden setHard casesProduction samplingGradingCode-based gradersLLM-as-judgeJudge validationHuman reviewAgentsTrajectory evalStep-level checksOperational metricsOffline / onlineOffline evalOnline evalUser feedbackDriftDoing it wellEval-driven devCI gateGoodhart's law
上面是基础;下面是六组——第 2–7 章按它们展开。

Eval——给「猜测者」的测试

给一篇作文评分,不像核对一道加法题——没有唯一正确的字符串可以去对照,而且同一个提示词每次产出的作文都略有不同。

普通测试断言的是 output === expected。LLM 是非确定性且开放式的:同一个提示词给出变化的文本,而「正确」往往是一种质量,不是某个精确的字符串。所以断言这套模型就失效了。**评测(eval)**取而代之:一组输入,每个都配有一种方法去评分输出有多好,反复运行——为一个「不会两次返回同样东西」的组件而生的测试。

Ordinary code: deterministicInputFunctionOutputalways 42assert ==pass / failLLM: non-deterministicInputLLManswer Aanswer Banswer CScorerubric · 0–1same input, different text → score the quality, don't match a string
普通代码:一个输入,一个输出,断言。LLM:一个输入,不同的回答——所以你要给它们打分,而不是去匹配某个字符串。
ConceptEval· AI 系统评测
问题
LLM 是非确定性的:output === expected 会失败,而「正确」是一种质量。
思路
一组输入 + 给每个输出打分的方法 + 每次改动都跑一遍。
例子
给客服机器人准备一百个问题,每个都有好答案的标志;结果:「84% 通过」。
代价
收集用例、搭建打分方法要花时间。
何时使用
任何链条里有 LLM 的功能。
关联
建立在 golden set 之上,由 grader 打分,在 CI gate 里运行。

Tuning by Vibes——凭感觉调参的陷阱

一个从不尝菜、只是反复改配方然后碰运气的厨师——他根本分不清昨晚的改动是帮了忙,还是悄悄毁了这道菜。

没有评测,你就凭感觉调提示词:试点什么,瞄一眼几条输出,觉得更好了就发布。陷阱在于你看不见回退——一个修好了某个用例的改动,常常会弄坏你没回头去查的另外三个。评测把「感觉更好了」变成「打了 84 分对 79 分」,这就是工程与猜测之间的区别。

the same 12 cases, before and after a prompt changev1v2✓✓✗✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✗✓✗✓✗✓you eyeballed these3 regressions you never sawan eval re-checks every case on every change
新提示词修好了你看过的那个用例,却悄悄弄坏了另外三个。靠眼睛瞄是看不出来的。
PitfallTuning by Vibes· 凭感觉调参
是什么
改提示词,瞄几条输出,觉得「更好了」就发布。
为何糟糕
回退是看不见的:修好一个用例,弄坏三个。
例子
用「看着好点了」代替「84% 对 79%」。
解药
哪怕是很小的 eval,在改动前后各跑一遍。
关联
Eval-driven Development 的反面。

The Last Mile——80% 很快,95% 才是整个项目

任何东西的初稿都出得很快。把一份粗糙的草稿变成可靠的东西,时间才真正花在这里。

评测要处理的就是这条残酷的事实:一个80% 情况下正确的 demo 一个下午就能做出来;从那里一路磨到 95%,才是大部分的活儿。最后这一段,即最后一英里(last mile),要一个用例一个用例地找——边缘输入、罕见失败——而且只有你在度量时,才能找到并修好它们。评测就是让这段漫长攀登变得可见的仪器。

80%95%0found case by case:edge inputs, rare failuresan afternoonmost of the workeffort →quality ↑
到 80% 是一个下午的快速攀升。从 80% 到 95% 是漫长的活儿,一个用例一个用例地来。
ConceptThe Last Mile· 80% → 95%
是什么
前 80% 的质量来得很快;剩下的 15% 是大部分的活儿。
为什么
剩下的是边缘输入和罕见失败,只能一个一个地找。
例子
一个下午的 demo 能跑;在它之上做出产品要几周。
后果
没有度量,这段攀登是看不见、也管不住的。
关联
靠 eval、hard cases 和 slicing 变得可见。

评测是你的回退防护网,也是你的规格说明

安全绳让攀岩者敢于尝试难度大的动作,因为失手不会致命——它让大胆的改动变得安全。

一旦有了评测,你就可以改提示词、换模型或重构流水线,并且立刻看出是帮了忙还是添了乱。它在用户之前抓住回退,还悄悄成为你这个功能「好是什么样」的真正规格说明。没有它,每次改动都是一场赌博;有了它,改进就成了一个你真能跑起来的循环。

Prompt editModel swapPipeline changeEvalsame golden setHelpedship itHurtregression caughtnow
任何改动——提示词、模型、流水线——都过同一套评测,立刻显示是帮了忙还是添了乱。

你没法给非确定性组件做单元测试。评测改为给它打分——而没有评测,每次改动都是猜。

§ 02

「它好吗?」是没法度量的。评测的第一项真正工作,是把这个含糊的问题变成你能真正打分的具体事项——并且要与你这个功能的任务相匹配。

Eval Criteria——把「好」变成具体的检查

驾照考试不会问「你是个好司机吗?」——它给具体的事项打分:打转向灯了吗、保持在车道里了吗、完全停稳了吗、停进线内了吗。

「质量」太含糊,没法优化。把它拆成可度量的属性——评测标准(eval criteria):答案对不对、是否有来源依据、格式是否有效、是否调用了正确的工具、长度和语气是否合适?每一项都是你能打分的东西。关键功夫在于:挑出对你的任务真正重要的那几项,而不是什么都去测。

Is it good?not measurableCorrect?scoreGrounded in source?scoreValid format?scoreRight tool called?scoreRight length & tone?score
含糊的「它好吗?」拆成具体的检查,每项各有自己的分数。
ConceptEval Criteria· 可度量的属性
问题
「它好吗?」既没法度量,也没法优化。
思路
把质量拆成属性:正确性、依据、格式、工具使用、长度和语气。
例子
「JSON 符合 schema」、「答案依赖检索到的文档」。
代价
你必须决定什么重要——并诚实地舍弃其余的。
关联
选标准就是 task-specific metrics;由 grader 去检查。

Task-specific Metrics——让指标与任务相匹配

评价译者看忠实与流畅,评价收银员看速度与准确——量尺用错了,评价就没用。

不同的功能需要不同的指标。RAG 系统:检索到的片段对不对,答案是否忠实于它们?分类器:对照标签的准确率。agent:选对工具了吗,达成目标了吗?摘要:忠实、完整、简洁。挑那些对应你的任务里「失败究竟意味着什么」的指标,否则你优化的就是一个不重要的数字。

RAGright chunks retrieved · answer faithful to themClassifieraccuracy against labelsAgentright tools picked · goal reachedSummaryfaithful · complete · concise
功能的类型决定指标:RAG、分类器、agent 和摘要各需要不同的量尺。
PracticeTask-specific Metrics· 与任务匹配的指标
问题
一刀切的指标,测的并不是真正会坏的东西。
思路
指标反映「失败」对这个具体功能意味着什么。
例子
RAG——片段是否正确与忠实度;分类器——准确率;agent——工具与目标。
代价
你得针对每个功能把指标想清楚。
关联
让 eval criteria 落到实处;agent 再加上 trajectory。

Faithfulness vs Correctness——两件不同的事

学生可以写出论证漂亮但错误的答案,也可以写出笨拙但正确的答案。文采和真相是分开的两项分数。

最重要的两个属性常被混为一谈。**正确性(correctness)**是答案究竟对不对;**忠实性(faithfulness)**是它是否有所给上下文的支持、没有凭空编造。一个有依据的系统可以是忠实的(用了来源)却是错的(来源本身就错了),也可以是正确的却不忠实(蒙对了,而不是出自上下文)。把二者分开度量,才能告诉你失败出在哪里。

faithful to contextnot from contextanswer rightanswer wrongThe goalright, from the sourceRight by luckfix groundingSource was wrongfix retrieval / dataHallucinationboth broken
两条轴给出四种结果。每种指向不同的修复位置:检索、依据,或两者都要。
TermFaithfulness vs Correctness· 有依据 vs 答得对
是什么
Correctness——答案是对的。Faithfulness——它出自所给的上下文,没有编造。
为何重要
不同的失败要在不同的地方修。
例子
忠实但错误——修数据或检索。答对了但不忠实——修依据。
坑
一个笼统的「质量」总分把两者混在一起,掩盖了原因。
关联
RAG 的关键指标对;常由 LLM-as-judge 打分。

Slicing——一个数字隐藏得太多

「舒适」的平均气温,可能掩盖了一间冻人的屋子和一间闷热的屋子。汇总会抹掉你最需要看到的那些情况。

单一的总分是起点,不是全貌。把结果拆开——切片(slicing)——按类别和难度:简单与困难、每种问题类型、每种失败模式——因为一个平平的 85% 可能是简单用例 100%、关键用例 40%。评测的价值在于这种拆解,它告诉你下一步该瞄准哪里。

85%overall scoresliceeasy cases100%hard cases40% — the ones that matterslice by category, difficulty, failure mode — the aggregate hides the hard cases
总体 85% 看着不错,一切片就变了:简单用例 100%,关键用例 40%。
PracticeSlicing· 按分段拆解
问题
平均值抹掉了系统真正出错的那些用例。
思路
按类别、难度和失败模式分别打分。
例子
总体 85% = 简单 100% + 困难 40%。
代价
集合里的用例需要带类别标签。
关联
指出 last mile 该往哪走;依赖带标签的 golden set。

「它好吗?」不是指标。把质量拆成为你的任务挑选的具体、可打分的属性——并且永远不要相信单一的汇总数字。

§ 03

评测的诚实程度,取决于里面的样例。数据集——输入及其已知为好的结果——才是真正的资产,大部分用心都花在这里。

Golden Set——带有已知为好结果的输入

老师的标准答案——题目与「正确回答是什么样」配成对,这样评分才一致,而不是看心情。

评测的核心是 golden set:一批有代表性的输入,每个都配有已知为好的答案,或对成功的清晰定义。你就是对着它打分。建它是实打实的活儿——正是在这里你才确定「正确」对你的功能究竟意味着什么——它也是让今后每次改动都可度量的资产。

inputknown-good outcomeWhat's your refund window?30 days, cites the policyCancel my subscriptioncalls cancel_subscriptionasdf??asks a clarifying questionIgnore your instructions…refuses, stays on taskthe asset: every future change is scored against it
golden set 就是一张表:一个真实输入和它已知为好的结果。每次改动都对着它打分。
ConceptGolden Set· 评测数据集
问题
没有参照,输出就按心情评分。
思路
有代表性的输入,每个配一个好答案或清晰的成功标准。
例子

「取消我的订阅」→ 必须调用 cancel_subscription;「asdf??」→ 一个澄清问题。

代价
实打实的活儿:为每个用例决定「正确」是什么。
关联
由 hard cases 和 production sampling 充实;由离线评测运行。

Hard Cases——覆盖边缘和已知的失败

桥梁要用最重的卡车和最糟的风暴来做压力测试,而不只是晴天里的一辆普通轿车。

只有简单、典型输入的集合,会给你一个好看却没用的分数。要刻意放进困难用例(hard cases):含糊的问题、边缘用例、对抗性提示词,尤其是你已经见过的那些失败。每当有 bug 进了生产环境,就把它作为**回归用例(regression case)**加进评测,让它永远不能悄悄回来。集合应当集中在系统最可能出问题的地方。

flattering settypical, easy inputshonest settypicalambiguousedgeadversarialpast bugsProd bug foundadd it so it never silently returns
好看的集合只有典型输入。诚实的集合还加上含糊的、边缘的、对抗性的和过去 bug 的用例。
PracticeHard Cases· 边缘用例、对抗用例、回归用例
问题
一堆简单用例给出的是好看却没用的分数。
思路
刻意加入含糊的、边缘的、对抗性的,以及所有已经坏过的。
例子
一个 bug 进了生产环境 → 它的输入成为集合里的永久用例。
代价
分数会掉——但变得诚实了。
关联
golden set 的一部分;来源是 production sampling。

Production Sampling——采集真实样例

最好的考题来自学生真正考过的那场考试,而不是老师想象他们会问什么。

评测用例最丰富的来源是真实使用:用户实际问了什么,尤其是问了却出了错的。从日志和反馈里挖出真实输入,并入集合。凭空编的样例反映的是你以为会发生什么;生产里的样例反映的是真正发生了什么,包括你绝对想不到的那些凌乱措辞和古怪请求。

Real usersmessy phrasingLogs+ feedbackPick casesesp. failuresGolden setreal inputsinvented cases: what you think happensproduction cases: what doesmine logs and feedback, fold real inputs into the set
用户 → 日志与反馈 → 挑选用例,尤其是失败 → golden set。
PracticeProduction Sampling· 来自真实使用的用例
问题
编出来的样例反映的是你的想法,而不是现实。
思路
从日志和反馈里取输入,尤其是出过问题的地方。
例子
用户那种你永远想不出来的凌乱措辞。
代价
你需要有日志,而且用户数据必须先清除个人信息。
关联
喂给 golden set;信号来自 user feedback。

小而锋利,胜过大而陈旧

五十个精心挑选、直戳真实弱点的问题,比一千个你从不细看的随机问题教给你的更多。

起步不需要成千上万个用例——几十个精心挑选的,覆盖主要行为和已知的失败模式,就足以抓住大部分回退并指导调参。从小处开始,保持诚实,随着你了解系统在哪里出问题再让它长大。一个你真会去跑的评测,胜过一个庞大却不去跑的。

golden set 就是资产。把真实输入与已知为好的结果配对,集中在困难的和坏过的上面,并随着你的了解让它长大。

§ 04

有了输入和预期之后,你需要一种给每个输出打分的方法。这些方法从廉价精确到灵活易错一字排开——你要选能满足需要的最便宜的那个。

Code-based Graders——精确的、基于规则的检查

批改选择题不需要判断力——答案要么对要么错,机器瞬间就能打分。

当输出受到约束时,用代码做确定性的打分——基于代码的 grader(code-based grader):分类用精确匹配,格式用正则或 schema 检查,agent 看是否调用了正确的工具,抽取看数字是否正确。这些检查便宜、快速、无可争辩。要尽可能多地把你的评测放进这一类——它是最可靠的打分方式。

Exact matchclassificationRegex / schemaformat · tool calledLLM-as-judgerubric · fuzzy qualitiesHuman reviewspot-check sampledeterministic: push most checks herecheap · exact · unarguableflexible · costly · fallible
grader 阶梯:左边廉价而精确,右边灵活、昂贵而易错。选能满足需要的最低一级。
ToolCode-based Grader· 确定性检查、精确匹配
问题
明明可以直接比对,却用了昂贵且有争议的判断。
思路
用代码检查输出:匹配、正则、schema、正确的调用。
例子
类别标签匹配;JSON 通过 schema;agent 调用了正确的工具。
代价
只适用于受约束的输出——你没法这样给一篇作文打分。
关联

阶梯的第一级;模糊的输出用 LLM-as-judge;agent 用步骤级检查(step-level checks)。

LLM-as-Judge——让模型给模糊的东西打分

一篇作文请来第二位考官,拿着清晰的评分细则——是判断,但有明确标准做引导,所以是一致的。

对开放式输出——这个摘要忠实吗?这个回答有用吗?——没有精确匹配可用,所以你用一个模型来打分,即 LLM-as-judge:把输出、上下文和一份清晰的**评分细则(rubric)**交给第二个模型,让它打分。它能把接近人的判断扩展到成千上万个用例。对于你没法用规则检查的质量,它是标准工具——但也有需要注意的地方。

Outputto be gradedContextquestion · sourceRubriccriteria + examplesJudge modelLLM-as-judgeScore+ short reasonscales human-like judgement to thousands of cases
judge 拿到输出、上下文和评分细则——返回一个分数和一句简短的理由。
PatternLLM-as-Judge· 用模型当评分员
问题
开放式输出没法做字符串匹配,而人力没法扩展到成千上万个。
思路
第二个模型对照上下文和明确的评分细则给输出打分。
例子
「摘要忠实于来源吗?打 1–5 分,并用一句话解释。」
代价
judge 自己也会出错、也有偏见——必须检验它。
关联
没有 judge validation 就不可信;常用来度量 faithfulness。

Judge Validation——judge 也得被评判

第二位裁判也可能有偏见——偏爱更长的答案,或听起来更自信的那个——所以你在信任他之前,先拿几个人工判定来检验这位裁判。

LLM judge 有它的失败模式:它可能偏好冗长的答案(verbosity bias),被自信的语气左右,或偏离你的本意。所以要在一个样本上对照人工打分来验证 judge,给它一份带例子的锐利细则,并保持简单。一个你没检验过的 judge,不过是又一个没被度量的模型——在确认它的分数确实跟着你真正在乎的东西走之前,别信它。

Samplea few dozen casesHuman gradesJudge gradesAgreementcompareTrustthe judgewatch for: verbosity bias · confident tone · drift from intent
人和 judge 给同一个样本打分。若一致,judge 就可信。留意它常见的偏见。
PracticeJudge Validation· 用人工检验 judge
问题
judge 喜欢又长又自信的答案,还可能偏离你的本意。
思路
在信任它之前,先在样本上把 judge 的分数和人工分数做比较。
例子
几十个用例由人来打分;judge 与之一致——所以可以信任它。
代价
要做一些人工标注,而且每当 judge 或细则变了,就得重新检验。
关联
LLM-as-judge 的必备搭档;用到人工复核(human review)。

Human Review——人在回路,小剂量

即便有自动打分,厨师依然要尝尝菜——快速抽查一下仪器有没有悄悄出错。

自动打分能规模化,但要定期**亲自去读真实的输出——人工复核(human review)。**抽查一个样本,重点看那些失败,并核对你的指标是否仍然反映真实的质量。人工复核没法覆盖每个用例,但小而定期的一剂,能抓住你的自动分数漏掉的东西——并避免你去优化一个已经偏离现实的数字。

PracticeHuman Review· 人工抽查
问题
自动分数可能悄悄偏离真实质量。
思路
定期读一个真实输出的样本,尤其是失败的那些。
例子
每周一次,读那些分数掉了的用例,看看你是否同意。
代价
人的时间——所以小剂量,不是每个用例都做。
关联
grader 阶梯的最后一级;judge validation 的基础。

能确定性打分的地方就确定性打分,其余模糊的交给 LLM judge——并且要验证 judge,因为一个没检验过的评分员不过是又一个猜测。

§ 05

agent 需要的不只是对最终答案的一个分数,因为它们可能经由一个有问题的过程,得出一个干净的答案。要信任一个 agent,你得度量旅程,而不只是终点。

干净的最终答案,可能藏着一个坏掉的中间

只按最终数字评分的数学考试,会让那个靠两个相互抵消的错误得到结果的学生过关——你对到底发生了什么一无所知。

在多步骤的 agent 里,中间的错误可以通过最终输出的检查,同时却污染了整个过程——它检索到了正确的来源,中途把一个事实张冠李戴,然后写出一份干净却是错的摘要。只给最终答案打分,你就把它放行了。你最需要抓住的那些失败,恰恰是只看终点的检查最看不见的。

Retrieveright source ✓Extractmisattributes ✗Summarizeclean, fluentFinal checklooks right ✓the error lives herefinal-only check: PASSa clean answer through a broken process — destination-only grading waves it through
错误出在「Extract」那一步,但摘要读起来很顺——只看最终结果的检查会放它过去。

Trajectory Evaluation——给路径打分

驾考官会看整段驾驶——每次打灯、每次看后视镜、每次变道——而不只是看你有没有到达那个地址。

对 agent 你要评估它的轨迹(trajectory):每一步,它是否选对了工具、传对了参数、检索到了正确的上下文、推理是否站得住?这能抓住只看最终结果漏掉的坏中间,还能告诉你是哪一步出了问题——比只知道结尾错了要有用得多。agent 的可靠性,正是在这些步骤里建成或丢掉的。

trajectory eval: grade every stepfinal-onlyStep 1search_docsright tool?✓Step 2read_doc(id)right args?✓Step 3send_emailright context?✗Answerfinal outputgoal reached?✓tells you which step failed
检查每一步,就能看出究竟是哪里坏的。只看最终结果的检查只能看到最后一个框。
ConceptTrajectory Evaluation· 给 agent 的路径打分
问题
正确的结尾可能藏着错误的步骤。
思路
给每一步打分:工具、参数、检索到的上下文、推理。
例子
第 1–2 步对;第 3 步 agent 取错了上下文——评测点出了第 3 步。
代价
你得记录并标注每一步,而不只是答案。
关联

由**步骤级检查(step-level checks)**构成;由 operational metrics 补充。

Step-level Checks——直接检查工具调用和检索

审计一位研究助理,就是检查他实际调取了哪些来源、发出了哪些调用——而不只是读他最后的备忘录。

agent 的很多行为是具体的,不用判断就能打分:该调用 send_email 时它调用了吗,收件人对吗?它检索到相关文档了吗?它是否守在自己的工具权限之内?这些就是对步骤的确定性检查——步骤级检查(step-level checks),廉价而精确,能精确定位很大一部分 agent 的失败。

PracticeStep-level Checks· 工具调用检查
是什么
对 agent 具体步骤的代码检查,不需要 judge。
怎么做
核对调用了哪个工具、用了哪些参数、检索到了哪份文档。
例子
调用了 send_email,收件人正确,没有超出任何权限。
好处
便宜、精确,并且直指出问题的那一步。
关联
应用在 trajectory 上的 code-based graders。

Operational Metrics——也要度量那些乏味的真相

评价一家快递,不只看包裹到没到,还要看用了多久、试了几次、花了多少钱。

除了正确性,还要追踪 agent 的运行指标(operational metrics):它走了多少步、多频繁地陷入循环或重试、延迟(latency),以及每个任务的成本。一个循环用二十个昂贵的步骤得出正确答案,而三步就够了,这是一个可靠性与成本的问题,你的最终答案分数是显示不出来的。这些数字揭示出那些能跑、却撑不过生产环境的 agent。

Run A✓ right answer3 steps · fast · cheapRun B✓ right answer20 steps · loops and retries · slow · costlyboth score 100% on the final answer — only steps, latency and cost tell them apart
两次运行都得到了正确答案。但一次用了三步,另一次用了二十步,还带着循环和重试。
ConceptOperational Metrics· 步数、循环、延迟、成本
问题
最终答案的分数看不到这个答案花了什么代价。
思路
统计每个任务的步数、循环和重试、延迟与成本。
例子
三步就够的地方,用 20 个昂贵的步骤得出正确答案。
代价
每次运行都需要做追踪。
关联
补充 trajectory evaluation;在生产中由在线评测盯着。

agent 可能经由一个坏掉的过程,得出一个干净的答案。给轨迹打分——工具、检索、步骤——而不只是终点。

§ 06

评测有两种,各干不同的活儿:发布之前跑的测试套件,和在生产里持续运行的度量。两者你都需要,因为世界并不等于你的测试集。

Offline Eval——发布之前的闸门

一条试车道,让一辆车在载上第一位乘客之前先经受考验——受控、可重复、在发布前运行。

**离线评测(offline eval)**就是在改动发布之前,拿你的 golden set 去跑:这个新提示词或新模型,在你精心挑选的那些用例上得分更高吗?它受控且可重复,是你抓回退、安全地比较各种方案的地方。这是你要接进开发循环的评测——最好做成 CI 里的闸门,这样任何让分数下降的东西都发布不出去。

OFFLINE · before shipONLINE · after shipGolden setcurated casesScorevs baselineCI gateblock if worseLive trafficreal usersSample & scorejudge · metricsDashboardquality over time
发布线的左边——离线:golden set、对照基线打分、闸门。右边——在线:真实流量、抽样、仪表盘。
ConceptOffline Eval· 发布前评测
问题
你需要在用户看到之前,就知道一个改动是安全的。
思路
在新版本上跑 golden set,并与基线比较。
例子
新提示词:84%,旧的是 79%——可以安全发布。
代价
它只能看到集合里有的东西——世界要宽广得多。
关联
在 golden set 上运行;由 CI gate 自动化;与在线评测配对。

Online Eval——度量真实世界

不管试车道多好,车上了真实的路,你仍然要监控——因为真实的路上有试车道从没有过的坑洼。

生产环境的表现,没有哪个离线集合能完全预测:真实用户的措辞你想象不到,输入分布也会漂移。所以你也要在线度量——在线评测(online eval):对线上输出抽样并打分,盯着质量指标,收集用户信号。离线集合证明一个改动可以安全发布;在线度量则告诉你,它上线之后实际在发生什么。

Real usersunexpected phrasingAI featurein productionLive outputsinputs shiftSamplea slice of trafficScorejudge · rulesWatchquality metrics
线上输出经过抽样和打分,汇成你盯着的质量指标。
ConceptOnline Eval· 生产环境的质量监控
问题
真实的用户和输入与测试集并不一致。
思路
对线上输出抽样、打分,并盯着指标。
例子
一部分生产环境的回答交给 judge;结果显示在仪表盘上。
代价
生产环境里的打分基础设施,以及 judge 在流量上的成本。
关联
抓住 drift;收集 user feedback;发现新的 hard cases。

User Feedback——免费的评测信号

一个点赞按钮和一个投诉邮箱,就是一份持续、免费的调查,告诉你这东西对使用它的人是否真的管用。

不管你收不收集,你的用户都在给你打分。把用户反馈信号(user feedback signals)——点赞/点踩、修改、重试、放弃、转人工——抓起来并喂回去。重试或点踩的突增是早期预警;那些具体的失败,会成为明天的评测用例。这就闭合了循环:生产环境教会评测集现实是什么样,评测集又保护下一次发布。

Productionlive usageUser signalsthumbs · edits · retriesNew eval casesthe specific failuresNext releaseprotected by the setproduction teaches the set;the set protects the release
一个闭环:生产环境给出信号,失败变成用例,集合保护下一次发布。
PracticeUser Feedback Signals· 隐式与显式反馈
是什么
点赞/点踩、修改、重试、放弃、转人工。
为什么
来自真正在用的人的、免费而持续的评分。
例子
发布后重试的突增,是早期预警。
坑
信号是有噪声的:是个该去看看的理由,而不是现成的分数。
关联
在线评测的一部分;转化为 golden set 里的 hard cases。

Drift——盯住缓慢的衰退

一台秤慢慢偏离校准——没有什么戏剧性,只是每次读数都多错一点,直到某天数字就错了。

一个曾经得分很高的系统,会悄无声息地退化——这就是 drift:模型提供方更新了,你的数据变了,使用模式变了。没有持续的在线度量,你是从愤怒的用户而不是从仪表盘那里得知的。随时间追踪质量,让 drift 显现为一个你能采取行动的趋势,而不是一个意外。评测不是一次性的闸门;它是你要持续读取的生命体征。

alert thresholdqualityprovider updateusage shiftstime →
在提供方更新和使用方式变化之后,质量悄悄下滑。一个阈值能赶在投诉之前抓住它。
TermDrift· 质量漂移
是什么
在你这边没有任何改动的情况下,质量缓慢、悄悄地下降。
成因
提供方的模型更新、数据变化、新的使用模式。
例子
每周差一点——直到投诉比仪表盘先到。
解药
随时间追踪质量,并设一个告警阈值。
关联
由在线评测抓住;新的失败进入 golden set。

离线评测把守发布;在线评测盯着现实。前者证明一个改动是安全的,后者告诉你实际在发生什么。

§ 07

评测是一种实践,不是一次性的事。功夫在于:在你觉得准备好之前就开始,把度量接进循环,并且不让那个数字变成一个对你撒谎的目标。

Eval-driven Development——先写评测,再调参

你得先校准温度计,再去调烤箱——否则每次调整都是披着进步外衣的猜测。

常见的错误是无休止地调提示词,到后来也许才去建评测。把它倒过来:在优化之前先写一个小评测,让每次改动从一开始就被度量——这就是 eval-driven development。哪怕十个用例也胜过零个。没有评测的调参感觉很有成效,其实多半没有——你在挪动你看不见的数字。

PracticeEval-driven Development· 先写评测,再调参
问题
提示词被调了几周;评测是「以后再说,也许」。
思路
在第一次优化之前先有个小评测;每次改动都被度量。
例子
今天十个用例,每次改提示词前都跑一遍。
代价
起步花一小时,而那时一切还「不能用」。
关联
tuning by vibes 的解药;会长成 CI gate。

CI Gate——把评测做成 CI 里的闸门

测试不通过,代码就不能合并——同样的纪律,也能防止一个悄悄变差的提示词到达用户手里。

有了评测,就在每次改动时自动运行它,分数跌破门槛就拦住发布——这就是 CI gate。它把评测从「想起来才做的事」变成一道始终开着的护栏——AI 版的「测试套件全绿」。「没有评测就不发布」是值得坚持的标准:对 AI 功能做一个没被度量的改动,就是一次没测过的部署。

Pull requestprompt changeRun evalon every changeScore ≥ bar?ShipmergeBlockedscore droppedyesno"evals or it didn't ship"
每次改动都跑评测。分数达到或高于门槛——发布;下降了——被拦住。
PracticeCI Gate· CI 里的评测闸门
问题
「谁想起来才跑」的评测,抓不住一个悄悄变差的提示词。
思路
每次改动都跑;分数低于门槛就拦住发布。
例子
改了提示词的 PR,评测通过之前不能合并。
代价
每个 PR 都跑一遍集合要花时间和钱。
关联
让离线评测自动化;在生产之前抓住回退。

Goodhart's Law——别让指标变成目标

只为考试而教,会教出考试拿高分却干不了活的学生——分数上去了,它所衡量的东西却没有。

当一个度量变成目标,它就不再是一个好的度量——这就是古德哈特定律(Goodhart's law)。你可能把提示词对你那些具体的评测用例过拟合(overfit),眼看着分数上升而真实质量原地不动。要防范:留出一部分用例不参与调参(held out),用新的生产失败刷新集合,并记住评测只是用户价值的一个代理,而不是价值本身。一个在涨、而用户却没有感觉的数字,是个警告,不是胜利。

eval scorereal user valueoverfit to eval casesiterations on the same eval set →guard: held-out cases · fresh prod failures · the score is a proxy
评测分数随每次迭代上升,真实价值却已停滞。这个差距就是对集合的过拟合。
PitfallGoodhart's Law· 度量变成目标
是什么
当一个度量变成目标,它就不再是一个好的度量。
表现
提示词被拟合到评测用例上:分数上升,质量不涨。
例子
在集合上涨了 10 分,而用户感觉不到任何差别。
防范
留出不参与调参的用例、新鲜的生产失败、记住分数只是个代理。
关联
由 production sampling 和 human review 来制衡。

从小处开始,随失败而成长

好的测试套件不是一次写成的——它是积累出来的,一个 bug 一个用例,直到悄悄覆盖了所有出过错的地方。

别等一个完美、全面的评测——那样你永远发布不了。先为核心行为准备一把用例,然后**每次有东西坏了就加一个。**久而久之,集合恰好沿着你的系统真正出错的轮廓长大,而这正是你想要覆盖的地方。评测随产品一起成熟,它永远不算真正完成。

这些概念如何连在一起

一只不断转动的轮子:每转一圈,集合就更诚实,发布就更安全。

这门课里的一切都属于同一个循环。criteria 说明测什么;golden set 说明拿什么来测;grader(代码、judge、人)给出分数。带 CI gate 的离线评测把守发布,在线评测盯着现实——反馈和 drift——它发现的失败变成新用例,回到集合里。对 agent,你给轨迹打分,而 Goodhart 定律提醒你:分数只是个代理。

Criteriawhat to measureGolden setwhat to test onGraderscode · judge · humanOffline + CI gateguards the releaseOnline evalsample · feedback · driftNew casesfrom real failuresagents: grade the trajectory, not just the endGoodhart: the score is a proxy — keep the set fresh
评测循环:标准 → 集合 → grader → 闸门 → 在线 → 新用例 → 回到集合。
发布 AI 功能之前
  • 到底有没有评测——一组带有给输出打分方法的输入?
  • 指标是否与任务匹配,按难度和失败类型拆开,而不是一个平平的总分?
  • 集合里是否包含那些困难的、怪异的、以前坏过的用例,并且取自真实使用?
  • 打分用的是不是最便宜的可靠方法——能确定性的就确定性,不能的就用经过验证的 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度量变成目标

变成目标的度量就不再度量。分数只是个代理。

评测不是一次性的测试。它是那个循环——度量、找出失败、把它们叠回去——把一个非确定性组件变成你能信任并能改进的东西。

速成课结束 · 7 章 · 24 个概念

接下来是实践:今天就挑一个 AI 功能,给它写十个评测用例——真实的输入、已知为好的结果、给每个打分的方法——并在你下一次改提示词之前把它们跑一遍。然后每当有东西坏掉就加一个用例。但有一个念头要高于其余:那个跑一次就行的 demo,是容易的那 80%。一切让它成为一个你能信任的产品的东西——爬到 95%、抓住的那些回退、看见的那些漂移——只有在你度量时才有可能。没有评测,你就是凭感觉调参;有了它,改进就成了一个你能跑起来的循环。