AI 评测系列(07):自定义 Benchmark——从业务场景到评测集

公开 Benchmark 不够用的三种情况

MMLU、HELM、BIG-Bench 测通用能力,不测你的业务场景。三种情况需要自定义:

情况 1:业务场景过于特殊

一个企业的汽车售后知识库问答系统,用户问的是"大众迈腾 B8 车型 2023 款的 DSG 变速箱保修期是多少"。没有任何公开 Benchmark 覆盖这类问题------领域专业度、客户问法、答案格式都是企业特有的。

情况 2:数据不能出域

医疗、金融、政务场景的评测数据包含敏感信息,不能上传到第三方评测平台。需要在内部构建和运行评测集。

情况 3:需要持续监控质量变化

公开 Benchmark 静态,跑一次结束。自定义 Benchmark 可以加入新问题、更新 ground_truth、追踪每次模型或知识库变更后的质量 Delta。


构建流程

Step 1:定义评测场景

先明确这个 Benchmark 要覆盖哪些用户意图,不要试图覆盖所有可能的问题。

以企业文档问答为例,典型的场景分类:

yaml 复制代码
# 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 生成 + 人工审核(推荐)

python 复制代码
QUESTION_GEN_PROMPT = """根据以下文档内容,生成 {n} 个测试问题。

要求:
- 问题要模拟真实用户的问法,使用自然口语
- 覆盖以下场景类型:{scenarios}
- 不要问文档中没有答案的问题(边界测试除外)
- 不要重复问同一个信息点

文档内容:
{document}

输出格式(每行一个问题):
1. [问题]
2. [问题]
..."""

生成后人工做两件事:

  1. 过滤明显错误的问题(歧义、语法错误、重复)
  2. 抽样验证:随机选 20% 的问题,确认知识库中确实有答案

方法 C:从生产日志挖掘(最真实)

如果系统已在运行,从真实用户查询中采样是最有价值的来源------这些问题是用户真实在问的,不是我们猜测的。

python 复制代码
# 从 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 内容对齐):

erlang 复制代码
问题:退款政策是什么?
ground_truth:购买后 7 天内可全额退款,7-30 天退 50%,30 天后不退款。
              退款申请需在订单详情页提交,处理时间 3-5 个工作日。

ground_truth 编写规则:

  • 直接引用文档内容,不改写、不概括
  • 包含数字、名词等具体细节(这些是 Faithfulness 评测的重要锚点)
  • 如果问题有多个正确答案,都写进去
  • 边界测试的 ground_truth 写"该信息在知识库中不存在"

Step 4:难度分层

难度分层让你了解系统在哪个难度级别上出现问题,比单一通过率数字更有价值。

三个难度层:

arduino 复制代码
Easy(应该接近满分):
  单文档、单段落能直接找到答案
  例:问题和答案在同一个 chunk 里,直接检索就能命中

Medium(评测真实能力):
  需要整合同文档的多个段落,或者答案表述与问题用词差异较大
  例:问题用"申请发票",文档里用"开具发票凭证"

Hard(暴露系统瓶颈):
  需要跨文档推理,或者隐式推断,或者边界情况
  例:"购买了 A 和 B 两个产品,分开退款和合并退款哪个合算?"

初始难度分配方法:

先把所有问题都跑一遍,用系统的实际表现来校准难度------通过率高的问题归 Easy,通过率低的归 Hard,中间的归 Medium。不要凭直觉决定哪道题是 Hard。

python 复制代码
def calibrate_difficulty(eval_results: list[dict]) -> dict:
    """根据实际通过率校准难度"""
    for result in eval_results:
        score = result["avg_score"]
        if score >= 0.85:
            result["difficulty"] = "Easy"
        elif score >= 0.60:
            result["difficulty"] = "Medium"
        else:
            result["difficulty"] = "Hard"
    return eval_results

Step 5:版本管理

评测集需要版本控制,原因是:

  1. 防止标准漂移:如果 ground_truth 悄悄被修改("这道题写错了,我改一下"),历史数据就不可比了
  2. 追踪问题集演变:新增了哪些问题,删除了哪些,为什么
  3. 允许回溯:可以用旧版本评测集验证旧版系统
yaml 复制代码
# 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:修改元数据、注释、格式,不影响评测结果

评测集质量自检

在使用评测集之前,做以下检查:

erlang 复制代码
问题质量:
  □ 每道题都有唯一的正确答案?(避免主观题)
  □ 问法多样,不全是"X是什么"格式?
  □ 没有 leading question(问题里已经给出答案暗示)

ground_truth 质量:
  □ 直接来自文档,没有概括改写?
  □ 包含足够的具体细节(数字、名词)?
  □ 边界测试的 ground_truth 明确标注"知识库中不存在"?

难度分布:
  □ Easy 比例不超过 50%(防止整体数字虚高)
  □ Hard 比例不低于 15%(能暴露真实问题)
  □ 难度来自实际表现校准,不是主观判断?

覆盖度:
  □ 每个场景(S01-S04)都有至少 5 道题?
  □ 包含边界测试(知识库中无答案)?
  □ 生产日志里的高频问题有覆盖?

总结

  1. 公开 Benchmark 测通用能力,自定义测业务场景:企业问答系统用 MMLU 评测没有意义,用自己构建的 50-150 道题更能反映真实质量
  2. 难度分层比单一通过率更有诊断价值:85% 通过率可能是 Easy 题太多撑起来的;Hard 题通过率才暴露系统真实的边界
  3. 评测集本身需要版本控制:ground_truth 变了而不记录版本,历史对比数据就失去了意义

欢迎访问 PrimeSkills ------ 一个精心策划的 AI Agent 与技能市场,所有内容均经过真实企业级工作流验证。没有噱头,只有真正有效的东西。

更多实用知识和有趣产品,欢迎访问我的个人主页

相关推荐
骏晔科技DreamLNK2 小时前
国产蓝牙模块哪个品牌好?骏晔科技 7 款主流型号横向对比
人工智能·科技
用户938515635072 小时前
从零搭建 AI 日记助手:用 Milvus 向量数据库 + RAG 让机器读懂你的每一天
javascript·人工智能·全栈
阿部多瑞 ABU3 小时前
新帝国殖民主义:文化-情感-金融复合体的当代运作机制
大数据·人工智能·金融
thesky1234564 小时前
27届大模型岗面试准备(三):位置编码全景——从绝对编码到 RoPE/ALiBi 的演进与手推
人工智能·ai·大模型
动恰客流统计4 小时前
ReID边缘计算视觉统计:餐饮店客流增长的数字化破局路径
java·大数据·运维·人工智能
小小仙子5 小时前
矢量网络分析仪如何测试S参数的?
人工智能·算法·机器学习
IT_陈寒5 小时前
SpringBoot这个分页坑,我踩了三天才爬出来
前端·人工智能·后端
颜酱5 小时前
05 | 召回前置准备:根据业务数据库生成各数据库(读取配置阶段)
前端·人工智能·后端