RAGAS: Framework Evaluasi untuk Pipeline RAG

# RAGAS: Framework Evaluasi untuk Pipeline RAG ## Pendahuluan Retrieval-Augmented Generation (RAG) telah menjadi arsitektur standar untuk membangun aplikasi LLM yang berbasis pengetahuan. Namun, mem...

By Ruby Abdullah · · tutorial
RAGASRAGEvaluationLLMPython

RAGAS: Framework Evaluasi untuk Pipeline RAG

Pendahuluan

Retrieval-Augmented Generation (RAG) telah menjadi arsitektur standar untuk membangun aplikasi LLM yang berbasis pengetahuan. Namun, membangun pipeline RAG saja tidak cukup. Kita perlu cara yang sistematis untuk mengukur kualitas output dari pipeline tersebut. Di sinilah RAGAS (Retrieval Augmented Generation Assessment) hadir sebagai solusi.

RAGAS adalah framework open-source yang dirancang khusus untuk mengevaluasi pipeline RAG secara otomatis. Framework ini menyediakan serangkaian metrik yang mengukur berbagai aspek kualitas, mulai dari relevansi konteks yang diambil hingga kesetiaan jawaban terhadap sumber informasi.

Dalam tutorial ini, kita akan mempelajari cara menginstal dan menggunakan RAGAS, memahami metrik-metrik intinya, membuat dataset evaluasi, mengintegrasikannya dengan LangChain, dan menerapkannya pada contoh praktis untuk mengevaluasi dan meningkatkan sistem QA dokumen.

Instalasi

Instal RAGAS dan dependensi yang diperlukan menggunakan pip:

pip install ragas langchain langchain-openai chromadb

Pastikan Anda memiliki API key OpenAI yang dikonfigurasi sebagai environment variable:

export OPENAIAPIKEY="sk-your-api-key-here"

RAGAS menggunakan LLM (secara default OpenAI) untuk menghitung beberapa metriknya, jadi API key ini diperlukan untuk evaluasi.

Metrik Inti RAGAS

RAGAS menyediakan empat metrik utama yang masing-masing mengukur aspek berbeda dari pipeline RAG:

1. Faithfulness (Kesetiaan)

Faithfulness mengukur sejauh mana jawaban yang dihasilkan konsisten dengan konteks yang diberikan. Metrik ini memastikan bahwa LLM tidak "berhalusinasi" atau menambahkan informasi yang tidak ada dalam dokumen sumber.

from ragas.metrics import faithfulness

Skor 1.0 = semua klaim dalam jawaban didukung oleh konteks

Skor 0.0 = tidak ada klaim yang didukung oleh konteks

Faithfulness dihitung dengan cara:

  • Memecah jawaban menjadi klaim-klaim individual
  • Memverifikasi setiap klaim terhadap konteks yang diberikan
  • Menghitung rasio klaim yang didukung terhadap total klaim

2. Answer Relevancy (Relevansi Jawaban)

Answer Relevancy mengukur seberapa relevan jawaban yang dihasilkan terhadap pertanyaan yang diajukan. Jawaban yang lengkap dan langsung menjawab pertanyaan akan mendapat skor tinggi.

from ragas.metrics import answerrelevancy

Skor tinggi = jawaban sangat relevan dengan pertanyaan

Skor rendah = jawaban tidak relevan atau terlalu umum

3. Context Precision (Presisi Konteks)

Context Precision mengukur seberapa presisi konteks yang diambil. Metrik ini mengevaluasi apakah potongan dokumen yang relevan ditempatkan di peringkat lebih tinggi dibanding yang tidak relevan.

from ragas.metrics import contextprecision

Skor tinggi = konteks relevan berada di posisi atas

Skor rendah = konteks relevan tercampur dengan yang tidak relevan

4. Context Recall (Recall Konteks)

Context Recall mengukur seberapa banyak informasi yang diperlukan untuk menjawab pertanyaan berhasil diambil dari dokumen. Metrik ini membutuhkan ground truth (jawaban referensi) untuk perhitungan.

from ragas.metrics import contextrecall

Skor tinggi = semua informasi yang diperlukan berhasil diambil

Skor rendah = banyak informasi penting yang terlewat

Membuat Dataset Evaluasi

Untuk menjalankan evaluasi RAGAS, kita perlu menyiapkan dataset dalam format yang tepat. Dataset harus berisi: pertanyaan, konteks yang diambil, jawaban yang dihasilkan, dan ground truth (opsional, tapi diperlukan untuk context recall).

from datasets import Dataset

questions = [

"Apa itu machine learning?",

"Bagaimana cara kerja neural network?",

"Apa perbedaan supervised dan unsupervised learning?"

]

groundtruths = [

"Machine learning adalah cabang dari kecerdasan buatan yang memungkinkan sistem belajar dari data tanpa diprogram secara eksplisit.",

"Neural network bekerja dengan meniru cara kerja neuron di otak manusia, menggunakan lapisan-lapisan node yang saling terhubung untuk memproses informasi.",

"Supervised learning menggunakan data berlabel untuk training, sedangkan unsupervised learning menemukan pola dalam data tanpa label."

]

contexts = [

["Machine learning adalah subset dari artificial intelligence yang fokus pada pengembangan algoritma yang dapat belajar dari data. Sistem ML dapat meningkatkan performanya secara otomatis melalui pengalaman."],

["Neural network atau jaringan saraf tiruan terdiri dari lapisan input, hidden, dan output. Setiap node memproses input menggunakan fungsi aktivasi dan bobot yang diperbarui selama training."],

["Dalam supervised learning, model dilatih menggunakan pasangan input-output yang sudah diketahui. Unsupervised learning bekerja dengan data tanpa label, mencari struktur tersembunyi seperti kluster."]

]

answers = [

"Machine learning adalah cabang AI yang memungkinkan komputer belajar dari data secara otomatis tanpa perlu diprogram secara eksplisit untuk setiap tugas.",

"Neural network bekerja dengan memproses data melalui lapisan-lapisan node yang saling terhubung, mirip dengan neuron di otak manusia.",

"Supervised learning menggunakan data berlabel sedangkan unsupervised learning tidak menggunakan label pada datanya."

]

evaldataset = Dataset.fromdict({

"question": questions,

"groundtruth": groundtruths,

"contexts": contexts,

"answer": answers

})

print(evaldataset)

Menjalankan Evaluasi

Setelah dataset siap, kita dapat menjalankan evaluasi dengan metrik yang dipilih:

from ragas import evaluate

from ragas.metrics import (

faithfulness,

answerrelevancy,

contextprecision,

contextrecall

)

result = evaluate(

dataset=evaldataset,

metrics=[

faithfulness,

answerrelevancy,

contextprecision,

contextrecall

]

)

print("Hasil Evaluasi:")

print(f"Faithfulness: {result['faithfulness']:.4f}")

print(f"Answer Relevancy: {result['answerrelevancy']:.4f}")

print(f"Context Precision: {result['contextprecision']:.4f}")

print(f"Context Recall: {result['contextrecall']:.4f}")

Untuk melihat detail per pertanyaan:

df = result.topandas()

print(df[['question', 'faithfulness', 'answerrelevancy',

'contextprecision', 'contextrecall']])

Integrasi dengan LangChain

RAGAS terintegrasi dengan baik dengan LangChain, memungkinkan evaluasi langsung pada chain RAG yang sudah ada:

from langchainopenai import ChatOpenAI, OpenAIEmbeddings

from langchaincommunity.vectorstores import Chroma

from langchain.textsplitter import RecursiveCharacterTextSplitter

from langchain.chains import RetrievalQA

from langchaincommunity.documentloaders import TextLoader

Muat dokumen

loader = TextLoader("knowledgebase.txt")

documents = loader.load()

Split dokumen

textsplitter = RecursiveCharacterTextSplitter(

chunksize=500,

chunkoverlap=50

)

splits = textsplitter.splitdocuments(documents)

Buat vector store

embeddings = OpenAIEmbeddings()

vectorstore = Chroma.fromdocuments(splits, embeddings)

Buat RAG chain

llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)

qachain = RetrievalQA.fromchaintype(

llm=llm,

chaintype="stuff",

retriever=vectorstore.asretriever(searchkwargs={"k": 3}),

returnsourcedocuments=True

)

Jalankan chain dan kumpulkan hasil untuk evaluasi

questions = [

"Apa kebijakan cuti perusahaan?",

"Bagaimana prosedur pengajuan reimbursement?",

"Apa benefit kesehatan yang tersedia?"

]

allanswers = []

allcontexts = []

for question in questions:

response = qachain.invoke({"query": question})

allanswers.append(response["result"])

allcontexts.append(

[doc.pagecontent for doc in response["sourcedocuments"]]

)

Buat dataset evaluasi dari hasil chain

evaldataset = Dataset.fromdict({

"question": questions,

"answer": allanswers,

"contexts": allcontexts,

"groundtruth": groundtruths # Siapkan sebelumnya

})

Evaluasi

result = evaluate(

dataset=evaldataset,

metrics=[faithfulness, answerrelevancy, contextprecision, contextrecall]

)

print("Evaluasi LangChain RAG Chain:")

print(result)

Custom Metrics

RAGAS memungkinkan Anda membuat metrik kustom sesuai kebutuhan:

from ragas.metrics.base import MetricWithLLM

from dataclasses import dataclass, field

@dataclass

class ToneConsistencyMetric(MetricWithLLM):

name: str = "toneconsistency"

evaluationmode: str = "qa"

def init(self, runconfig=None):

pass

async def ascore(self, row, callbacks=None):

"""Evaluasi konsistensi tone jawaban."""

question = row["question"]

answer = row["answer"]

prompt = f"""Evaluasi apakah jawaban berikut menggunakan tone yang

profesional dan konsisten.

Pertanyaan: {question}

Jawaban: {answer}

Berikan skor 0-1 di mana 1 adalah tone paling profesional.

Jawab hanya dengan angka."""

response = await self.llm.ageneratetext(prompt)

try:

score = float(response.generations[0][0].text.strip())

return min(max(score, 0), 1)

except ValueError:

return 0.5

Gunakan metrik kustom

tonemetric = ToneConsistencyMetric()

result = evaluate(

dataset=evaldataset,

metrics=[faithfulness, answerrelevancy, tonemetric]

)

Generasi Test Set Otomatis

RAGAS menyediakan fitur untuk menghasilkan test set secara otomatis dari dokumen Anda:

from ragas.testset.generator import TestsetGenerator

from ragas.testset.evolutions import simple, reasoning, multicontext

from langchainopenai import ChatOpenAI, OpenAIEmbeddings

from langchaincommunity.documentloaders import DirectoryLoader

Muat dokumen

loader = DirectoryLoader("./docs/", glob="*/.txt")

documents = loader.load()

Inisialisasi generator

generatorllm = ChatOpenAI(model="gpt-4o-mini")

criticllm = ChatOpenAI(model="gpt-4o")

embeddings = OpenAIEmbeddings()

generator = TestsetGenerator.fromlangchain(

generatorllm=generatorllm,

criticllm=criticllm,

embeddings=embeddings

)

Generate test set

testset = generator.generatewithlangchaindocs(

documents=documents,

testsize=20,

distributions={

simple: 0.5, # Pertanyaan sederhana

reasoning: 0.25, # Pertanyaan yang butuh penalaran

multicontext: 0.25 # Pertanyaan multi-konteks

}

)

testdf = testset.topandas()

print(f"Generated {len(testdf)} test questions")

print(testdf[['question', 'evolutiontype']].head(10))

Contoh Praktis: Evaluasi dan Peningkatan Sistem QA Dokumen

Mari kita bangun contoh end-to-end di mana kita mengevaluasi sistem QA dokumen dan meningkatkannya berdasarkan metrik RAGAS.

Langkah 1: Bangun Sistem QA Dasar

import os

from langchainopenai import ChatOpenAI, OpenAIEmbeddings

from langchaincommunity.vectorstores import Chroma

from langchain.textsplitter import RecursiveCharacterTextSplitter

from langchain.chains import RetrievalQA

Simulasi knowledge base

knowledgebase = """

Panduan Produk AI Assistant Pro

Fitur Utama

AI Assistant Pro adalah platform AI enterprise yang mendukung pemrosesan

bahasa alami, analisis sentimen, dan ekstraksi informasi. Platform ini

mendukung 50+ bahasa dan dapat diintegrasikan via REST API.

Harga

Paket Starter: Rp 500.000/bulan untuk 10.000 request.

Paket Business: Rp 2.000.000/bulan untuk 100.000 request.

Paket Enterprise: Custom pricing untuk unlimited request.

Integrasi

Platform mendukung integrasi dengan Slack, Microsoft Teams, WhatsApp,

dan Telegram. SDK tersedia untuk Python, JavaScript, dan Java.

Keamanan

Data dienkripsi menggunakan AES-256 at rest dan TLS 1.3 in transit.

Platform comply dengan ISO 27001 dan SOC 2 Type II.

Mendukung SSO via SAML 2.0 dan OAuth 2.0.

Support

Support 24/7 tersedia untuk paket Business dan Enterprise.

Paket Starter mendapat support email dengan SLA 48 jam.

Dokumentasi lengkap tersedia di docs.aiassistantpro.com.

"""

Simpan knowledge base

with open("/tmp/knowledgebase.txt", "w") as f:

f.write(knowledgebase)

Setup RAG pipeline versi 1 (baseline)

from langchaincommunity.documentloaders import TextLoader

loader = TextLoader("/tmp/knowledgebase.txt")

documents = loader.load()

Chunking agresif (chunk kecil)

splitterv1 = RecursiveCharacterTextSplitter(

chunksize=200,

chunkoverlap=20

)

splitsv1 = splitterv1.splitdocuments(documents)

embeddings = OpenAIEmbeddings()

vectorstorev1 = Chroma.fromdocuments(splitsv1, embeddings,

collectionname="v1")

qav1 = RetrievalQA.fromchaintype(

llm=ChatOpenAI(model="gpt-4o-mini", temperature=0),

retriever=vectorstorev1.asretriever(searchkwargs={"k": 2}),

returnsourcedocuments=True

)

Langkah 2: Siapkan Dataset Evaluasi

from datasets import Dataset

evalquestions = [

"Berapa harga paket Business?",

"Apa saja fitur keamanan yang tersedia?",

"Integrasi apa saja yang didukung?",

"Bagaimana SLA support untuk paket Starter?",

"Bahasa pemrograman apa yang didukung SDK-nya?"

]

evalgroundtruths = [

"Paket Business berharga Rp 2.000.000/bulan untuk 100.000 request.",

"Fitur keamanan meliputi enkripsi AES-256 at rest, TLS 1.3 in transit, compliance ISO 27001 dan SOC 2 Type II, serta SSO via SAML 2.0 dan OAuth 2.0.",

"Platform mendukung integrasi dengan Slack, Microsoft Teams, WhatsApp, dan Telegram.",

"Paket Starter mendapat support email dengan SLA 48 jam.",

"SDK tersedia untuk Python, JavaScript, dan Java."

]

Langkah 3: Evaluasi Versi 1

from ragas import evaluate

from ragas.metrics import (

faithfulness, answerrelevancy,

contextprecision, contextrecall

)

Kumpulkan jawaban dari pipeline v1

answersv1 = []

contextsv1 = []

for q in evalquestions:

resp = qav1.invoke({"query": q})

answersv1.append(resp["result"])

contextsv1.append([d.pagecontent for d in resp["sourcedocuments"]])

datasetv1 = Dataset.fromdict({

"question": evalquestions,

"answer": answersv1,

"contexts": contextsv1,

"groundtruth": evalgroundtruths

})

resultv1 = evaluate(

dataset=datasetv1,

metrics=[faithfulness, answerrelevancy, contextprecision, contextrecall]

)

print("=== Hasil Evaluasi V1 (Baseline) ===")

print(f"Faithfulness: {resultv1['faithfulness']:.4f}")

print(f"Answer Relevancy: {resultv1['answerrelevancy']:.4f}")

print(f"Context Precision: {resultv1['contextprecision']:.4f}")

print(f"Context Recall: {resultv1['contextrecall']:.4f}")

Langkah 4: Identifikasi Masalah dan Perbaiki

Berdasarkan hasil evaluasi, jika context recall rendah, itu berarti chunk yang terlalu kecil memecah informasi penting. Mari perbaiki:

# Pipeline V2: Chunk lebih besar + overlap lebih banyak + lebih banyak konteks

splitterv2 = RecursiveCharacterTextSplitter(

chunksize=500, # Chunk lebih besar

chunkoverlap=100 # Overlap lebih banyak

)

splitsv2 = splitterv2.splitdocuments(documents)

vectorstorev2 = Chroma.fromdocuments(splitsv2, embeddings,

collectionname="v2")

qav2 = RetrievalQA.fromchaintype(

llm=ChatOpenAI(model="gpt-4o-mini", temperature=0),

retriever=vectorstorev2.asretriever(searchkwargs={"k": 4}), # Ambil lebih banyak

returnsourcedocuments=True

)

Evaluasi V2

answersv2 = []

contextsv2 = []

for q in evalquestions:

resp = qav2.invoke({"query": q})

answersv2.append(resp["result"])

contextsv2.append([d.pagecontent for d in resp["sourcedocuments"]])

datasetv2 = Dataset.fromdict({

"question": evalquestions,

"answer": answersv2,

"contexts": contextsv2,

"groundtruth": evalgroundtruths

})

resultv2 = evaluate(

dataset=datasetv2,

metrics=[faithfulness, answerrelevancy, contextprecision, contextrecall]

)

print("\n=== Hasil Evaluasi V2 (Improved) ===")

print(f"Faithfulness: {resultv2['faithfulness']:.4f}")

print(f"Answer Relevancy: {resultv2['answerrelevancy']:.4f}")

print(f"Context Precision: {resultv2['contextprecision']:.4f}")

print(f"Context Recall: {resultv2['contextrecall']:.4f}")

Langkah 5: Bandingkan Hasil

import pandas as pd

comparison = pd.DataFrame({

"Metric": ["Faithfulness", "Answer Relevancy",

"Context Precision", "Context Recall"],

"V1 (Baseline)": [

resultv1['faithfulness'],

resultv1['answerrelevancy'],

resultv1['contextprecision'],

resultv1['contextrecall']

],

"V2 (Improved)": [

resultv2['faithfulness'],

resultv2['answerrelevancy'],

resultv2['contextprecision'],

resultv2['contextrecall']

]

})

comparison["Improvement"] = comparison["V2 (Improved)"] - comparison["V1 (Baseline)"]

print("\n=== Perbandingan V1 vs V2 ===")

print(comparison.tostring(index=False))

Tips dan Best Practices

  • Evaluasi secara berkala: Jalankan evaluasi RAGAS setiap kali Anda mengubah pipeline RAG, seperti mengubah chunking strategy, embedding model, atau prompt template.
  • Gunakan test set yang beragam: Pastikan dataset evaluasi mencakup berbagai jenis pertanyaan, mulai dari factual sederhana hingga pertanyaan yang membutuhkan penalaran kompleks.
  • Perhatikan trade-off antar metrik: Meningkatkan satu metrik kadang bisa menurunkan metrik lain. Misalnya, mengambil lebih banyak konteks bisa meningkatkan recall tapi menurunkan precision.
  • Automasi evaluasi dalam CI/CD: Integrasikan evaluasi RAGAS ke pipeline CI/CD Anda untuk mendeteksi regresi kualitas secara otomatis.
  • Kombinasikan dengan evaluasi manual: Metrik otomatis bagus untuk monitoring, tetapi evaluasi manual oleh domain expert tetap penting untuk menangkap nuansa kualitas.
  • Kesimpulan

    RAGAS menyediakan framework yang komprehensif dan mudah digunakan untuk mengevaluasi pipeline RAG. Dengan metrik-metrik seperti faithfulness, answer relevancy, context precision, dan context recall, Anda dapat mengidentifikasi kelemahan spesifik dalam pipeline dan melakukan perbaikan yang terukur.

    Kunci dari evaluasi yang efektif adalah konsistensi. Jalankan evaluasi secara berkala, gunakan dataset yang representatif, dan selalu bandingkan hasilnya dengan baseline. Dengan pendekatan ini, Anda dapat membangun pipeline RAG yang semakin baik dari waktu ke waktu.

    Untuk informasi lebih lanjut, kunjungi dokumentasi resmi RAGAS di docs.ragas.io.

    Artikel Terkait

    DSPy: Berhenti Ngoprek Prompt Manual, Biarkan Compiler yang Optimasi

    DSPy: Berhenti Ngoprek Prompt Manual, Biarkan Compiler yang Optimasi Halo temen-temen, kali ini aku mau ngenalin satu li...

    Inspect AI: Framework Evaluasi LLM dari UK AI Safety Institute

    Inspect AI: Framework Evaluasi LLM dari UK AI Safety Institute yang Wajib Kamu Coba Temen-temen, kalau kamu udah mulai s...

    Tutorial Lengkap Braintrust: Evaluasi, Testing, dan Improve Aplikasi LLM

    Tutorial Lengkap Braintrust: Evaluasi, Testing, dan Improve Aplikasi LLM Halo temen-temen, di tutorial kali ini aku mau ...

    Tutorial LangChain: Framework Paling Populer untuk Membangun Aplikasi LLM

    Tutorial LangChain: Framework Paling Populer untuk Membangun Aplikasi LLM LangChain adalah framework open-source yang di...