AI 评测系列(07):自定义 Benchmark——从业务场景到评测集
公开 Benchmark 不够用的三种情况
MMLU、HELM、BIG-Bench 这些通用基准测的是模型在学术任务上的表现,跟你的业务场景之间隔着一条鸿沟。什么时候需要自己动手搭评测集?下面三种情况,任何一条满足,都值得认真考虑。

情况 1:业务场景过于特殊
举个真实的例子:某车企的售后知识库问答系统,用户会问“大众迈腾 B8 车型 2023 款的 DSG 变速箱保修期是多少”。这种问题,公开 Benchmark 里根本找不到——领域术语、用户问法、答案格式全都是企业独有的。通用评测帮不上忙。
情况 2:数据不能出域
医疗、金融、政务场景的评测数据里往往包含敏感信息,不能上传到第三方平台。那就只能在内部自建评测集,自己跑,自己看结果。
情况 3:需要持续监控质量变化
公开 Benchmark 是静态的,跑一次就结束了。但线上系统迭代频繁,模型升级、知识库更新、prompt 调整,每一步都可能影响回答质量。自定义 Benchmark 的好处是:可以随时加入新问题,更新 ground_truth,追踪每次变更后的质量变化(Delta),让效果变化可量化、可追溯。
构建流程
Step 1:定义评测场景
动手之前,先想清楚这个评测集要覆盖哪些用户意图。别试图覆盖所有可能的问题,那会把自己累死,而且没必要。以企业文档问答为例,常见的场景分类可以这样切:
# eval_scenarios.yaml
scenarios:
- id: S01
name: 事实查询
description: 用户问文档中明确存在的事实
examples:
- "退款政策是什么?"
- "产品质保期多长?"
target_metric: Faithfulness (答案不能超出文档内容)
- id: S02
name: 流程指引
description: 用户询问如何完成某个操作
examples:
- "怎么申请发片?"
- "如何修改收货地址?"
target_metric: Answer Relevancy + Completeness
- id: S03
name: 比较判断
description: 用户需要比较多个选项
examples:
- "普通配送和快递配送有什么区别?"
- "黄金会员和铂金会员的区别?"
target_metric: Context Recall (两个选项的信息都要检索到)
- id: S04
name: 边界测试
description: 知识库中没有答案的问题
examples:
- "你们支持加密货币支付吗?"(实际不支持)
target_metric: Rejection Rate (拒答而不是幻觉)
一个实用的 Benchmark 通常覆盖 4-8 个场景,每个场景 10-20 个问题,总量控制在 50-150 题。太少统计意义不显著,太多构建和维护成本又会飙升。
Step 2:生成问题
方法 A:人工编写(最准确,成本最高)
优点:覆盖真实用户问法,无数据污染风险
缺点:慢,每道题需要领域专家审核
适合:高安全要求场景,评测集 < 50 题
方法 B:LLM 生成 + 人工审核(推荐)
QUESTION_GEN_PROMPT = """根据以下文档内容,生成 {n} 个测试问题。要求:
- 问题要模拟真实用户的问法,使用自然口语
- 覆盖以下场景类型:{scenarios}
- 不要问文档中没有答案的问题(边界测试除外)
- 不要重复问同一个信息点
文档内容:{document}
输出格式(每行一个问题):
1. [问题]
2. [问题]
..."""
生成之后,人工需要做两件事:第一,过滤掉明显错误的问题(歧义、语法错误、重复);第二,抽样验证——随机选 20% 的问题,确认知识库里确实有对应的答案。
方法 C:从生产日志挖掘(最真实)
如果系统已经在线上运行,直接拿真实用户的查询来采样,这是最宝贵的来源——这些问题是用户真在问的,不是我们拍脑袋猜的。
# 从 Langfuse 或应用日志采样
def sample_from_production_logs(logs, n=100):
"""采样生产日志中的真实用户查询作为测试问题"""
# 去重(相同问题只保留一个)
unique_queries = deduplicate(logs)
# 按场景类型分层采样
stratified = stratified_sample(unique_queries, n)
return stratified
Step 3:准备 ground_truth
ground_truth 的质量直接决定评测的可信度。来看两个例子:
不好的 ground_truth(太模糊):
问题:退款政策是什么?
ground_truth:可以退款
好的 ground_truth(足够具体,和 FAQ 内容对齐):
问题:退款政策是什么?
ground_truth:购买后 7 天内可全额退款,7-30 天退 50%,30 天后不退款。退款申请需在订单详情页提交,处理时间 3-5 个工作日。
编写 ground_truth 的几个核心规则:
- 直接引用文档内容,不要概括或改写
- 数字、产品名、具体条款等细节必须保留(这些是 Faithfulness 评测的重要锚点)
- 如果一个问题有多个正确答案,全部写进去
- 边界测试的 ground_truth 统一写“该信息在知识库中不存在”
Step 4:难度分层
难度分层能让你知道系统在哪个级别上出了问题,这比只看一个整体通过率数字有价值得多。先分三个难度层:
Easy(应该接近满分):单文档、单段落能直接找到答案
例:问题和答案在同一个 chunk 里,直接检索就能命中
Medium(评测真实能力):需要整合同文档的多个段落,或者答案表述与问题用词差异较大
例:问题用"申请发片",文档里用"开具发片凭证"
Hard(暴露系统瓶颈):需要跨文档推理,或者隐式推断,或者边界情况
例:"购买了 A 和 B 两个产品,分开退款和合并退款哪个合算?"
初始难度怎么分配?别凭直觉猜。先把所有问题都跑一遍,用系统的实际表现来校准:通过率高的归 Easy,通过率低的归 Hard,中间的归 Medium。
def calibrate_difficulty(eval_results: list[dict]) -> dict:
"""根据实际通过率校准难度"""
for result in eval_results:
score = result["a vg_score"]
if score >= 0.85:
result["difficulty"] = "Easy"
elif score >= 0.60:
result["difficulty"] = "Medium"
else:
result["difficulty"] = "Hard"
return eval_results
Step 5:版本管理
评测集需要版本控制,原因有三:
- 防止标准漂移——如果 ground_truth 被悄悄修改(“这道题写错了,我改一下”),历史数据就不可比了
- 追踪问题集演变——新增了哪些问题,删除了哪些,为什么
- 允许回溯——可以用旧版本评测集验证旧版系统
# eval_dataset_v1.2.yaml
metadata:
version: "1.2.0"
created_at: "2026-06-01"
last_updated: "2026-07-01"
total_questions: 52
breakdown:
easy: 20
medium: 22
hard: 10
changelog:
v1.2.0:
- added 5 questions covering new payment method (Apple Pay)
- updated ground_truth for Q023 (refund policy changed)
v1.1.0:
- calibrated difficulty based on 1000-run baseline
- removed 3 duplicate questions
questions:
- id: Q001
scenario: S01
difficulty: Easy
question: "退款政策是什么?"
ground_truth: "购买后 7 天内可全额退款,7-30 天退 50%,30 天后不退款。"
added_in: "1.0.0"
last_updated: "1.0.0"
版本号建议这样管理:
MAJOR:场景结构重大变化(删除了某个场景类别)
MINOR:新增问题,或修改了问题的 ground_truth
PATCH:修改元数据、注释、格式,不影响评测结果
评测集质量自检
在正式使用评测集之前,花点时间做一遍自检,能省下后面很多麻烦:
问题质量:
□ 每道题都有唯一的正确答案?(避免主观题)
□ 问法多样,不全是"X是什么"格式?
□ 没有 leading question(问题里已经给出答案暗示)
ground_truth 质量:
□ 直接来自文档,没有概括改写?
□ 包含足够的具体细节(数字、名词)?
□ 边界测试的 ground_truth 明确标注"知识库中不存在"?
难度分布:
□ Easy 比例不超过 50%(防止整体数字虚高)
□ Hard 比例不低于 15%(能暴露真实问题)
□ 难度来自实际表现校准,不是主观判断?
覆盖度:
□ 每个场景(S01-S04)都有至少 5 道题?
□ 包含边界测试(知识库中无答案)?
□ 生产日志里的高频问题有覆盖?
总结
- 公开 Benchmark 测通用能力,自定义 Benchmark 测业务场景。企业问答系统拿 MMLU 来评测没什么意义,自己构建 50-150 道针对性题目,更能反映真实质量。
- 难度分层比单一通过率更有诊断价值。85% 通过率,很可能是 Easy 题太多撑起来的;Hard 题的通过率,才暴露系统真正的边界在哪里。
- 评测集本身需要版本控制。ground_truth 变了但不记录版本,历史对比数据就失去了意义。
-
- 关于宇宙的好的网名有哪些
- 角色扮演 | 1
- 网名