참고
rag의 정량적 성능 측정 방법으로 가장 잘 알려진 것이 RAGAS이다.
RAGAS는 검색(retrieval)과 생성(generation) 두 측명을 동시에 평가할 수 있다.
이에 대해서 알아보자.
RAG(Retrieval-Augmented Generation)는 대규모 데이터베이스에서 필요한 정보를 검색하고, 이를 바탕으로 답변을 생성하는 기술이다.
기술이 아무리 뛰어나더라도, 정확한 성능 평가 없이는 그 가치를 제대로 보여줄 수는 없다.
RAG 성능 평가란, RAG가 얼마나 효과적으로 작동하는지 측정하는 과정이다.
RAG는 크게 두 단계로 작동한다.
1. 검색 단계: 질문과 관련된 정보를 찾아오는 단계
2. 생성 단계: 찾아온 정보를 바탕으로 답변을 만드는 단계
Retrieval Eveluation
정보를 찾아오는 능력을 쳥가하는 단계이다.
Generation Evaluation
검색된 정보를 바탕으로 얼마나 정확한 답변을 생성하는지 평가한다.
유창성 Fluency
: 답변이 사실에 기반해 정확한 정보를 제공하는지 평가한다.
적응성 Adaptability
: 검색된 정보가 완벽히 일치하지 않더라도, 질문에 적합한 답변을 유연하게 제공할 수 있는지를 평가한다.
일관성 Consistency
: 여러 출처에서 얻은 정보가 서로 모순되지 않고, 논리적으로 연결되어 있는지 평가한다.
End-to-End Evaluation
시스템 전체의 성능을 평가하는 단계로, 검색과 생성이 얼마나 조화를 이루고 있는지 종합적으로 평가한다.
기본의 BLEU, ROUGE와 같은 지표는 주로 기계 번역이나 요약과 같은 특정 태스크에서 사용되며, 주어진 텍스트와 모델이 생성한 텍스트 간의 유사성을 측정한다.
RAG는 정보 검색과 생성이 결합된 복합적인 과정이기 때문에, 단순한 텍스트 유사성 지표로는 그 성능을 충분히 평가하기 어렵다.
즉, RAG의 성능 평가는 정보 검색의 정확성과 생성된 텍스트의 질을 함께 고려해야 한다.
- 검색된 정보의 적합성
- 생성된 답변의 일관성
- 두 과정 간의 시너지 효과를 반영할 수 있는 새로운 지표가 필요

RAGAS(Retrieval-Augmented Generation Assessment)는 RAG 파이프라인의 정량적 평가를 지원하는 오픈 소스 프레임워크이다.
주요 지표는 아래와 같다.
평가 데이터셋에는 ‘question’, ‘ground_truth’ 컬럼이 존재해야 한다.
- question: 사용자 입력에 해당하는 질문
- ground_truth: 질문에 대응되는 정답




from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_community.document_loaders import PyMuPDFLoader
from langchain_community.vectorstores import FAISS
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough
from langchain_core.prompts import PromptTemplate
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
# 단계 1: 문서 로드(Load Documents)
loader = PyMuPDFLoader("data/SPRI_AI_Brief_2023년12월호_F.pdf")
docs = loader.load()
# 단계 2: 문서 분할(Split Documents)
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=50)
split_documents = text_splitter.split_documents(docs)
# 단계 3: 임베딩(Embedding) 생성
embeddings = OpenAIEmbeddings()
# 단계 4: DB 생성(Create DB) 및 저장
# 벡터스토어를 생성합니다.
vectorstore = FAISS.from_documents(documents=split_documents, embedding=embeddings)
# 단계 5: 검색기(Retriever) 생성
# 문서에 포함되어 있는 정보를 검색하고 생성합니다.
retriever = vectorstore.as_retriever()
# 단계 6: 프롬프트 생성(Create Prompt)
# 프롬프트를 생성합니다.
prompt = PromptTemplate.from_template(
"""You are an assistant for question-answering tasks.
Use the following pieces of retrieved context to answer the question.
If you don't know the answer, just say that you don't know.
#Context:
{context}
#Question:
{question}
#Answer:"""
)
# 단계 7: 언어모델(LLM) 생성
# 모델(LLM) 을 생성합니다.
llm = ChatOpenAI(model_name="gpt-4o", temperature=0)
# 단계 8: 체인(Chain) 생성
chain = (
{"context": retriever, "question": RunnablePassthrough()}
| prompt
| llm
| StrOutputParser()
)
→ 배치 데이터셋을 생성
batch_dataset = [question for question in test_dataset["question"]]
batch_dataset[:3]
→ batch() 를 호출하여 배치 데이터셋에 대한 답변 받기
answer = chain.batch(batch_dataset)
answer[:3]
→ LLM이 생성한 답변을 answer 컬럼에 저장
# 'answer' 컬럼 덮어쓰기 또는 추가
if "answer" in test_dataset.column_names:
test_dataset = test_dataset.remove_columns(["answer"]).add_column("answer", answer)
else:
test_dataset = test_dataset.add_column("answer", answer)
⭐ RAGAS 메인 코드
from ragas import evaluate
from ragas.metrics import (
answer_relevancy,
faithfulness,
context_recall,
context_precision,
)
result = evaluate(
dataset=test_dataset,
metrics=[
context_precision,
faithfulness,
answer_relevancy,
context_recall,
],
)
result
# {'context_precision': 0.8000, 'faithfulness': 0.6689, 'answer_relevancy': 0.7836, 'context_recall': 0.7667}
Q. question, answer, ground truth, context가 제공되면 라이브러리를 활용해 별도의 추가 구현 없이 faithfulness, context recall 등을 구할 수 있는가?
A. 가능. 다만 “완전 무설정”은 아님. 컬럼 형식과 LLM/임베딩 백엔드 설정이 필요하다.
✅ 핵심 요건
question:str, answer:str, contexts:list[str], ground_truths:list[str](※ context_recall에 필요)✅ 지원 예
faithfulness(LLM 필요)answer_relevancy(LLM 필요)context_precision(LLM+임베딩)context_recall(LLM+임베딩+ground_truths 필요)✅ 최소 예시
from datasets import Dataset
from ragas import evaluate
from ragas.metrics import faithfulness, answer_relevancy, context_precision, context_recall
from ragas.llms import OpenAI as RagasOpenAI
from ragas.embeddings import OpenAIEmbeddings
data = {
"question": ["Q1", "Q2"],
"answer": ["A1", "A2"],
"contexts": [["ctx1a","ctx1b"], ["ctx2a","ctx2b"]],
"ground_truths": [["gt1"], ["gt2"]], # 없으면 context_recall 계산 불가
}
ds = Dataset.from_dict(data)
llm = RagasOpenAI(model="gpt-5", api_key="...") # 또는 litellm/로컬 LLM
emb = OpenAIEmbeddings(model="text-embedding-3-large", api_key="...")
result = evaluate(
ds,
metrics=[faithfulness, answer_relevancy, context_precision, context_recall],
llm=llm,
embeddings=emb,
)
print(result) # 각 지표의 평균과 샘플별 점수 포함
✅ 정리
ground_truths가 없으면 context_recall은 제외하고 faithfulness 등만 계산하면 된다.