当前位置: 首页 > news >正文

RAG :构建测试数据集

为什么需要测试集

凭感觉

RAG 系统由检索(Retrieval)和生成(Generation)两个相互耦合的模块组成。调整 chunk 大小、切换 embedding 模型、修改 prompt 等每一项改动都可能以非线性方式影响最终输出质量。

如果没有一套稳定的测试集,只依赖主观感受和随机抽样来判断改动是否有效,效率低下不说,还会在迭代中引入大量不可复现的回归问题。

一份设计良好的测试集是 RAG 工程的第一基础设施,就像传统软件工程中的单元测试一样重要;测试从来都不是可选项,而是保障系统可靠演进的必要条件。

带着BUG上生产,高速路上换轮胎的感觉并不好受。

RAG失败的根源

如果从最终结果质量角度看,RAG 系统失败时,总归都是下面这两个:

  • 检索失败:必要的 chunk 没有被召回,生成模型无从作答
  • 生成失败:检索已经召回了正确的 chunk,但 LLM 没有正确使用,又或者产生了幻觉

这两种失败在端到端表现上很难区分,因为用户看到的都是一个错误的答案。

只有通过结构化的测试集,分别在检索端和生成端设立评估指标,才能将故障精确定位,从而选择正确的修复路径:是优化检索(比如,调整向量权重、扩大召回 K 值),还是优化生成(比如,改写 prompt、增加引用约束)。

测试集 ≠ 训练集

这个不等关系在模型训练上倒是非常直观明显的。

测试集的价值来自于它代表系统"从未见过的真实世界"。一旦测试集与训练数据或 fine-tuning 数据产生交叉,评估指标就会虚高,最终生产使用后可能出现不符合预期的效果。

在模型训练方面,常见的时间维度,测试集只使用模型训练或系统调优截止日期之后收集的数据。

对于没有 fine-tuning 环节的 RAG 系统,则需确保合成测试数据的文档来源与开发调试期间使用的文档没有重叠。


评估什么

检索端 和 生成端

RAG 系统的评估必须同时覆盖两个维度,且它们在概念上是相互独立的。

检索端评估重点关注注检索模块的召回质量。总的来说就是给定一个查询,系统能否将回答该问题所必须的 chunk 排在靠前的位置。核心指标包括 Recall@K、MRR和 NDCG等等

生成端评估重点关注LLM 在给定上下文后的生成质量。也就是常说的生成的答案是否忠实于检索到的 chunk(无幻觉)、是否真正回答了用户的问题(不偏题)、是否覆盖了完整的必要信息(不遗漏)。

这两个维度的失败点完全不同,需要分别设计评估逻辑。如果只是简单的用统一的端到端分数来代替分层评估,就像用应用程序的可用性指标来代替数据库查询延迟差不多,很难针对性具体优化。

端到端 和 分层评估

一般来说,分层评估(检索端 + 生成端分别评估)精度高、定位准,适合开发和调试阶段;端到端评估(直接评估最终答案质量)更接近用户实际需求,适合上线前的综合验收和生产监控。

分层评估用于定位问题,端到端评估用于把关发布。

RAG 与纯检索测试集的关键差异

纯检索系统(如搜索引擎)的测试集只需标注"哪些文档与查询相关",输出的是一个文档列表,用 Recall 和 Precision 来评估。

RAG 系统的测试集则必须额外包含ground_truth_answer因为最终的评估对象是自然语言答案,不是文档列表。

从成本角度来看,这一区别带来了标注成本会明显上升,也是很多团队在 RAG 测试集建设上投入不足的主要原因。但这个成本无法被规避的,因为如果没有标准答案,生成端的评估就失去了基准,幻觉检测也只能依赖不够可靠的无监督方法。


基础设施

chunk_id

chunk_id 不是"标注时想的",是入库时就需要定好的主键。

如何将测试集中的 ground truth 与向量库中的具体 chunk 关联起来?

chunk_id 必须在数据入库时就作为稳定的业务主键生成,而不是在标注阶段临时分配。每个被切分并写入向量库的 chunk,在入库的那一刻就应该持有一个全局唯一、可复现的 ID。

这个 ID 是测试集与向量库之间的唯一匹配关系。没有稳定的 chunk_id,就无法构建可复现的评测集,也无法在分块策略迭代后批量重算 ground truth 的映射关系。

生成策略及适用场景

选择策略的核心原则是可复现性:当分块参数不变时,相同的文档内容应该始终生成相同的 chunk_id。一旦分块策略发生变化(如 chunk 大小从 512 token 调整为 256 token),就需要重新生成 chunk_id 并更新 manifest,同时重新校验测试集的 ground truth 映射。

注意具体也还要看选择想向量库支持程度~

(chroma)

(Qdrant)

chunks_manifest的结构设计

manifest 是连接原始文档与向量库的元数据清单,是整个评测基础设施的基石。

{ "chunk_id": "contract_9912_clause_3_2", "doc_id": "contract_9912.pdf", "source_path": "documents/contracts/contract_9912.pdf", "clause": "3.2", "start_char": 4820, "end_char": 5340, "text_preview": "在等待期内,被保险人因疾病导致的..."}

对于大规模语料库(如 100 万个 chunk),manifest 应存储为 Parquet 格式并以 chunk_id 建立索引,评测脚本只需加载 ID 列和必要的元数据字段,无需将全量文本加载进内存。

如果入库流程没有产出 manifest,标注人员就无从将具体的业务坐标转换为可供评测脚本使用的 chunk_id。建索引和建测试集依赖同一份分块清单,这两件事最好是在系统设计阶段就一并规划,而不是等到需要评估时再补救。


分层设计

问题数 和 chunk 总数

有一个常见的误解是:语料库越大,测试集就需要越多条目。

实际上测试集的规模由问题数量决定,而非 chunk 总数。

比如保险RAG系统,可能100 万个 chunk 的语料库,只需要 200 道测试题,每题标注 1 到 3 个必要 chunk,总共只引用了全库 0.06% 的 chunk。这 200 道题,只要设计合理、覆盖了系统的关键失效模式,就能提供比 10,000 道随机题更有价值的评估信号。

当然,实际上也可以在不同阶段的计划不同规模,比如(按需,按业务,只是个参考):

按查询类型分层

测试集通常需要覆盖不同类型的查询,因为不同类型会触发检索和生成的不同质量差异问题,比如常见类型:

  • 事实型(Factual):问题有明确的单一答案,测试基础召回能力
  • 推理型(Reasoning):答案需要基于检索到的 chunk 进行逻辑推导,测试 LLM 的上下文推理能力
  • 多跳型(Multi-hop):答案需要综合多个 chunk 的信息才能得出,测试跨 chunk 的联合召回与推理
  • 无答案型(Unanswerable):问题在知识库中没有对应信息,系统应拒绝回答而非编造,测试系统的知识边界感知能力

注意,有些论文研究表明,无答案型样本尤为重要,现有 RAG 基准测试很少评估系统处理超出知识库范围问题的能力,而这恰恰是生产系统中高频出现的失效场景。

按难度分层

在每个查询类型内,进一步按难度分层有助于精细化评估系统能力,比如:

  • 简单:答案在单一 chunk 中有明确陈述,无需推理
  • 中等:答案需要结合 2 到 3 个 chunk,或需要基础推理
  • 困难:答案散布在多个语义距离较远的 chunk 中,需要多步推理
  • 对抗:专门设计用来触发系统弱点

数据来源

线上日志

已上线系统的用户查询日志是最接近真实分布的数据来源(没错,很多人喜欢不做测试就上线的)。

从日志中采样的问题天然反映了用户的真实意图、提问习惯和长尾需求,这是任何合成生成方法都无法完全复现的。

使用日志数据需要分层和脱敏处理。

分层采样:原始日志中高频查询会大量重复,尾部查询严重稀少,直接采样会导致测试集分布严重偏斜。应按查询长度、是否包含实体、单轮/多轮对话等维度分层后再按比例采样,确保测试集覆盖完整的流量形态。

脱敏处理:日志中可能包含用户的个人信息或业务敏感数据。在将日志数据纳入测试集之前,必须经过数据脱敏和合规审查,这在医疗、金融等受监管行业中尤为重要。

领域专家

对于很多垂直领域(比如,法律、医疗、金融、工业),领域专家编写的问题和答案标注质量无疑是最高的了。专家能够提供系统性的领域知识覆盖,识别非专业标注者难以发现的细微错误,并提供权威的 ground truth 答案。

但还是那句话经济效益问题,成本和时间周期都会增加很多。

缩小场景,将专家标注限定特定场景比较折中,比如,高风险决策链路上的核心问题、自动评估指标校准用的 golden set,以及争议问题的仲裁。

LLM 合成生成

当缺乏大量标注数据时,利用 LLM 从文档中自动生成问答对是目前最主流的冷启动方案。

比如,RAGAS 框架的合成数据生成模块受 Evol-Instruct 启发,采用演化式生成范式(evolutionary generation paradigm),系统性地从文档中生成具有不同特征的问题,包括推理型、条件型、多上下文型等。相比直接提示 LLM 生成问题,这种方式能产生更高多样性和难度梯度的测试样本,在实际工程中可将数据收集阶段的时间成本可以大幅度降低。

合成数据的最大局限是分布偏差,LLM 倾向于生成"教科书式"的问题,而真实用户的提问方式更口语化、更模糊,且包含大量 LLM 不会主动生成的长尾模式。因此,最好是合成数据应作为补充而非替代,与少量真实日志数据混合使用。

公开数据集

很多时候,特别是在系统早期,没有线上日志、没有足够的专家资源时,公开数据集可以提供一个快速验证评估流程的起点。比如:

  • SQuAD / SQuAD 2.0:维基百科问答,含无答案样本,适合检验基础能力
  • HotPotQA:多跳推理问答,适合评估复杂推理能力
  • MS MARCO:面向搜索的问答数据集,问题分布较接近真实用户
  • MultiHop-RAG:专为 RAG 多跳查询评估设计的基准数据集

公开数据集最大的局限是领域不匹配,因为通用数据集上的高分不能保证在特定垂直领域的表现。它们只应作为流程验证和冷启动工具,而非最终评估基准。


标注流程

全流程概览

RAG 测试集标注不是让人工标注员从头到尾处理每一条数据,而是将人力集中在机器最不确定的部分。

第一层:机器预标

机器预标的目标是利用当前最佳检索系统召回候选 chunk,再用 LLM 作为初步评判者,将高置信度的标注结果直接写入 ground truth,降低后续人工处理量。

def machine_prelabel(question: str, retriever, llm_judge, top_k: int = 50): candidates = retriever.search(question, k=top_k) prelabels = [] for chunk in candidates: # LLM 判断该 chunk 是否能支持回答该问题 score = llm_judge.evaluate_relevance(question, chunk.text) label = { "chunk_id": chunk.id, "text_preview": chunk.text[:200], "confidence": "high" if score > 0.8 else "low", "source": "auto" if score > 0.8 else "human_required" } prelabels.append(label) return prelabels

机器预标的可靠性依赖于当前检索系统的质量。如果系统本身存在系统性偏差(如对某类问题的召回率低),机器预标就会遗漏这些 chunk,导致测试集出现盲点。因此,机器预标的结果必须定期与人工抽检进行比对校验。

第二层:人工精标

人工精标不是让标注员从空白开始,而是在机器预标的 Top-K 候选 chunk 中进行点选确认或修正。

需要的标注工具的核心功能

  • • 展示问题和机器预标的候选 chunk 列表
  • • 支持在列表中直接勾选"必须引用"的 chunk
  • • 自动记录被勾选 chunk 的 ID,一键导出为评测 JSON

相对严谨来说,双人独立标注后进行比对,对于不一致的条目(Inter-Annotator Agreement,IAA 低于阈值的部分)送第三位标注员仲裁。IAA 目标值应高于 Cohen’s Kappa 0.75,低于此阈值通常意味着标注规范不够清晰或任务本身存在歧义。

{ "id": "eval_001", "question": "重疾险等待期内确诊是否赔付?", "ground_truth_chunk_ids": ["POL-2024-001_3_2_1", "POL-2024-001_3_2_2"], "ground_truth_answer": "等待期(通常为 90 天或 180 天)内确诊的重大疾病,保险公司不予赔付,保单继续有效但该次罹患不在保障范围之内。", "answer_type": "factual", "required_chunks_count": 2, "difficulty": "medium", "hallucination_risk": "high", "notes": "需同时引用等待期定义条款与赔付例外条款"}

第三层:专家抽检

标注完成后,随机抽取一定比例的样本由领域专家进行独立重标,将专家判断与第二层结果进行比对。如果错误率超过某个值,整批数据打回第二层重新标注。

这一层是质量保障的最后一道防线,能有效发现标注规范中的歧义点,以及标注员在长时间工作后出现的质量下滑。


冷启动策略

向量相似度阈值

在没有任何标注数据的情况下,余弦相似度得分可以作为检索质量的近似代理指标。通过为检索结果设置相似度阈值(比如 0.8),可以粗略地筛选出与查询高度相关的 chunk,并将其用于系统基线评估。

这种方法的局限性很明显,相似度高不等于内容相关,尤其在领域专用语料中,嵌入模型可能未经过充分的领域适配。但作为冷启动阶段的临时指标,它具有零成本、即时可用的优势。

多 LLM 互评

当没有 ground truth 答案时,可以利用多个 LLM 对同一问题的回答进行互评,将不同模型的输出提交给彼此打分,通过跨模型比较和排名来估算系统的整体生成质量。

注意哈,这种方法并不能替代有标注的评估,但它提供了一种快速、可自动化的方式来识别明显的质量差异,有助于在构建正式测试集之前就发现系统的主要问题点。

合成数据扩充

对于已有的少量高质量样本,可以通过语义变体生成来扩充测试集规模。核心思路是用 LLM 对已有问题进行改写,生成表达方式不同但语义等价的问法。

这类变体对于测试系统的鲁棒性很有价值,因为理想的 RAG 系统对于语义等价的不同问法,应该给出一致质量的回答。

主题拆分

在合成生成之前,先对源文档进行主题拆分,能有效升生成问题的质量和覆盖度。将一段包含多条信息的文本拆解为独立的主题单元,再针对每个单元生成对应的查询-上下文对,可以在不增加人工成本的前提下将数据点数量翻倍,并确保每个问题与其所需的 chunk 有精确的对应关系。


对抗性测试集

掩盖真实弱点

有没有发现实际系统上,很多在标准测试集上取得高分的系统,在生产环境中可能仍然存在严重的失效场景。

这是因为标准测试集往往覆盖了系统最擅长处理的典型问题,而将真正考验系统能力的边界情况排除在外。

现有 RAG 基准测试中的很多"多跳"问题实际上可以通过断开推理链的方式被单步解决,并不真正测试多跳推理能力。对抗性测试集的目标就是堵住这些漏洞。

对抗案例

同义词替换:将查询中的关键词替换为语义等价的同义词或别名(如"阿良" → “亚圣儿子”,“等待期” → “观察期”)。这类问题直接测试 embedding 模型的语义泛化能力。理想的系统对同义词改写后的查询,应该召回相同的 chunk 并给出相同质量的回答。

否定与反问:将标准问题改写为否定或反向形式,这类问题测试系统对否定语义的理解,以及是否会产生与原问题相反的幻觉。

多跳组合:构建需要联合多个语义距离较远的 chunk 才能回答的问题。这是 RAG 系统最具挑战性的场景之一,因为标准的向量检索倾向于召回语义最相似的单一 chunk,而非能够联合支持复杂推理的 chunk 组合。

幻觉诱导:设计问题的描述,可以隐含一个在知识库中并不存在的"事实",测试系统能否识别并拒绝这类带有虚假预设的查询,而非顺势编造答案。

对抗集占比

对抗性样本在测试集中的占比根据实际场景来,比如常见的是,控制在 10%~20%。过高会导致测试集失去对"正常场景"的代表性,但完全不包含则无法发现系统的关键弱点。

优先从线上 bad case 中反向挖掘,已经在生产中出现过的失败案例,是最有价值的对抗性样本来源。每一次线上事故都应该触发一条新的对抗性测试用例,确保相同问题不会再次出现(回归测试)。


测试集的维护

测试集过期

测试集在构建时反映的是特定时间点的系统行为和数据分布。

随着时间推移,几个因素可能会导致测试集逐渐"过期":

  • • 知识库内容更新:原有的 ground truth chunk_id 可能已经不再存在,或对应内容已经修改
  • • 用户行为漂移:线上查询的分布会随着产品迭代和用户群体变化而变化,早期测试集可能不再覆盖当前的主流场景
  • • 模型"刷分":模型在多轮迭代中可能已经对当前测试集过拟合,指标虚高但线上表现并不同步

版本化管理

测试集最好是能像代码一样进行版本管理,每个版本记录构建时间、基于的模型版本、数据来源和状态,比如:

class TestsetVersion: id: str # 如 "v3.2" created_at: datetime # 构建时间 based_on_model: str # 构建时使用的系统版本 data_sources: list[str] # 数据来源描述 status: str # "active" | "deprecated" | "dev" size: int # 题目数量 notes: str # 版本说明

三种状态的含义:

  • active:当前版本,用于正式性能评估和 CI/CD 门禁
  • dev:开发调试版本,用于日常迭代中的快速验证
  • deprecated:已废弃版本,仅供历史追溯

持续迭代机制

测试集不是一次性产出,而是需要持续维护的。

bad case 回流是持续迭代中最重要的机制,每一个从线上发现的系统失败或者说用户倒赞,都应该在测试集中留下痕迹。这不仅防止了已知问题的回归,还让测试集的分布随着时间逐渐逼近真实的场景,从而持续提升测试集的价值。


开源框架

RAGAS

RAGAS(Retrieval Augmented Generation Assessment)是开源评估框架。

  • 无监督评估指标:Faithfulness、Answer Relevancy、Context Precision、Context Recall 四个核心指标均可在无 ground truth answer 的情况下计算,适合生产监控
  • 合成测试数据生成:基于演化式生成范式,从文档自动生成具有多样性和难度梯度的问答对
  • 框架集成:原生支持 LangChain 和 LlamaIndex
  • RAGAS 的主要局限是,其 LLM-as-a-judge 方法在特定领域或特定语言(比如中文)下可能存在评估偏差,需要通过与少量人工标注进行比对来校验可靠性。

ARES

ARES在 RAGAS 的基础上增加了统计稳健性保障。它利用合成数据对轻量级 LLM 进行微调,生成专为特定域定制的评判模型,并采用预测功效推断(Prediction-Powered Inference,PPI)技术生成带置信区间的评估结果。

ARES 的优势在于,它的评估结论具有统计意义上的置信区间,适合需要严格质量报告的场景(如监管审计、学术研究)。

人工标注平台

对于需要大量人工标注的场景,专业的标注平台可以显著提升效率和标注质量:

  • Label Studio:开源、自部署,支持自定义标注界面,适合有数据隐私要求的团队
  • Argilla:为 NLP 任务优化的开源标注平台,内置对 LLM 评估任务的支持

结语

构建 RAG 测试数据集很重,测试集是 RAG 系统唯一可靠的优化基准,其规模由问题数决定,其质量由分层设计和标注流水线保证,其价值由持续迭代维持

RAG 测试集必须同时覆盖检索端(chunk 是否被召回)和生成端(答案是否忠实、完整、相关),这是它区别于纯检索测试集的根本所在。

稳定的 chunk_id 与 manifest 是一切的前提,没有它们,标注工作就缺无从谈起;三层标注流水线(机器预标、人工精标、专家抽检)在控制成本的同时保障了标注质量;对抗性样本(同义词替换、否定反问、多跳组合、幻觉诱导)则弥补了常规测试集对系统弱点的覆盖盲区。

测试集不是一次性产出,而是需要版本化管理、定期刷新、持续回流线上 bad case 的工程资产,只有这样,它才能持续反映系统的真实失效模式,而不是成为被模型"刷分"的静态标靶。

不服跑个分试试也得看测试集是谁出不是~

我使用一个最小可用评测 JSON 格式

{ "id": "eval_001", "question": "重疾险等待期内确诊是否赔付?", "query_type": "factual", "difficulty": "medium", "ground_truth_chunk_ids": [ "POL-2024-001_3_2_1", "POL-2024-001_3_2_2" ], "ground_truth_answer": "等待期(90 天)内确诊不予赔付,保单继续有效。", "required_chunks_count": 2, "hallucination_risk": "high", "data_source": "expert_annotated", "created_at": "2025-05-01", "notes": "需同时引用等待期定义与赔付例外条款"}

学AI大模型的正确顺序,千万不要搞错了

🤔2026年AI风口已来!各行各业的AI渗透肉眼可见,超多公司要么转型做AI相关产品,要么高薪挖AI技术人才,机遇直接摆在眼前!

有往AI方向发展,或者本身有后端编程基础的朋友,直接冲AI大模型应用开发转岗超合适!

就算暂时不打算转岗,了解大模型、RAG、Prompt、Agent这些热门概念,能上手做简单项目,也绝对是求职加分王🔋

📝给大家整理了超全最新的AI大模型应用开发学习清单和资料,手把手帮你快速入门!👇👇

学习路线:

✅大模型基础认知—大模型核心原理、发展历程、主流模型(GPT、文心一言等)特点解析
✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑
✅开发基础能力—Python进阶、API接口调用、大模型开发框架(LangChain等)实操
✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用
✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代
✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经

以上6大模块,看似清晰好上手,实则每个部分都有扎实的核心内容需要吃透!

我把大模型的学习全流程已经整理📚好了!抓住AI时代风口,轻松解锁职业新可能,希望大家都能把握机遇,实现薪资/职业跃迁~

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

http://www.jsqmd.com/news/925373/

相关文章:

  • 戴森球计划工厂蓝图库:5000+模块化工业设计解决方案深度解析
  • Multi-Agent商业模式:平台化生态构建与开发者激励策略
  • 用Arduino Nano与8x8 LED矩阵复刻《太空侵略者》街机游戏
  • 047、知识蒸馏改进 YOLO:用大模型软标签指导小模型训练的全流程实战
  • 企业级微信自动化解决方案:基于Python的智能机器人实战指南
  • 社区老年人健康监护系统原型设计作业 - xiaoxi
  • 如何永久保存微信聊天记录:WeChatMsg让你轻松掌控数字记忆的完整指南
  • 能快速导出无水印的AI证件照一键生成工具有哪些?2026免费无水印AI证件照工具推荐 - 科技大爆炸
  • 197、运动控制中的行业应用:四足机器人步态控制
  • 井下做业实景透明.智能预警透明化三维立体重构AI预判盲区管控
  • 如何打造终极随身游戏库:Playnite便携版完整配置教程
  • 为什么83%的Gemini A/B测试结论被评论数据推翻?——用户原声分析的4个反直觉真相
  • RAG-Anything:港大开源多模态RAG框架,统一处理文本/图像/表格/公式
  • WarcraftHelper:让经典魔兽争霸3在现代电脑上完美运行的8大优化方案
  • UVa 340 Master-Mind Hints
  • 198、运动控制中的行业应用:软体机器人控制
  • 终极指南:如何永久保存微信聊天记录并生成年度情感报告
  • 别再只懂理论了!用C语言实战FIR滤波器设计:避坑指南与代码优化技巧
  • Harness Engineering:Agent任务优先级调度算法
  • 除了微信扫一扫,试试这款专业条码扫描APP:Scandit(附iOS/Android下载与使用体验)
  • 逆向工程实现PC端微信QQ防撤回功能的技术方案
  • 【Ragent】企业级 Agentic RAG 智能体:让 AI 落地从“调 API“变成“真工程“
  • 陕西全屋定制行业 GEO 优化科普:3 分钟看懂 AI 时代如何获客
  • 别再死记硬背了!用Python实战拆解CS224W中的传统图特征:从节点中心性到Graphlet
  • 抖音批量下载助手:3分钟掌握全自动视频保存的终极方案
  • 有线耳机改造:焊接3.5mm母座实现可换线升级与维修
  • 200、运动控制算法总结与未来展望:AI与边缘计算
  • 如何永久保存微信聊天记录:WeChatMsg本地化数据管理方案
  • 【Gemini 2.5重磅升级全解读】:谷歌AI团队亲授5大核心突破与企业落地避坑指南
  • 【Gemini广告创意策划黄金法则】:20年AI营销专家亲授5大不可绕过的策略盲区