Ragas로 RAG 기반 질의응답용 합성 테스트 세트 생성하기
Ragas로 RAG 기반 질의응답용 합성 테스트 세트 생성하기 (Generating a Synthetic Test Set for RAG-Based Question Answering with Ragas)
이 튜토리얼에서는 Ragas의 테스트 세트 생성 모듈을 사용해서 RAG(Retrieval-Augmented Generation) 기반 질의응답 봇을 위한 합성 테스트 세트를 만들어요. 목표는 항공편 예약, 변경·취소, 수하물 정책, 예약 조회, 지연, 기내 서비스, 특별 지원 등 다양한 주제의 고객 질문에 답할 수 있는 Ragas Airline Assistant를 설계하는 것이에요.
출처: 문서
본문
이 튜토리얼에서는 Ragas의 테스트 세트 생성 모듈을 탐구해서 RAG 기반 질의응답 봇을 위한 합성 테스트 세트를 만들 거예요. 목표는 다음을 포함한 다양한 주제의 고객 질문에 답할 수 있는 Ragas Airline Assistant를 설계하는 것이에요.
- 항공편 예약
- 항공편 변경 및 취소
- 수하물 정책
- 예약 조회
- 항공편 지연
- 기내 서비스
- 특별 지원
합성 데이터셋을 가능한 한 현실적이고 다양하게 만들기 위해 다양한 고객 페르소나를 만들 거예요. 각 페르소나는 서로 다른 여행자 유형과 행동을 나타내며, 종합적이고 대표성 있는 테스트 세트를 구축하는 데 도움을 줘요. 이 접근 방식은 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 및 임베딩 모델 설정
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 만들기
문서로 기본 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)
Transform 설정
이 튜토리얼에서는 노드로만 구성된 knowledge graph를 사용해 Single Hop Query 데이터셋을 만들어요. 그래프를 강화하고 쿼리 생성을 개선하기 위해 세 가지 핵심 transform을 적용해요.
- Headline 추출: 언어 모델로 각 문서에서 명확한 섹션 제목을 추출해요 (예: flight cancellations.md에서 "Airline Initiated Cancellations"). 이 제목들은 특정 주제를 분리하고 집중된 질문 생성에 직접적인 컨텍스트를 제공해요.
- Headline 분할: 추출된 headline을 기반으로 문서를 관리 가능한 하위 섹션으로 나눠요. 이는 노드 수를 늘리고 더 세분화되고 컨텍스트 특화된 쿼리 생성을 보장해요.
- Keyphrase 추출: 핵심 주제 키프레이즈(예: 주요 좌석 정보)를 식별해서 의미적 시드 포인트로 사용하며, 생성되는 쿼리의 다양성과 관련성을 풍부하게 해요.
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]
쿼리 생성을 위한 페르소나 구성
페르소나는 컨텍스트와 관점을 제공해서 생성되는 쿼리가 자연스럽고, 사용자 특화적이며, 다양하도록 보장해요. 쿼리를 다른 사용자 관점에 맞춤으로써 테스트 세트가 광범위한 시나리오를 다루게 돼요.
- 첫 비행 승객 (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]
Synthesizer를 사용한 쿼리 생성
Synthesizer는 강화된 노드와 페르소나를 쿼리로 변환하는 역할을 해요. 노드 속성(예: "entities" 또는 "keyphrases")을 선택하고, 페르소나·스타일·쿼리 길이와 짝지은 뒤, LLM을 사용해서 노드 내용을 기반으로 쿼리-답변 쌍을 생성하는 방식으로 이를 달성해요.
SingleHopSpecificQuerySynthesizer의 두 인스턴스를 사용해서 쿼리 분포를 정의해요.
- Headlines 기반 Synthesizer – 추출된 문서 headline을 사용해서 특정 섹션을 참조하는 구조화된 질문을 생성해요.
- Keyphrases 기반 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 |
마무리 (Final Thoughts)
이 튜토리얼에서는 주로 single-hop 쿼리에 초점을 맞춰 Ragas 라이브러리로 테스트 세트 생성을 탐구했어요. 다음 튜토리얼에서는 multi-hop 쿼리를 다루면서 더 풍부한 테스트 세트 시나리오를 위해 이러한 개념을 확장할 거예요.