第 09 篇 评测工程:把「好不好」变成可测的数字

本篇属于「工程质量」模块。02 篇搭过三层评测结构的概览,这一篇把它做成完整操典:如何建一个可信的 golden set、如何从失败模式反推指标、如何让 LLM 当裁判而不被它骗、如何把评测焊进 CI 与线上监控。读完应能独立搭出一套可运行的评测体系。


引言:为什么评测是 PM 最大的分水岭

本系列第一篇对 654 份在招产品经理 JD 的分析显示,85% 的岗位描述提到 AI/ML,其中 32% 明确要求候选人具备 evals(评测)能力。换句话说,约三分之一的岗位把"能不能定义并运行评测"当硬门槛。

为什么是评测,而不是别的?因为 AI 系统的输出是概率性的。传统软件"跑通测试"约等于"功能正确";AI 系统"跑通一次"什么都不证明——同样的输入换一次运行可能就错。没有评测,你不知道一次 prompt 改动是变好还是变坏;没有评测,你不知道上线后是不是在悄悄退化;没有评测,团队的所有讨论都停留在"我觉得"。

结论先行:评测是 AI PM 唯一的客观话语权。它把"好不好"从主观感受翻译成可对比的数字,让迭代有方向、让争论有依据、让上线有底线。


一、评测的三种类型与分工

很多人把"评测"当成一件事,于是要么只在上线前跑一次,要么只盯线上曲线。实际上评测分三种,职责、频率、负责人都不同,缺任何一种都会出现盲区。

类型目的何时跑谁负责成本失败的后果
能力评测(离线)测"这个系统当下能做到什么水平"每次改动(prompt/检索/模型/知识库)后,接入 CIPM 定义集与指标,工程接入中(全量跑固定集)不知道改动是涨是跌,迭代靠猜
回归评测(离线)测"改动有没有破坏已有能力"同上,与能力评测同一次运行同上低(复用 golden set)旧能力悄悄退化,用户先发现
在线评测(生产)测"真实环境下表现如何、是否在漂移"持续,按采样比例回流PM 看指标,算法/SRE 接监控高(依赖 trace 与标注)线上退化数周后才被投诉暴露

核心判断:

  • 离线评测保"底线":每次合并前必须全绿,红灯不合并。它回答"这次改动有没有把事情搞砸"。
  • 在线评测保"现实":离线分数好不代表线上好,因为真实输入分布、用户问法、知识库状态都在变。它回答"系统在真实世界里还站不站得住"。

两者不可互相替代。离线集是冻结的、可控的;在线是开放的、噪声大的。只看离线会过度自信,只看在线会反应滞后。


二、Golden Set 的构建方法

这是整篇最该花时间的一章。一个糟糕的 golden set 会让整个评测体系变成精密的摆设——它给你漂亮的数字,却对你真正的失败视而不见。

2.1 规模:50–200 条起步

经验上,一个能用的 golden set 从 50 条开始,到 200 条进入稳定区。这个量级基于两个考量:

  • 统计意义:少于 50 条时,单条失败会让总分波动 2 分以上,你分不清是真退化还是噪声。100 条以上,多数核心失败模式才能各分到足够样本。
  • 维护成本:golden set 要人工标注、长期维护。超过 200 条后,标注与复核的人力成本上升很快,而边际信息增益递减。

扩充的时机:当出现新的、稳定的失败模式,而现有集合里该类样本不足 5 条时,针对性补到能支撑趋势判断为止。不要为了"凑大"而堆量。

2.2 来源优先级:真实生产 > 专家手写 > 合成

来源可信度适用局限
真实生产数据(已脱敏)最高覆盖真实分布与长尾可能含敏感信息,需脱敏;早期没有
领域专家手写冷启动期、定义"什么叫对"规模有限,专家时间贵
合成数据中–低扩充表达多样性、格式变体无法发明领域知识,会放大模型自身盲区

为什么合成数据只能补充、不能当主力?模型生成的数据来自模型已有的认知。它能把"已知"说成"另一种说法",但不能产生模型不知道的知识,也不能创造它没见过的失败形态。用合成数据撑起 golden set,等于让系统在自己熟悉的舒适区里考自己,分数虚高却不代表真实能力。合成数据正确的位置是:在真实/专家样本定标后,做表达层面的扩充。

2.3 覆盖原则:按失败模式分层,而非随机抽样

最常见的错误是"从生产日志里随机抽 100 条"。随机抽到的几乎全是正常 case,因为失败本来就是少数。你的 golden set 于是成了"漂亮案例集",对真正的 bug 毫无覆盖。

正确做法:先列失败模式清单(参考《第 03 篇:LLM 能力边界与失败模式图鉴》),用失败模式作为第一维来构造。一个覆盖矩阵示例:

失败模式简单场景复杂/多跳场景对抗/边界场景小计
幻觉(编造事实)15201550
答非所问(相关性差)15151040
检索遗漏(该召不回)10201040
工具调用错误1015530
格式崩溃55515
合计557545175

构造顺序:先保证每个已知失败模式都能分到 5–15 条;再用"场景难度"拉开分布,逼出长尾;最后补少量"正常 case"防止集子全是负样本导致指标失真。

2.4 冻结原则:主集冻结,新失败进"新失败集"

golden set 一旦建立,主集必须冻结——不增、不改、不删。原因:指标要跨版本可比。如果每次都往主集里加新题,你看到的分数变化里混进了"题目变难了"的因素,分不清是系统变好还是题目变简单。

新发现的失败案例,先进独立的"新失败集"。观察它是否稳定复现、是否代表一类而非个例,稳定后再合并进主集并提升版本号(如 golden-v3)。每次合并都是一次有记录的版本演进。

2.5 污染问题:绝不能用测试集调 prompt

用 golden set 调 prompt,等于用答案反推考题。你会得到一组在这个集上异常好看的数字,但它在真实分布上几乎一定失效——因为模型只是"记住"了这几十条题。这叫测试集污染(data leakage 的一种)。

纪律:golden set 是"考试卷",不是"练习册"。任何为了抬高主集分数而做的针对性改动,都必须在另一个独立集上验证才作数。

2.6 标注规范:判分标准写到可执行

模糊的标注指令(“判断回答是否忠实”)会让两个标注员给出完全不同的分,指标因此不可信。规范必须写到"看到什么算什么"。

下面是一份"忠实度"可执行分级定义(0/1/2 分):

忠实度评分标准(Faithfulness)
判断对象:回答中的每一个事实性论断,是否都能在给定检索内容中找到依据。

2 分(完全忠实):
  - 所有事实性论断(人名、数字、时间、因果、结论)都能在检索内容中找到原文或等价表述;
  - 没有引入检索内容之外的任何事实;
  - 推理步骤(若有)可由检索内容直接推出。

1 分(部分忠实):
  - 核心结论有依据,但存在一处次要事实无法溯源(如多出一个未提及的时间点、一个模糊的"通常");
  - 或对检索内容做了轻微过度概括,但不改变结论方向。

0 分(不忠实):
  - 出现检索内容中不存在的具体事实(编造的数字、来源、事件);
  - 或结论与检索内容相悖;
  - 或把 A 的信息安到 B 身上(张冠李戴)。

判分铁律:拿不准时,凡检索内容里找不到原文支撑的事实性论断,一律记 0。

注意最后一条"拿不准记 0"——它把主观判断的歧义推到最严格一侧,保证不同标注员的分差可控。

2.7 测试用例记录模板

每条用例建议落库为一条结构化记录,而非散落的文本文件。模板如下(可直接套用):

# 测试用例记录(单条)

id:            RAG-042
所属失败模式:  幻觉-编造数字
场景难度:      复杂/多跳
输入(query):   我们去年 Q3 的华东区退货率是多少?对比 Q2 变化多少?
期望输出:      给出具体百分比与环比,并引用来源段落
检索内容(ref): [段落A: ...][段落B: ...]   # 与 query 对应的真实上下文
参考回答:      ...(可选,专家手写的标准答案)
标注维度:
  faithfulness: 2
  answer_relevancy: 2
  context_recall: 1
  format_valid: 1
关键判定点:    "退货率"必须是检索内容里出现的真实数字,不得估算
标签:         regression(回归必须保持), p0(高优先)
版本引入:     golden-v1
备注:         Q2 段落缺失时本应触发降级而非编造

这套字段让每条用例都可被程序读取、可跨版本比对、可按失败模式聚合——它是你评测体系的"最小数据单元"。


三、指标设计:从失败模式反推指标

指标不是凭空定的。先有失败模式,才有指标;指标必须能追溯到具体失败模式,否则就是虚荣指标(vanity metric)——看着涨了,问题还在。

下面这张对照大表把常见失败模式映射到可测指标,并标出每个指标"能抓到什么、抓不到什么"。

失败模式对应指标建议阈值能抓到什么抓不到什么
编造事实忠实度 Faithfulness≥ 0.90回答超出检索依据回答"对但没用"
答非所问答案相关性 Answer Relevancy≥ 0.85偏题、答错方向事实是否准确
召不回关键信息上下文召回率 Context Recall≥ 0.85该检索的没检索到检索内容是否相关
召回到垃圾上下文精确率 Context Precision≥ 0.80检索结果不相关生成质量
任务没完成任务完成率 Task Success≥ 0.80多步目标未达成单步质量细节
调错工具工具选择正确率 Tool Selection Acc.≥ 0.95选错/漏选工具参数对错
违反约束约束违反率 Constraint Violation≤ 0.05越权/超范围/违规完成质量高低
成本失控每正确答案成本 Cost / Correct≤ 预算花了很多钱才对答案本身对不对
该答不答拒答率 Refusal Rate≤ 0.05过度拒答答了之后的质量
格式崩格式合规率 Format Compliance≥ 0.98多了前言/占位符语义正确性
长尾慢P95 延迟≤ 2s长尾体验差平均体验
结果飘一致性 Consistency(同输入多次方差)方差 ≤ 阈值同问不同答绝对对错

RAG 四指标(忠实度/相关性/上下文精确率/上下文召回率)的计算思路简述:

  • 忠实度:把回答拆成论断,逐条判定有无检索依据,比值即分。可 LLM-as-judge 自动算,但需人工校准。
  • 答案相关性:判断回答是否回应了 query 的意图,与事实无关。
  • 上下文召回/精确率:以"检索到的内容"相对"与问题相关的理想内容"的覆盖与纯度来算,需要标注"哪些段落是相关的"。

Agent 类指标特别强调"成本与约束":因为 Agent 会多步调用、会自己选工具,光看"最后对不对"掩盖了两件事——它是否绕了远路(成本)、它是否干了不该干的(约束违反)。任务完成率 ÷ 成本 才是 Agent 的真实效率。

通用指标里最容易被忽略的是一致性:同一输入跑 5 次,答案一会儿对一会儿错,说明系统不可信。一个平均 90% 但对同一问题方差极大的系统,不如稳定 85% 的系统。


四、LLM-as-judge 的正确用法与三个偏差

人工标注贵且慢,全量评测几乎必须上 LLM-as-judge(用模型当裁判自动打分)。但它有三个已知偏差,不处理就会系统性虚高或虚低。

偏差机制表现缓解手段
循环论证用会幻觉的模型判另一个模型判官自己也编,给错分换不同厂商模型做集成评判;冻结 golden set;5% 人工校准
位置偏差成对比较时偏好特定位置总判第一个或第二个"赢"成对比较时随机交换 A/B 顺序,各跑一次取平均
长度/风格偏差偏好更长、更"像样"的回答冗长但空洞的回答得分高在判官 prompt 里明确要求"只看事实正确性,忽略长度与文风";必要时做长度归一

缓解手段落地清单

  1. 换厂商集成评判:主裁判用 A 厂模型,副裁判用 B 厂模型,分歧超阈值才升级人工。两个会幻觉的模型来自不同训练分布,同时犯同一个错的概率显著低于单一模型。
  2. 成对比较随机交换位置:任何 A vs B 的胜负判断,都随机决定哪个放前面,跑两次,消除位置偏置。
  3. 抽 5% 人工标注定期校准:每周抽 5% 的 trace 人工打分,计算判官与人工的一致性(如 Cohen’s kappa 或简单一致率)。一致率低于某阈值就说明判官已漂移,需重新调 prompt 或换模型。
  4. 定期验证判官与人工一致性:不是跑一次就完。判官本身也是个"模型",它也会随你改它的 prompt 而变。把它当成一个需要被评测的对象。

核心原则:LLM-as-judge 是"放大器",不是"真理"。它能把人工定好的标准规模化,但标准本身必须来自人。


五、把评测接进工程流程:CI 门禁

评测最大的敌人是"忘了跑"。解决方法是把它焊进工程流程——不跑评测,就不许合并。

5.1 哪些变更必须触发评测

任何可能影响输出的改动都要触发全量评测:

  • prompt 改动(哪怕是改一个词)
  • 检索参数改动(top-k、chunk 大小、相似度阈值)
  • 模型版本替换(升级或降级)
  • 知识库更新(新增/删除文档、重新建索引)

这几类改动里,prompt 和知识库更新最容易"以为没事"——结果上线才发现忠实度掉了。所以门禁对它们一视同仁:先红后绿,不许跳过。

5.2 红灯规则伪代码

门禁不是"跑一下看分数",而是带硬阈值的断言。一个包含质量、延迟、成本三道闸的写法:

def gate_before_merge(eval_result, budget):
    # ---- 质量下限(任何一项低于阈值,红灯)----
    assert eval_result.faithfulness      >= 0.90, "忠实度低于 0.90"
    assert eval_result.answer_relevancy  >= 0.85, "答案相关性低于 0.85"
    assert eval_result.context_recall    >= 0.85, "上下文召回率低于 0.85"
    assert eval_result.format_compliance >= 0.98, "格式合规率低于 0.98"
    assert eval_result.refusal_rate      <= 0.05, "拒答率超过 0.05"

    # ---- 延迟上限(P95 单点不能超)----
    assert eval_result.p95_latency_ms    <= budget.max_latency_ms, "P95 延迟超限"

    # ---- 成本上限(单次与每正确答案成本)----
    assert eval_result.avg_cost_per_call <= budget.max_cost,         "单次成本超限"
    assert eval_result.cost_per_correct  <= budget.max_cost_correct, "每正确答案成本超限"

    # ---- 回归保护:相比上一版本,核心指标不得明显退化 ----
    assert eval_result.faithfulness >= baseline.faithfulness - 0.02, "相对基线退化超 0.02"

    return "GREEN"  # 全过才放行

注意最后一条"回归保护":它不仅守绝对下限,还守"相对上版本不退化"。这能拦住那种"分数没破线、但比上周差了一截"的隐性劣化。

5.3 例外流程:紧急修复怎么办

门禁不是铁板。生产事故时要能绕,但要留痕:

  • 紧急修复可走 hotfix 通道,附"已绕过评测门禁"标签与理由,但必须在 24–48 小时内补跑评测并回填结果。
  • 任何绕过都要有 owner 签字(哪怕是即时通信里的一句确认),避免"临时"变成"永久"。
  • 补跑若红灯,立即回滚或进入修复流程,不得带病上线。

原则:没有绿灯的 eval,不许合并。例外是例外,不是常态。


六、在线评测与漂移监控

离线绿灯不等于线上安全。真实输入分布、用户问法、知识库状态都在变,系统会"漂移"。

6.1 采样比例

环境采样比例说明
开发/预发100%每条 trace 全留,便于定位
生产5%–20%全量成本过高,按流量抽样
错误/异常高采样(接近 100%)失败日志多采,才有足够失败样本

6.2 监控什么

  • 输入分布:用户真实问法的分布是否变了(新意图出现、老意图消失)。
  • 指标趋势:在线忠实度、相关性、拒答率、格式合规率的周环比。
  • 工具错误率:Agent 场景下,工具调用失败/超时/参数错误的比例。
  • 成本与延迟:单次成本、P95 的实际分布,是否随流量上升而劣化。

6.3 告警阈值怎么定

阈值要分"观察"与"行动"两级:

  • 观察线:指标偏离基线 1 个标准差 → 进周报,不告警。
  • 行动线:连续两次采样(或单周跌幅超 3%)→ 触发告警,PM 必须响应。
  • 硬性红线:忠实度周跌幅超 5%、工具错误率翻倍 → 立即回滚或降级。

6.4 漂移的三种来源

来源机制例子
知识库变了文档更新后,旧答案依据失效价格改了,模型还在引用旧价
用户问法变了真实意图分布迁移上新功能后,大量新问题无对应知识
模型版本变了底层模型升级/降级,行为偏移同 prompt 换模型后语气或边界变化

每周节奏:周一采样、周二标注、周三归集、周四并入测试集、周五重跑评测(与《第 10 篇:数据飞轮与冷启动》的飞轮节奏对齐)。


七、评测报告怎么写

评测的价值在于被消费。一份没人读的报告等于没跑。一页纸模板,结论先行:

# 评测报告:[功能名] [版本号]  [日期]

## 结论(一句话)
本次 [prompt 改动 / 模型升级] 后,忠实度 0.91→0.93(达标),但 P95 延迟 1.4s→2.1s(逼近上限),建议上线前优化检索。

## 指标对比
| 指标 | 上版本 | 本版本 | 阈值 | 判定 |
|------|--------|--------|------|------|
| 忠实度 | 0.91 | 0.93 | ≥0.90 | ✅ |
| 相关性 | 0.88 | 0.87 | ≥0.85 | ✅ |
| P95延迟 | 1.4s | 2.1s | ≤2.0s | ⚠️ |
| 单次成本 | 0.002 | 0.0021 | ≤0.003 | ✅ |

## 失败归因
- 延迟上涨主因:检索 top-k 从 5 调到 8,召回更全但更慢。
- 2 条忠实度失败:均属多跳推理,模型跳过中间步骤。

## 下一步动作
1. 检索 top-k 回调到 6,平衡召回与延迟(owner:工程,本周)。
2. 新增 8 条多跳用例进 golden-v4(owner:PM)。

## 附:测试集版本
golden-v3,共 175 条;标注规范 v2。

记住:报告第一行就该让人知道"能不能上"。细节是给想知道为什么的人看的,不是给所有人看的。


一页速查

评测体系搭建清单
├─ 先建 golden set
│   ├─ 规模 50–200 条,按失败模式分层,不随机抽
│   ├─ 来源:真实生产 > 专家手写 > 合成(合成只补表达)
│   ├─ 主集冻结,新失败进"新失败集",稳定后升版本合并
│   └─ 绝不用测试集调 prompt(防污染)
├─ 指标从失败模式反推(抓不到失败的指标是虚荣指标)
│   RAG:忠实度/相关性/上下文精确率/召回率
│   Agent:完成率/工具正确率/约束违反率/每正确答案成本
│   通用:拒答率/格式合规/P95/单次成本/一致性
├─ LLM-as-judge 三偏差:循环论证/位置偏差/长度偏差
│   缓解:换厂商标判 + 随机交换位置 + 5% 人工校准
├─ 焊进 CI:prompt/检索/模型/知识库改动必跑
│   红灯规则:质量下限 + 延迟上限 + 成本上限 + 回归保护
│   原则:没绿灯不许合并;紧急可绕但 48h 内补跑
└─ 线上监控:开发 100% / 生产 5–20% / 错误多采
    漂移三源:知识库变 / 用户问法变 / 模型变;每周重跑

常见坑

  1. 用测试集调 prompt:分数虚高,线上翻车。golden set 是考卷不是练习册。
  2. 随机抽 case 当测试集:抽到的全是正常样本,失败模式零覆盖,等于没测。
  3. 指标凭空定:没有对应失败模式的指标只是虚荣数字,涨了也发现不了真问题。
  4. 只用单一模型当裁判:循环论证 + 位置/长度偏差叠加,系统性虚高。
  5. 忘了位置偏差:成对比较不交换顺序,判官永远偏向某一个位置。
  6. golden set 从不冻结:每次加题导致分数变化混进"题变难",无法判断系统涨跌。
  7. 只看离线不顾线上:离线全绿,但知识库/问法/模型已漂移,真实表现早崩了。
  8. CI 门禁没有回归保护:守了绝对下限却放过"比上周差一截"的隐性退化。
  9. 告警只有一条线:要么不响要么狂响,PM 对波动麻木,真事故被淹没。
  10. 评测报告写成长文:结论埋在倒数第二段,没人看,跑评测变成走过场。

结语

没有评测的 AI 项目,迭代全靠感觉,上线只能靠运气。评测不是上线前的一道手续,而是 AI PM 贯穿产品全生命周期的底层操作系统——它定义"好",守住"好",并证明"还好吗"。


本文为「AI 产品经理入门与进阶」系列第 09 篇。数据来源:本系列第 01 篇对 654 份产品经理 JD 的分析(32% 岗位要求 evals 能力)、公开 LLM 评测框架技术文档(Ragas / DeepEval / Arize Phoenix / LangSmith)、LLM-as-judge 偏差相关研究。数据用于说明趋势与方法,具体数值随技术迭代变化,请以最新数据为准。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐