π‘οΈ Hallucination Mitigation & Grounding β CRAG, Self-RAG, dan Verifikasi Faktual
Hallucination adalah masalah #1 RAG di production β LLM menjawab dengan informasi yang tidak ada di konteks, atau kontradiksi dengan konteks. Dokumen ini membahas penyebab hallucination, teknik mitigasi dari level retrieval (chunking, reranking) hingga level generation (CRAG, Self-RAG, prompt engineering), dengan fokus pada Corrective RAG yang sudah diimplementasikan di vault-rag.
Hubungan ke Vault
vault-rag punya CRAG (Corrective RAG) di
scripts/corrective_rag.py. Catatan ini menjelaskan teori di belakangnya plus alternatif. Terkait dengan query-transformation-rag (CRAG bisa trigger query rewrite), advanced-chunking-strategies-deepdive (parent-child chunking mengurangi hallucination dengan konteks lebih lengkap), dan rag-evaluation-framework (evaluasi faithfulness).
Daftar Isi
- 1. Kenapa LLM Hallucinate di RAG?
- 2. Teknik Mitigasi
- 3. Corrective RAG β Implementasi vault-rag
- 4. Perbandingan
- Koneksi ke Vault
- References
1. Kenapa LLM Hallucinate di RAG?
| Penyebab | Penjelasan | Contoh |
|---|---|---|
| Context Ignorance | LLM gak baca/peduli konteks yang dikasih | Konteks bilang βSYN flood = layer 4β tapi jawaban bilang βlayer 7β |
| Retrieval Gap | Konteks gak cukup untuk jawab, LLM βnambahinβ | Pertanyaannya spesifik, tapi cuma dapet konteks umum |
| Chunk Fragmentation | Konteks kepotong, LLM nebak sisanya | Child chunk tanpa parent context |
| Parametric Bias | LLM lebih percaya internal knowledge daripada konteks | LLM udah βtahuβ jawaban dari training data, malah ngaco kalo konteks beda |
| Instruction Drift | Prompt gak cukup kuat untuk grounding | βJawab berdasarkan konteksβ vs βJawab dengan detailβ β kontradiksi |
1.1 Jenis Hallucination di RAG
Input: "Apa itu SYN flood?"
Konteks: [Artikel tentang TCP handshake dan SYN flood mitigation]
β
Faithful: "SYN flood adalah serangan DoS layer 4 yang mengirim banyak SYN..."
β Input Conflict: "SYN flood adalah serangan SQL injection..." (kontradiksi konteks)
β Context Conflict: "SYN flood adalah serangan yang terjadi di layer 7..." (salah interpretasi)
β Fabrication: "SYN flood ditemukan oleh John Smith pada 1998..." (gak ada di konteks)
2. Teknik Mitigasi
2.1 Retrieval-Level
| Teknik | Cara | Efek |
|---|---|---|
| Parent-Child Chunking | Child untuk search, parent untuk context | β Konteks lebih lengkap |
| Reranking | Filter chunk yang relevan sebelum dikirim ke LLM | β Noise berkurang |
| Hybrid Search | Dense + BM25 β lebih banyak sinyal | β Coverage meningkat |
| Query Transformation | Multi-Query, HyDE β improve retrieval | β Context lebih relevan |
2.2 Generation-Level
| Teknik | Cara | Efek |
|---|---|---|
| Prompt Grounding | βHanya jawab dari konteks. Jika gak ada, bilang tidak tahu.β | β Sederhana, cukup efektif |
| CRAG | Self-evaluasi relevansi β rewrite kalo gagal | β Adaptive |
| Self-RAG | Generate + evaluasi sendiri β βapakah jawaban didukung konteks?β | β Lebih akurat |
| Chain-of-Verification | Generate dulu β verifikasi tiap klaim β revisi | β Paling akurat, tapi 3x latency |
3. Corrective RAG β Implementasi vault-rag
3.1 Alur CRAG
[Query] β [Retrieve] β [Evaluate Relevance] β [Confidence Score]
β
βββββββββββββββββββββββββββββββββΌββββββββββββββββ
βΌ βΌ βΌ
β
Correct β Incorrect β οΈ Ambiguous
(skor > 0.7) (skor < 0.3) (0.3-0.7)
β β β
βΌ βΌ βΌ
Generate answer [Rewrite Query] [Hybrid: generate
β retrieve ulang + search web]
[Return result] β
βΌ
Generate answer
[Return result]
3.2 Implementasi vault-rag
# scripts/corrective_rag.py (simplified)
def corrective_rag(query, llm, retriever):
# 1. Retrieve
docs = retriever.search(query)
# 2. Evaluate relevance
score = llm.evaluate(f"Is this context relevant to: {query}?\nContext: {docs}")
if score > 0.7:
# Langsung generate
return llm.generate(f"Answer from context:\nContext: {docs}\nQuery: {query}")
elif score < 0.3:
# Rewrite query & retrieve ulang
rewritten = llm.generate(f"Rewrite this query for better search: {query}")
docs = retriever.search(rewritten)
return llm.generate(f"Answer from context:\nContext: {docs}\nQuery: {query}")
else:
# Partial relevance β generate with caution
answer = llm.generate(f"Answer from context. If unsure, say so.\nContext: {docs}\nQuery: {query}")
return f"{answer}\n\nβ οΈ Disclaimer: Partially relevant context."4. Perbandingan
| Teknik | Kompleksitas | Latency | Akurasi | vault-rag |
|---|---|---|---|---|
| Prompt grounding | π’ Rendah | π’ +0ms | π‘ 70% | β Prompt template |
| Parent-Child | π‘ Sedang | π’ +0ms | π’ 85% | β Implemented |
| Reranking | π‘ Sedang | π‘ +200ms | π’ 85% | β Ada (opsional) |
| CRAG | π΄ Tinggi | π΄ +500ms | π’ 90% | β
scripts/corrective_rag.py |
| Self-RAG | π΄ Tinggi | π΄ +1s | π’ 93% | β Belum |
| Chain-of-Verification | π΄ Sangat Tinggi | π΄ +3s | π’ 95% | β Belum |
Koneksi ke Vault
- query-transformation-rag β CRAG rewrite query saat retrieval gagal
- advanced-chunking-strategies-deepdive β Parent-child chunking = mitigasi hallucination via konteks lengkap
- rag-evaluation-framework β Evaluasi faithfulness score
- corrective_rag.py β Implementasi CRAG loop
- query.py β Prompt grounding: βIf context has NOTHING relevant: say No relevant information foundβ
References
- CRAG Paper. S. Yan et al. (2024). https://arxiv.org/abs/2401.15884
- Self-RAG. A. Asai et al. (2023). https://arxiv.org/abs/2310.11511
- Chain-of-Verification. S. Dhuliawala et al. (2023). https://arxiv.org/abs/2309.11495
- RAGAS Hallucination. https://docs.ragas.io/en/latest/concepts/metrics/faithfulness.html
Bottom Line
Hallucination di RAG disebabkan oleh 4 hal: retrieval gap, chunk fragmentation, context ignorance, parametric bias. vault-rag udah mitigasi 2 dari 4: parent-child chunking (konteks lengkap) dan CRAG (self-evaluate + rewrite). Prompt grounding yang kuat (βJika konteks gak relevan, bilang tidak tahuβ) adalah safety net termurah dengan ROI tertinggi. Next step: implementasi Self-RAG untuk akurasi lebih tinggi.