从单点断言到分层证据:一套能进 CI、能阻断发布、也能解释"为什么"的评测门禁。
很多团队做 AI 评测,都是从写断言开始的。
给定输入,期望输出,assert actual == expected。跑通,变绿,心里踏实。
然后模型升了个版本,温度从 0 调到 0.3,检索多召回了一条文档。输出从"退款将在 3 个工作日内到账"变成"一般 3 个工作日左右到账,具体以银行处理为准"。意思没错,甚至更严谨,但断言红了。
于是你把断言放宽成正则,再放宽成关键词命中,最后发现它什么都能过。另一边,真正的事故——答非所问、编造政策、该拒答时瞎答——它一个都没拦住。
这就是"断言失灵":不是断言没用了,而是它只擅长判断形式,判断不了语义;只能覆盖单点,覆盖不了分布。
而 AI 系统的质量,恰恰住在这两个它够不着的地方。
一、断言为什么会失灵
第一,合法解不止一个。
同一句正确的话,可以有无数种说法。"3 个工作日到账"和"三天左右"是一个意思;"建议您联系人工客服"和"这个问题需要专员处理"也是。精确匹配把表达差异当成错误,误报率会高到没人愿意看。
第二,不确定性是系统属性,不是 bug。
温度、采样、检索结果、工具返回、上下文长度,任何一环抖动,输出都会变。就算把温度设成 0,也不等于完全确定——浮点运算、批处理、服务端版本更新,都可能让同一请求得到不同结果。
第三,失败是分布的,不是单点的。
一次 prompt 改动,可能让 95% 的 case 变好、5% 的 case 变差,平均分还涨了。逐条断言看不出这种结构性变化,你只会看到"红了几条",却不知道红的这几条是不是最要命的那几条。
第四,真正的质量在过程里。
RAG 有没有召回正确文档、工具参数填得对不对、多轮对话里有没有丢掉前面的约束——最终那句回答只是最后一环。只断言最终字符串,等于只看体检报告的最后一页。
所以结论不是"扔掉断言",而是:断言该留,但只能守它守得住的那部分——结构、格式、硬约束、安全红线。
二、换个问法:从"这条对不对"到"这次能不能上"
评测的目标不是给模型打个分,而是做一个可辩护的上线决策。
这两个目标听起来接近,做起来差很远。打分只需要一个指标,决策需要回答:证据够不够、差异是不是噪声、最坏情况能不能接受、出了问题怎么退。
所以一套质量门禁至少要包含四个部件:
• 契约:什么算合格?分几档?哪些是零容忍?
• 证据:用什么数据集、什么规则、什么评委、多少人审?
• 决策:阈值多少?差异是否显著?哪个切片能否决?
• 处置:不通过时,是阻断、降级、灰度,还是带期限豁免?
少任何一个,门禁都会退化成报表。尤其是最后一个——没有处置动作的门禁,只是一张没人看的图。
三、四层门禁:把"确定"和"不确定"分开管
我推荐按"确定性从高到低、成本从低到高"分四层。每层职责不同,不要混着用。
L0 硬规则层:零容忍,必须 100%
这一层才是断言的正确用法。适合放四类东西:
• 结构:JSON 能不能解析、字段是否齐全、枚举是否合法
• 事实锚点:引用的文档 ID 是否存在、金额是否等于订单金额、日期是否在有效期内
• 安全与合规:PII 泄漏、违规承诺、越权操作、提示词注入命中
• 业务不变量:退款金额不超过订单金额、推荐的 SKU 必须在库存内
这一层的判定必须确定、可复现、低误报。有一条失败就阻断,不需要统计。
L1 统计门禁层:看分布,不看单条
语义正确率、任务完成率、拒答准确率、检索召回率,这些只能看整体。关键不是"这次 88 分",而是三个问题:
• 和基线比,是涨是跌?
• 置信区间是多少?
• 哪个切片跌了?
L2 语义评委层:把"好不好"拆成可判断的小问题
用 LLM-as-judge,但别让它打 1 到 10 分。分数没有校准,人与人之间都对不齐,何况模型。改成一组二元判断:
• 回答是否直接回应了用户问题?是 / 否
• 每个事实性陈述是否能在检索结果中找到依据?是 / 否
• 是否遗漏了用户明确提出的约束?是 / 否
• 是否包含未经授权的承诺?是 / 否
每条判断要求评委引用原文证据。这样既能算分,也能解释为什么扣分。
如果被测系统是 Agent,还要多评一层轨迹。 工具选对没有、参数填对没有、步数有没有失控、中间失败能不能恢复。只看最终答案,会把"碰巧答对"和"绕了十步才答对"都算成成功,而这两种情况在上线后的成本完全不同。
L3 人工与线上层:处理长尾和真实世界
• 发布前分层抽检,重点看 P0 风险和评委分歧样本
• 上线后灰度,监控 guardrail 触发率、转人工率、投诉率、重试率
• 每周把线上 bad case 回流进评测集
层级 | 判断对象 | 典型方法 | 失败处置 |
L0 硬规则 | 单条输出 | schema、正则、业务校验 | 阻断 |
L1 统计 | 数据集与切片 | 通过率、置信区间、配对检验 | 阻断或告警 |
L2 语义 | 单条或成对 | 二元 rubric 加证据 | 计入统计,重大项阻断 |
L3 人工与线上 | 样本与流量 | 抽检、灰度、业务指标 | 回滚、降级、复盘 |
一句话:确定的东西用规则,概率的东西用统计,主观的东西用校准过的人。
这里还有个容易走偏的地方:什么都想卡。门禁的权威来自克制,只对真正影响用户和业务的事情说不。建议分三级——P0 阻断发布,P1 告警并限期修复,P2 只观测。指标越多,门禁越容易被绕过。
四、三个最容易被忽略的工程细节
1. 样本量不够,阈值就是玄学
n=100、通过率 90%,95% 置信区间大约是 84% 到 96%。也就是说,88% 和 93% 在这个样本量下,你根本分不出谁更好。
几个可以直接用的经验:
• 核心指标每个切片至少 200 条
• 零失败不等于安全:n=100 且零失败时,真实失败率的上界仍有约 3%,这就是"三倍法则"
• 报告点估计的同时报告置信区间,别只报一个数
• 固定样本量或做序贯检验,别"跑到达标就停"
2. 平均值会骗人,切片不会
一个总分成 88 的系统,可能在"退款政策"切片上从 92 掉到 71,只是被其他切片涨上来的分盖住了。用户不会按平均值投诉,他们只会正好撞上那 5%。
建议至少按这几个维度切片:
• 意图或业务场景
• 风险等级:涉及钱、权限、合规的单独切
• 输入长度与语言
• 是否触发工具调用、是否多轮
• 新出现的风险类型
门禁规则可以写成:总分可以涨,但任何 P0 切片不得下跌超过 1 个百分点,其他切片不得超过 3 个百分点。
3. 要配对比较,不要拿两次独立运行比
基线跑一次、新版本跑一次,然后比平均分,这是最常见的错误。两次运行的样本不同、波动不同,差异里混着噪声。
正确做法是同一批 case、同一套评委、同一天跑,做配对比较:
• 二值结果用 McNemar 检验,只看"基线过、新版不过"和"基线不过、新版过"这两类不一致样本
• 连续分数用配对 bootstrap,按 case 重采样,算差异的置信区间
• 同时看 win / loss / tie,不只看均值
这样你才能说出一句站得住的话:"在 500 条配对样本上,新版通过率提升 2.1 个百分点,95% 置信区间 0.4 到 3.8;退款切片下降 1.2 个百分点,但在噪声范围内。"
五、评委要可信,靠的是校准而不是 prompt 写得漂亮
LLM 评委最大的风险不是不准,是不准你还不知道。
几个硬要求:
先有人工标注的校准集。 200 到 300 条,覆盖各切片和边界情况,由业务专家标注。计算评委与人工的一致率,以及更重要的——关键错误的召回率。一致性系数 Cohen's κ 低于 0.6 的评委,不要用来做阻断门禁。
用锚点集监控漂移。 固定一批答案已知的样本,每次换评委模型、改 rubric 都重跑。如果分数突然整体上移,往往是评委变了,不是被测系统变好了。
防三种偏见:
• 位置偏见:成对比较时交换 A、B 顺序,两次一致才算赢
• 长度偏见:长答案更容易被判"更全面",要么控制长度,要么在 rubric 里写明"冗余不加分"
• 自偏好:别用同家族模型评自己,高风险场景用多评委投票或换一个家族
分歧样本要有人看。 评委之间不一致、评委与人工不一致的样本,信息量最大,优先送人工。
六、一套可以照着改的配置
把门禁写成代码,和 prompt、模型版本、数据集版本一起管理。
gate: support-rag-v3 baseline: prod-2026-10-20 datasets: smoke: smoke@1.4 # 80 条,PR 必跑 regression: reg@2.1 # 600 条,nightly challenge: adv@0.9 # 长尾与对抗,每周扩充 hard_rules: # 任一失败即阻断 - json_schema_valid == 1.0 - citation_exists == 1.0 - pii_leak == 0 - unauthorized_commitment == 0 statistical: - metric: task_success min: 0.88 ci_lower_bound: 0.85 - metric: groundedness min: 0.95 - metric: refusal_precision min: 0.90 paired: - slice: "*" max_drop_pp: 3 - slice: "risk:p0" max_drop_pp: 1 human: pre_release_sample: 200 critical_error_rate_max: 0.01 |
对应的 CI 节奏:
• PR:冒烟集、全部硬规则、受影响切片,10 分钟内出结果
• 合并后 / nightly:全量回归、配对检验、评委校准集
• 发版前:全量、人工抽检、红队用例
• 上线:5% 到 25% 再到 100% 灰度,盯业务指标和 guardrail 触发率
成本控制也很现实:小模型做初筛、大模型只复核边界样本;缓存没变的 case;只对 diff 涉及的切片跑全量。全量评测应该是 nightly 的事,不是每次 commit 的事。
另外记得留一个私有 holdout。用测试集调 prompt 调久了,分数会虚高,每季度换一批题,顺便也能发现训练数据泄漏。
七、30 天落地路线
第 1 周:盘点风险,立硬规则。
列出"绝对不能发生"的 5 到 10 件事,全部写成 L0 规则。同时收集 100 条真实 bad case,按意图和风险打标签。
第 2 周:搭统计门禁和切片。
确定 3 到 5 个核心指标,每个核心切片补到 200 条以上。接上基线,先只告警不阻断,看看噪声有多大。
第 3 周:上评委,做校准。
写二元 rubric,标 200 条校准集,算一致率和关键错误召回。κ 不达标就继续改 rubric,别急着上线。
第 4 周:接 CI,定处置。
PR、nightly、发版三档跑起来,明确阻断、告警、豁免的规则。豁免必须记录原因、负责人和到期时间,否则门禁会被一点点绕空。
附:发布前八问
□ 硬规则是否 100% 可复现、误报可接受?
□ 每个核心切片是否至少有 200 条样本?
□ 是否报告了置信区间,而不只是一个点估计?
□ 是否与同批样本的基线做了配对比较?
□ 评委是否有人工校准集,κ 是否达到 0.6?
□ P0 切片是否单独设了阈值?
□ 豁免是否有记录、负责人和到期时间?
□ 线上 bad case 是否有稳定的回流机制?
最后
断言没有错,它只是被要求做了超出能力范围的事。
AI 评测的门禁,本质上不是找一个更聪明的指标,而是承认三件事:
• 有些东西必须确定,那就用规则守住
• 有些东西本质是概率,那就用统计说清楚
• 有些东西只能由人判断,那就把人放进流程,而不是假装评委能替代人
一套好的门禁,最终回答的不是"这个模型有多好",而是"在这次变更、这个场景、这个风险水平下,我们能不能上,出了问题能不能兜住"。
这个答案,比任何一个分数都值钱。