用 Ragas 为基于 RAG 的问答生成合成测试集
概述
在本教程中,我们将探索 Ragas 中的测试集生成模块,为一个 基于 Retrieval-Augmented Generation(RAG)的问答机器人 创建 合成测试集。我们的目标是设计一个能够回答各类客户查询的 Ragas Airline Assistant,主题包括:
- 航班预订
- 航班变更与取消
- 行李政策
- 查看预订
- 航班延误
- 机上服务
- 特殊协助
为了让合成数据集尽可能 真实且多样,我们将创建 不同的客户 persona。每个 persona 代表不同的旅客类型与行为,帮助我们构建 全面且有代表性的测试集。这种方法确保我们可以充分评测 RAG 模型的有效性与稳健性。
让我们开始吧!
下载并加载文档
运行下面的命令,下载虚拟的 Ragas Airline 数据集,并用 LangChain 加载文档。
! git clone https://huggingface.co/datasets/vibrantlabsai/ragas-airline-dataset
from langchain_community.document_loaders import DirectoryLoader
path = "ragas-airline-dataset"
loader = DirectoryLoader(path, glob="**/*.md")
docs = loader.load()
设置 LLM 与 Embedding Model
from ragas.llms import LangchainLLMWrapper
from ragas.embeddings import OpenAIEmbeddings
from langchain_openai import ChatOpenAI
import openai
generator_llm = LangchainLLMWrapper(ChatOpenAI(model="gpt-4o-mini"))
openai_client = openai.OpenAI()
generator_embeddings = OpenAIEmbeddings(client=openai_client, model="text-embedding-3-small")
创建 Knowledge Graph
用文档创建基础知识图谱
from ragas.testset.graph import KnowledgeGraph
from ragas.testset.graph import Node, NodeType
kg = KnowledgeGraph()
for doc in docs:
kg.nodes.append(
Node(
type=NodeType.DOCUMENT,
properties={"page_content": doc.page_content, "document_metadata": doc.metadata}
)
)
kg
输出
KnowledgeGraph(nodes: 8, relationships: 0)
设置 transforms
在本教程中,我们使用仅由节点构成的知识图谱创建一个 Single Hop Query 数据集。为了增强图谱并改进查询生成,我们应用三项关键变换:
- Headline Extraction(标题抽取): 使用语言模型从每篇文档中抽取清晰的章节标题(例如 flight cancellations.md 中的 “Airline Initiated Cancellations”)。这些标题把具体主题隔离开,并为生成聚焦问题提供直接上下文。
- Headline Splitting(按标题切分): 根据抽取出的标题把文档分成可管理的子章节。这会增加节点数量,并确保查询生成更细粒度、更贴合上下文。
- Keyphrase Extraction(关键短语抽取): 识别核心主题关键短语(例如关键座位信息),作为语义种子点,丰富生成查询的多样性与相关性。
from ragas.testset.transforms import apply_transforms
from ragas.testset.transforms import HeadlinesExtractor, HeadlineSplitter, KeyphrasesExtractor
headline_extractor = HeadlinesExtractor(llm=generator_llm, max_num=20)
headline_splitter = HeadlineSplitter(max_tokens=1500)
keyphrase_extractor = KeyphrasesExtractor(llm=generator_llm)
transforms = [
headline_extractor,
headline_splitter,
keyphrase_extractor
]
apply_transforms(kg, transforms=transforms)
Applying HeadlinesExtractor: 100%|██████████| 8/8 [00:00<?, ?it/s]
Applying HeadlineSplitter: 100%|██████████| 8/8 [00:00<?, ?it/s]
Applying KeyphrasesExtractor: 100%|██████████| 25/25 [00:00<?, ?it/s]
为查询生成配置 Personas
Personas 提供上下文与视角,确保生成的查询自然、贴合用户、并且多样。通过针对不同用户观点定制查询,我们的测试集覆盖了广泛场景:
- First Time Flier: 生成带有详细、逐步指导的查询,面向需要清晰说明的新手。
- Frequent Flier: 为有经验的旅客生成简洁、注重效率的查询。
- Angry Business Class Flier: 生成带有批评、紧迫语气的查询,以反映高期望与立即解决问题的需求。
from ragas.testset.persona import Persona
persona_first_time_flier = Persona(
name="First Time Flier",
role_description="Is flying for the first time and may feel anxious. Needs clear guidance on flight procedures, safety protocols, and what to expect throughout the journey.",
)
persona_frequent_flier = Persona(
name="Frequent Flier",
role_description="Travels regularly and values efficiency and comfort. Interested in loyalty programs, express services, and a seamless travel experience.",
)
persona_angry_business_flier = Persona(
name="Angry Business Class Flier",
role_description="Demands top-tier service and is easily irritated by any delays or issues. Expects immediate resolutions and is quick to express frustration if standards are not met.",
)
personas = [persona_first_time_flier, persona_frequent_flier, persona_angry_business_flier]
使用 Synthesizers 生成查询
Synthesizers 负责把增强后的节点和 personas 转换成查询。它们通过选择一个节点属性(例如 "entities" 或 "keyphrases"),把它与 persona、风格和查询长度配对,然后使用 LLM 基于节点内容生成 query-answer 对。
使用两个 SingleHopSpecificQuerySynthesizer 实例来定义查询分布:
- Headlines-Based Synthesizer – 使用抽取的文档标题生成查询,得到引用特定章节的结构化问题。
- Keyphrases-Based Synthesizer – 围绕关键概念形成查询,生成更宽、更主题化的问题。
两个 synthesizer 权重相同(各 0.5),确保具体查询与概念性查询均衡混合,最终增强测试集的多样性。
from ragas.testset.synthesizers.single_hop.specific import (
SingleHopSpecificQuerySynthesizer,
)
query_distibution = [
(
SingleHopSpecificQuerySynthesizer(llm=generator_llm, property_name="headlines"),
0.5,
),
(
SingleHopSpecificQuerySynthesizer(
llm=generator_llm, property_name="keyphrases"
),
0.5,
),
]
测试集生成
from ragas.testset import TestsetGenerator
generator = TestsetGenerator(
llm=generator_llm,
embedding_model=generator_embeddings,
knowledge_graph=kg,
persona_list=personas,
)
现在我们可以生成测试集。
testset = generator.generate(testset_size=10, query_distribution=query_distibution)
testset.to_pandas()
Generating Scenarios: 100%|██████████| 2/2 [00:00<?, ?it/s]
Generating Samples: 100%|██████████| 10/10 [00:00<?, ?it/s]
输出
| user_input | reference_contexts | reference | synthesizer_name | |
|---|---|---|---|---|
| 0 | Wut do I do if my baggage is Delayed, Lost, or... | [Baggage Policies\n\nThis section provides a d... | If your baggage is delayed, lost, or damaged, ... | single_hop_specifc_query_synthesizer |
| 1 | Wht asistance is provided by the airline durin... | [Flight Delays\n\nFlight delays can be caused ... | Depending on the length of the delay, Ragas Ai... | single_hop_specifc_query_synthesizer |
| 2 | What is Step 1: Check Fare Rules in the contex... | [Flight Cancellations\n\nFlight cancellations ... | Step 1: Check Fare Rules involves logging into... | single_hop_specifc_query_synthesizer |
| 3 | How can I access my booking online with Ragas ... | [Managing Reservations\n\nManaging your reserv... | To access your booking online with Ragas Airli... | single_hop_specifc_query_synthesizer |
| 4 | What assistance does Ragas Airlines provide fo... | [Special Assistance\n\nRagas Airlines provides... | Ragas Airlines provides special assistance ser... | single_hop_specifc_query_synthesizer |
| 5 | What steps should I take if my baggage is dela... | [Baggage Policies This section provides a deta... | If your baggage is delayed, lost, or damaged w... | single_hop_specifc_query_synthesizer |
| 6 | How can I resubmit the claim for my baggage is... | [Potential Issues and Resolutions for Baggage ... | To resubmit the claim for your baggage issue, ... | single_hop_specifc_query_synthesizer |
| 7 | Wut are the main causes of flight delays and h... | [Flight Delays Flight delays can be caused by ... | Flight delays can be caused by weather conditi... | single_hop_specifc_query_synthesizer |
| 8 | How can I request reimbursement for additional... | [2. Additional Expenses Incurred Due to Delay ... | To request reimbursement for additional expens... | single_hop_specifc_query_synthesizer |
| 9 | What are passenger-initiated cancelations? | [Flight Cancellations Flight cancellations can... | Passenger-initiated cancellations occur when a... | single_hop_specifc_query_synthesizer |
结语
在本教程中,我们探索了用 Ragas 库生成测试集,主要聚焦 single-hop 查询。在接下来的教程中,我们将深入 multi-hop 查询,在这些概念上扩展,以得到更丰富的测试集场景。