Evaluation-Benchmark-RAG

一次人工抽查看起来变好,无法判断是切分、召回还是运气。根因是没有固定集与冻结协议。本方法锁评测集、指标与随机种子做回归。集与线上分布漂移时,门禁会失效,要看离线–线上相关。

本文属于 RAG 工程框架中的「6 模块化架构与评估闭环」环节,聚焦「Evaluation Benchmark(评测基准)」方法。

定位

维度 内容
角色 可复现回归门禁
输入 → 输出 系统版本 → 指标向量 → pass/fail
默认组合 RAGAS、DeepEval、TruLens;检索子集可挂 BEIR 口径
何时不用 还没有冻结的金标准,先别当门禁

核心机制

同一 commit 重复跑,分数方差应可忽略。一次只解冻被测模块。

实现路径与心智:锁数据集、指标、随机种子与冻结协议,CI 跑回归。底层心智:测量协议是产品的一部分。同时改切分和检索,数字就不可归因。

优缺点

  • 优点:可复现比较。
  • 缺点:集维护成本高;会过拟合门禁集。

契约与走通样例

输入

1
{"benchmark": "bio_methods_v1", "n_queries": 300, "seed": 42}

中间量

版本 A:Recall@10=$0.84$ < 门禁 $0.85$ → fail。版本 B:$0.88$ 且 P95 未破 → pass。

输出

1
{"recall_at_10": 0.88, "citation_precision": 0.90, "p95_ms": 840, "decision": "pass"}

社区实现

RAGAS。风险:LLM-judge 不锁温度等于测噪声。

工程落地

最小可运行示例

复制为 .py 后直接运行(仅标准库)。评测集与系统输出都冻结 seed;盲测集不要拿来调参。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
"""固定问答集上算 Recall@k,再聚合。"""
from __future__ import annotations

from dataclasses import dataclass
import random


@dataclass
class EvalRow:
"""一条评测问。gold 是应召回的 chunk_id 集合。"""

query: str
gold: set[str]


class ToySystem:
"""被测系统。生产对应完整 RAG;此处用关键词命中模拟。"""

def __init__(self, corpus: dict[str, str], seed: int = 42) -> None:
self.corpus = corpus
random.seed(seed)

def retrieve(self, query: str, k: int) -> list[str]:
q = set(query.lower().split())
ranked = sorted(self.corpus, key=lambda i: -len(q & set(self.corpus[i].lower().split())))
return ranked[:k]


def recall_at_k(gold: set[str], hits: list[str]) -> float:
if not gold:
return 0.0
return len(gold & set(hits)) / len(gold)


def run_benchmark(system: ToySystem, dataset: list[EvalRow], k: int) -> dict[str, float]:
"""输出指标字典。"""
scores = [recall_at_k(row.gold, system.retrieve(row.query, k)) for row in dataset]
return {"recall@k": sum(scores) / len(scores), "n": float(len(scores))}


if __name__ == "__main__":
corpus = {
"P-GAPDH-01-C1": "GAPDH siRNA 20 nM for 48 h",
"P-noise": "primer sequences",
}
dataset = [EvalRow("GAPDH 处理多久", {"P-GAPDH-01-C1"})]
print(run_benchmark(ToySystem(corpus), dataset, k=1))

参数

参数 起点 影响
fixed_seed 42 可复现
门禁 略低于当前基线 过紧无法迭代
盲测集 与 dev 分开 防过拟合

失效—信号—螺丝

  • 与线上漂移:离线过、线上崩。螺丝:看离线–线上 Spearman。
  • 只看相关不看引用:螺丝:加 CiteP。
  • 调参打同一 dev:螺丝:锁盲测。

规模(100 篇生物学 PDF)

200–500 条生物问答全链路约 0.5–4 GPU·h/次。评测集存储 < 2 GB

-------------本文结束感谢您的阅读-------------