RAG Pipelines Essentials
> Retrieval-Augmented Generation (RAG) membuat jawaban LLM berpijak pada data milik kita sendiri, bukan hanya mengandalkan apa yang "diingat" model dari training. Notebook ini membahas pipeline intinya, keputusan desain utama, dan contoh singkat merangkainya.
Apa itu RAG?
Pengetahuan LLM itu beku sejak waktu training dan terbatas oleh context window-nya. RAG mengatasi kedua batasan itu: alih-alih meminta model menjawab dari memori, kita lebih dulu retrieve potongan (chunk) relevan dari dokumen kita sendiri, lalu memasukkannya ke prompt sebagai context, baru kemudian meminta model men-generate jawaban.
Hasilnya, model bisa menjawab pertanyaan tentang konten yang tidak pernah dilihatnya saat training — dokumen internal, codebase, tiket support minggu lalu — dengan hallucination yang jauh lebih rendah, karena model menjawab dari teks yang benar-benar ada di depannya.
Kenapa ini penting:
Menjaga jawaban tetap berpijak pada source of truth yang sebenarnya, bukan memori parametrik model
Update instan — re-index dokumen, tidak perlu re-training model
Memungkinkan citation — kita tahu persis chunk teks mana yang menghasilkan jawaban tertentu
Lebih murah dibanding fine-tuning untuk sebagian besar use case "jawab pertanyaan tentang data kami"
Pipeline Inti
Dokumen → Chunking → Embedding → Vector Store
↓
Query User → Embedding → Similarity Search → Chunk Hasil Retrieval
↓
Prompt = Query + Chunk Hasil Retrieval
↓
LLM → Jawaban
1. Ingestion (offline, dilakukan di awal)
Chunking — memecah dokumen menjadi passage yang cukup kecil untuk di-embed secara bermakna dan di-retrieve secara presisi (biasanya 200–1000 token, sering dengan overlap)
Embedding — mengubah setiap chunk menjadi vector menggunakan embedding model
Indexing — menyimpan vector di vector database beserta teks asli dan metadata-nya
2. Retrieval (saat query)
Embed query user dengan embedding model yang sama
Jalankan similarity search (cosine similarity / nearest neighbor) terhadap vector store
Ambil top-k chunk yang paling relevan
3. Generation
Susun prompt yang berisi chunk hasil retrieval plus pertanyaan user
Kirim ke LLM dan kembalikan jawaban yang grounded
Use Case Umum
Internal knowledge assistant — menjawab pertanyaan karyawan dari wiki, dokumen kebijakan, runbook
Customer support bot — jawaban berpijak pada dokumentasi produk dan tiket-tiket sebelumnya
Codebase Q&A — retrieve file atau function relevan sebelum menjawab "gimana cara kerja X?"
Research assistant — retrieve dari kumpulan paper atau report sebelum menyusun jawaban
Domain yang sensitif terhadap compliance — jawaban harus bisa ditelusuri ke dokumen sumber tertentu
Contoh Praktis: RAG Pipeline Minimal
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain_community.vectorstores import Chroma
# 1. Ingestion — dijalankan sekali, atau setiap kali dokumen sumber berubah
splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)
chunks = splitter.split_documents(raw_documents)
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
vector_store = Chroma.from_documents(chunks, embeddings)
# 2. Retrieval + 3. Generation — dijalankan per query
def answer_question(question: str) -> str:
retrieved = vector_store.similarity_search(question, k=4)
context = "\n\n".join(doc.page_content for doc in retrieved)
prompt = f"""Jawab pertanyaan hanya berdasarkan context di bawah ini.
Kalau context tidak berisi jawabannya, katakan tidak tahu.
Context:
{context}
Pertanyaan: {question}"""
llm = ChatOpenAI(model="gpt-4o-mini")
return llm.invoke(prompt).content
print(answer_question("Apa kebijakan refund untuk subscription tahunan kami?"))
Contoh ini sengaja dibuat minimal — pipeline production biasanya menambahkan re-ranking, metadata filtering, dan citation tracking di atas bentuk dasar yang sama ini.
Keputusan Desain Kunci
Chunk size — terlalu kecil kehilangan context, terlalu besar mengencerkan relevansi dan membuang-buang token
Jumlah retrieval (k) — semakin banyak chunk memberi model lebih banyak context, tapi menaikkan cost dan noise
Re-ranking — pass kedua yang lebih presisi (sering pakai cross-encoder) terhadap top-k hasil sebelum masuk prompt, umum dipakai kalau vector search saja belum cukup presisi
Hybrid search — menggabungkan vector similarity dengan keyword search (BM25) untuk menangkap kasus yang terlewat oleh embedding murni, seperti ID persis atau singkatan
Metadata filtering — mempersempit retrieval berdasarkan source, tanggal, atau permission, sebelum atau saat similarity search
Kesalahan Umum
Chunking tanpa memperhatikan struktur — memotong di tengah kalimat atau tengah tabel menurunkan kualitas retrieval
Tidak ada citation/traceability — membuat mustahil untuk memverifikasi atau debug jawaban yang salah
Index yang stale — lupa re-embed saat dokumen sumber berubah
Menganggap retrieval "selesai" setelah launch — kualitas retrieval butuh iterasi dan evaluasi yang sama seriusnya dengan prompt itu sendiri
Key Takeaways
RAG memisahkan "apa yang model tahu" dari "apa yang benar saat ini" dengan retrieve context segar saat query
Pipeline punya dua fase berbeda — ingestion offline, dan retrieval + generation online
Kualitas retrieval, bukan kecerdikan prompt, biasanya jadi faktor terbesar yang menentukan kualitas jawaban
Mulai dari yang sederhana (chunk, embed, retrieve top-k), baru tambahkan re-ranking atau hybrid search setelah benar-benar terukur ada gap-nya
Resources
Dokumentasi RAG LangChain: https://python.langchain.com/docs/tutorials/rag/
"Lost in the Middle" (Liu et al.) — tentang bagaimana posisi context memengaruhi kegunaan retrieval