企业里把 LLM 和 Agent 真正用起来,最难的从来不是把它跑通。最难的是回答两个朴素的问题:它现在到底行不行,以及我改完之后有没有变差。确定性软件能用单元测试加覆盖率把这两个问题答得明明白白。LLM 是概率系统,输出是开放文本,行为依赖 prompt、上下文、工具返回,甚至同一份输入两次采样都能给出不一样的答案。这里没有 oracle,没有"期望输出"可以硬编码。Evals 本质是给这套非确定性系统造一把可重复的标尺。
我的看法很直接:评估不是上线后才补的功课,它是 Agent 工程的第一性原理。没有评估,所有号称的"调优"都是黑暗里调收音机,调一下听一下,毫无积累。这一篇我们不讲工具清单,讲最底层的机制:为什么需要评估,评估在哪些层次上发生,指标到底在度量什么,以及生产环境里那套评估体系是怎么把混乱收敛成可信任的工程活动的。
一、为什么非确定性系统必须有评估
确定性软件的测试逻辑是"输入确定,输出确定,断言相等"。这套逻辑对 LLM 彻底失效,失效来自三个源头:非确定性、漂移、回归。
非确定性来自采样即使 temperature 设成零,同一个 prompt 加同一份输入,两次生成也可能不同。原因包括解码时的数值非确定性、batch 内注意力计算的微小差异、以及服务端负载导致的 beam 行为变化。这意味着你不能靠"我试了一次好像行"来判断一个能力。评估必须定义在分布层面:在足够大的样本上,正确响应的比例是否达到阈值。
数学上要诚实。把单次生成看成从条件分布 P(Y|X) 里抽样,评估要估计的是在测试分布 D 上质量函数 Q 的期望值 E_{XD}[E_{YP(Y|X)}[Q(Y)]]。单次观察方差极大,要得到稳定的估计,样本量 N 必须足够大。中心极限定理告诉我们,比例的估计误差大约服从 1/√N 的衰减,所以你想把置信区间收窄一半,样本量得翻四倍。这就是为什么 eval 的单位是"集"而不是"例",指标是"率"而不是"次"。很多团队上线前拿五六个例子手测一遍就宣布 OK,这在统计上毫无意义。举个具体的数:你想以 95% 置信度检出 5 个百分点的成功率变化,假设基线成功率 70%,两比例检验需要的样本量在几百条量级。eval 集的规模是被统计有效性逼出来的,不是拍脑袋定的,宁可少测几个维度也要把样本量凑够。
漂移来自底座和世界的双重变动你依赖的底座模型会被供应商悄悄升级,P(Y|X) 随之变化,你的 prompt 在新模型上可能突然变得更保守或者更爱幻觉。你改 prompt 是显式漂移,底座的服务端变更对你而言是隐性漂移。更麻烦的是知识漂移:外部世界变了(新法规、新 API、新事实),正确答案本身在动。eval 集的意义就是当锚点,把这些变动暴露出来。漂移这一点和传统软件的回归测试同源,但难得多,因为"什么是正确"本身都不固定。
回归来自你自己的修改你为了修场景 A 改了 prompt,结果场景 B 掉分了。没有回归集你根本发现不了。eval 集在这里扮演的角色等价于软件工程的 golden set 或回归套件:每次改动跑全量,对 score diff 做 review。区别在于传统断言失败是确定的二值,LLM eval 有方差,你必须区分"真回归"和"噪声波动"。一个实用做法是多次运行取均值并看置信区间,必要时做两比例 z 检验(z = (p1 − p2) / √(p(1−p)(1/n1 + 1/n2))),用统计显著性把噪声和真回归分开。
二、评估在三个层次上发生
把评估类型按粒度铺开,其实是三个层次:单元级关注单次生成的质量,轨迹级关注多步过程是否合理,系统级关注端到端有没有达成业务目标。同一套方法会落在不同层次上,理解层次比背清单重要。
单元级 LLM-as-judge用一个强模型当裁判,按 rubric 给候选输出打分,这是当前最现实可用的方法。两种形态最常见:分类式,给 rubric 加候选,输出 1 到 5 分或 pass/fail 的结构化结果,通常走 function calling 拿稳定 JSON;对比式,直接把 A 和 B 喂进去问谁更好,主要用在 A/B 选型或迭代里挑优。
它为什么有效?因为"有用性""连贯性"这种语义质量根本没法用字符串匹配度量。人类裁判是 gold standard,但贵且慢,judge 是人类裁判的可扩展近似。数学直觉要清楚:judge 其实是对人类质量函数 H(Y) 的一个有偏估计 J(Y)。我们真正在乎的不是 J 的绝对值准不准,而是 J 和 H 的相关性高不高,能不能保持正确的排序和回归方向。换句话说,judge 是个 ranker,不是 scorer。
但 judge 有自己的系统性偏差,这是工程里最容易被忽略的坑。位置偏差让它在 pairwise 比较里偏好排在前面的那个。冗长偏差让更长的回答自动拿更高分,哪怕内容更水。自我偏好偏差是模型倾向于给和自己风格相似的输出打高分。权威语气偏差则让用词笃定的答案显得更可信。这些偏差不能靠"用更强的模型"消除,更强的模型只是把偏差换了个更优雅的形式。
缓解手段是工程化的:pairwise 要把顺序互换各跑一次取平均;分类式要喂 rubric 加参考回答,逼 judge 对照而非凭印象;用 chain-of-thought 让 judge 先给理由再给分,降低随机性;关键的,要拿人类标注做校准,算出 judge 和人的一致性(Spearman 相关)和偏差方向,必要时对 judge 分数做后校准回归修正。没有这步,你盯着 dashboard 上的分数涨跌,其实可能只是在看 judge 的心情。
校准的具体做法是画校准曲线:把 judge 分数分箱,算每箱里人类判正的比例,理想情况应该落在对角线上,明显偏离就说明有系统性偏差。更进一步可以算 Spearman 相关看排序一致性,算 Brier score 看概率校准程度。我的经验是,judge 和人的 Spearman 低于 0.7 就别拿它做回归门禁,只能当粗筛;真要进门禁,至少先做好校准曲线再决定。
引用与忠实度针对 RAG 和会调工具的 Agent:回答到底有没有忠实于它引用的证据,有没有幻觉出上下文里根本不存在的东西。忠实度(faithfulness)的标准做法是把回答拆成若干 claim,逐一让 judge 判断每个 claim 是否能被检索上下文蕴含(entailment);最终分数就是被支持的 claim 占比。引用正确度更进一步,它看引用的具体片段是不是真的支撑了那个论点,而不是"文中确实出现了引用"就算数。这类指标更客观,因为它有金标准证据可对,是 RAGAS 体系的核心(faithfulness、context precision、context recall 都落在这里)。
顺带说清楚 RAGAS 这几个指标的直觉,免得把它当黑盒。Context recall 衡量检索回来的上下文,覆盖了多少参考答案里的事实,分数低说明漏检。Context precision 衡量检索的排序质量,相关段落是不是排在前面,用的是类似 DCG 的折扣加权。Faithfulness 如上,是生成回答对上下文的忠实程度。它们合起来回答一件事:证据找得全不全、排得好不好、用得诚不诚实。
任务成功率给 Agent 一个明确目标,比如"把这个 bug 修掉并提 PR",它是不是真完成了。判定可以是程序化的(最终状态符合预期:文件改对了、PR 建了、测试过了),也可以是 judge 看最终产物。这是端到端最硬的指标,因为它直接对齐业务目标。但它的方差也最大:复杂任务本身成功率就不高,"成功"的定义边界还常常模糊,需要人工裁定。实践中我建议把成功率和"步骤数、工具调用次数、花费"摆在一起看,同样成功率下步骤越少越好,这是个帕累托权衡。
轨迹级评估不只看结果对不对,还看它怎么走过去的:每一步规划合不合理,工具调用对不对,有没有重复调用或死循环。两种做法,一是 step-level judge,在轨迹中间对每个 action 打质量分,能精确定位是哪一步走错了;二是对整条轨迹打一个整体分,衡量连贯性和效率。轨迹评估的价值在于,结果对可能是侥幸,轨迹对才说明方法可靠、能泛化。它也是过程奖励模型(PRM)和 RLAIF 的基础信号。和任务成功率的关系是:成功率是 0/1 的粗信号,轨迹分是连续的细信号,能给出改进梯度,更适合驱动迭代和强化学习。
三、指标:从准确率到忠实度再到工具调用正确率
指标不是越多越好,而是要清楚每个指标在度量什么、它会在哪里骗你。
准确率与精确率召回落在可判对错的硬任务上,比如分类、事实命中、工具选择。Accuracy = (TP+TN)/总数,但在不平衡集上召回更关键。Agent 最大的风险面往往是"该做的动作没做",召回直接衡量这个,比看整体准确率有用得多。
忠实度 faithfulness即回答中被证据支持的 claim 占比,或 judge 给出的 0 到 1 分。它衡量幻觉程度,是 RAG 和工具型 Agent 的生命线。一个回答准确率看着高,但靠编,faithfulness 会把它揪出来。
有用性 helpfulness让 judge 判断"是否真正解决了用户意图"。这是端到端体验指标,最难定义却最重要。我的观点是,很多团队沉迷于 faithfulness 和准确率,却忽略了用户真正感知的是 helpfulness。一个忠实但答非所问的回复,faithfulness 满分也没用。
工具调用正确率这是 Agent 区别于纯生成模型的核心能力指标。它还能拆成三块:工具选择是否选对、参数是否符合 schema、参数的语义是否正确。前两块容易程序化校验,第三块常常还要 judge 或单测。工具调用错了,后面生成得再漂亮也是南辕北辙。
这些指标常组合成综合分,但权重要小心。不同阶段关注点不同:早期看成功率和工具正确率,稳定期更要盯忠实度和成本。把权重写死一成不变,是另一种会让 eval 失真的隐性漂移。
综合分的设计还有个常见陷阱:各指标量纲不同、方差不同,简单加权平均会把高方差指标的声音放大,掩盖低方差但关键的指标。更稳的做法是先对每个指标归一化到同一区间再按业务阶段加权,或者直接盯少数几个北极星指标,其余只作监控不进总分。另一个坑是综合分对小幅均匀退化不敏感,所有指标都掉一点,加权平均可能还在阈值之上,但用户体验已经明显变差。所以回归门禁必须看单指标 diff,不能只看总分。
四、生产级评估体系:离线、在线、人工三层闭环
单机跑一遍 eval 脚本只是玩具。生产级体系是三层加起来,再配一道回归门禁。
离线回归集是一份固定、标注好、版本化的测试用例集合,从几百到几千条,覆盖核心场景和边界 case。每次 prompt 或模型改动都跑全量,生成 score diff 报告并进 code review。它等价于传统 CI 里的回归套件。这里的关键是,这份集本身是公司资产,要进版本库、要防污染(下一节细说),要和训练数据严格隔离。
在线监控 / 影子评估对线上真实流量采样打分,judge 异步跑、不影响用户。监控成功率、helpfulness 分布、工具调用失败率、幻觉率、延迟和成本,设告警阈值发现漂移。更进一步用 shadow 或 canary:新版本旁路上线,和旧版本在同一份流量上直接比分数,上线前就预判线上表现。
众包与人工校准定期抽一批 judge 评分的样本让人标,算 judge 和人的一致性,校准偏差;同时把最难的边界样本人工标注后回灌进回归集。这一步是让 judge 持续可信的闭环,没有它,前两层迟早会因为 judge 漂移而集体失真。
门禁要设计得稳。CI 里设回归门禁:关键指标相对基线跌超过阈值(或置信区间下界低于阈值)就阻断合并。但门禁必须容忍噪声,否则会出现两类错误:把噪声当回归的 false positive 会天天阻塞开发,方差大到盖住真回归的 false negative 则让门禁形同虚设。多次运行加统计检验是基本配置,不是可选项。具体怎么设噪声容忍?一个常用配置是每个改动跑 K 次(比如 5 到 10 次)取聚合指标,再和基线的多轮均值比较。拦截不要用点估计的差,而用置信区间下界:只有区间下界低于阈值才阻断。否则单次波动就会误杀好改动,团队很快就会对门禁失去信任。
五、评估集怎么建,以及如何避免被污染
评估集的构建质量,决定了你所有结论的天花板。
来源要真实首选线上日志采样,它反映真实分布,比人工拍脑袋造的题有价值得多。其次人工构造边界 case 和对抗样本,补日志里采样不到的长尾。再叠加合成数据扩量。
标注要有 oracle每条样本都得有明确的可判定标准:正确答案、判分 rubric、或者可程序化校验的最终状态。没有 oracle,eval 本身不可信,你只是在用一个模糊去测另一个模糊。困难样本要多人标注取共识,看标注者间一致性(inter-annotator agreement),一致性低说明题目本身模糊,得返工。
分层抽样按场景、难度、用户群分层,保证覆盖率。只测简单样本会给出虚高的分数,掩盖长尾的崩溃,这种虚高比低分更危险,因为它会让你带着错误的安全感上线。
污染是评估最大的隐形杀手底座模型的训练数据可能见过你的测试题,尤其公开 benchmark,或者你公司内部文档泄漏进了训练语料,结果分数虚高、完全不可信。数学上这把"测试损失"变成了"训练记忆",评估的泛化含义被彻底蒸发。规避手段是工程纪律:train/dev/test 严格隔离,测试集用私有、内部、时效性强的问题(比如本周刚出的文档),对公开 benchmark 做改写扰动改变其分布,留一个从不外泄的 holdout 集,并定期刷新测试题到模型 cutoff 之后的新事实。一个实用判据:换一个模型从没见过的同类问题,Agent 还行,那才说明你的 eval 没被污染。
还有一个容易被忽视的污染来自 prompt 本身。如果你的 prompt 里嵌了大量示例,而这些示例恰好和测试题同分布,eval 测的其实是模型对示例的记忆而非泛化能力。解决办法是测试题和 few-shot 示例严格不重叠,且示例的分布要宽于测试分布,宁可示例更通用也不能和考题撞车。
六、评估如何真正驱动迭代
评估不是终点,它是方向盘。
把失败 case 当 bug 修。每个 fail 都写成一条 regression test 防止复发,这和软件工程的态度完全一致。区别在于你修的是 prompt、是工具定义、是检索策略,不是常规代码,但纪律一样。
用 score diff 做决策,而不是感觉。跑 eval、看哪个维度掉分、哪个 case 失败、针对性改(加 few-shot、加工具、改检索、收窄 prompt),再跑 eval 看回归集回升且其他维度不降。A/B 上线前,用离线 eval 加影子评估预测线上表现,把"感觉会好"变成"数据说会好"。
把 eval 分数和线上真实指标(留存、人工满意度)对齐,逐步建立离线分与线上体验的相关性,团队才会真正信任 eval。信任建立起来后,迭代速度是指数级的,因为每个人的改动都能立刻被客观量化,不再靠口头争论。
落到组织层面,我建议把 eval 集和分数历史当一等公民资产来维护:每次改动的 score diff 进 PR,review 时和代码一起看;分数历史做成时间序列,能一眼看出某次提交引入的漂移。当这套成为团队肌肉记忆,Agent 的迭代就从"谁嗓门大谁对"变成"数据说话",这也才是评估体系最值钱的部分。
终极目标就一句话:让"改变模型行为"从玄学变成可测量、可回归、可协作的工程活动。评估体系本身也是要迭代打磨的产品,不是一次性建完就扔那的基建。