RAG: Strategi Chunking & Kenapa Retrieval Sering Gagal
Kategori: AI Engineering · Level: Intermediate–Advanced · Tanggal: 16 Okt 2026
🎯 Tujuan Belajar
Setelah sesi ini: - Paham kenapa chunking adalah root cause nomor satu kegagalan RAG — bukan vector DB, bukan embedding model. - Bisa memilih strategi chunking berdasarkan tipe dokumen, pola query, dan budget. - Bisa mendiagnosis apakah masalah ada di chunking, retrieval, atau generation. - Tahu trade-off konkret tiap pendekatan dengan angka benchmark.
1. Kenapa Retrieval Gagal — Diagnosis Bukan Tebak-tebakan
RAG gagal di 3 titik berbeda. Wajib dibedakan sebelum "fix":
| Gejala | Root cause | Bukan fix-nya |
|---|---|---|
| Chunk relevan tidak muncul di top-k | Embedding/query mismatch, chunk keburu kepotong | Ganti vector DB |
| Chunk muncul tapi jawaban salah | Chunk terlalu besar / multi-topik → embedding "averaged", noise | Naikin top-k |
| Chunk muncul, benar, tapi LLM tetap halusinasi | Chunk kurang konteks, "lost in the middle" | Ganti LLM |
Tesis utama Weaviate [1]: kalau RAG perform-nya buruk, sering kali bukan retriever-nya salah — chunk-nya yang buruk. Retriever sempurna tetap gagal kalau cari di data yang jelek.
Dua tuntutan yang saling tarik-menarik: - Chunk kecil & fokus → embedding presisi, mudah ditemukan vector search. - Chunk besar & kontekstual → LLM punya cukup konteks buat menjawab.
Chunk terlalu besar = "mendeskripsikan buku dengan merata-rata semua babnya" → embedding noise, tidak mewakili topik apa pun secara jelas. Chunk terlalu kecil = "satu kalimat dari tengah paper" → LLM tidak paham konteksnya.
Aturan praktis [1]: Kalau sebuah chunk bisa dipahami oleh manusia saat dibaca sendirian, LLM juga akan paham. Ini test cepat yang bisa dipakai tanpa benchmark.
2. Arsitektur & Alur Teknis Pipeline RAG
DOCUMENT INGESTION (offline)
┌─────────────┐ ┌──────────┐ ┌──────────┐ ┌───────────┐ ┌─────────┐
│ Parse/ │──▶│ CHUNKING │──▶│ Embed │──▶│ Index │──▶│ Vector │
│ Extract │ │ (split) │ │ (model) │ │ (upsert) │ │ DB │
│ (PDF→text) │ └──────────┘ └──────────┘ └───────────┘ └─────────┘
└─────────────┘ ▲
⚡ titik kegagalan #1
(paling sering diabaikan)
QUERY TIME (online)
┌────────┐ ┌──────────────┐ ┌────────────┐ ┌──────────┐ ┌────────┐
│ User │──▶│ Query │──▶│ Retrieve │──▶│ Rerank │──▶│ LLM │
│ Query │ │ Transform │ │ top-k │ │ (cross- │ │ + │
│ │ │ (HyDE, │ │ similarity │ │ encoder) │ │ chunks │
│ │ │ rewrite) │ │ │ │ │ │ │
└────────┘ └──────────────┘ └────────────┘ └──────────┘ └────────┘
▲
titik kegagalan #2
(kalau chunk jelek,
di sini kelihatan)
Poin kritis: Chunking terjadi sekali di ingestion, tapi efeknya terasa setiap query selama data itu ada. Biaya salah chunk = permanen sampai re-index. Biaya salah chunk kecil di depan; biaya salah chunk di produksi = harus re-embed seluruh korpus.
3. Tujuh Strategi Chunking — Detail
3.1 Recursive Character Splitting (default aman)
Coba split di boundary natural, cek separator berurutan sampai ketemu:
# Hierarki separator: paragraf → baris → kalimat → kata → char
separators = ["\n\n", "\n", ". ", " ", ""]
def recursive_split(text, max_tokens=512, overlap=0.15):
# coba "\n\n" dulu; kalau chunk masih > max, recurse pakai separator berikut
# overlap ~15% → jaga "train of thought" lintas boundary
...
Kapan pakai: default untuk hampir semua teks. Config [2]: 400–512 token, overlap 10–20%.
3.2 Semantic Chunking
Embed tiap kalimat, hitung similarity antar-kalimat berturutan, split di titik di mana similarity turun tajam (topic shift).
def semantic_split(doc, threshold_pct=95):
sentences = split_sentences(doc)
embs = embed(sentences) # ⚠️ biaya: N API calls
sims = [cosine(embs[i], embs[i+1]) for i in range(len(embs)-1)]
cut = percentile(sims, 100 - threshold_pct) # split di bawah persentil ini
return group_by_boundaries(sentences, cut)
- Recall +hingga 9% vs metode sederhana [2].
- Biaya: embed SETIAP kalimat saat indexing (bukan cuma chunk akhir).
3.3 Page-Level Chunking
Satu chunk = satu halaman. Menang NVIDIA 2024 benchmark: accuracy 0.648, variance terendah [2]. Tapi hanya untuk dokumen terpaginate (PDF laporan, slide deck). Untuk teks berjalan (markdown panjang) tidak masuk akal.
3.4 LLM-Based Chunking
Lempar dokumen ke LLM, minta dia analisis struktur dan tentukan boundary.
- Kualitas tertinggi, biaya & latency tertinggi.
- Cocok untuk korpus kecil bernilai tinggi (kontrak hukum, dokumentasi medis).
- Tipikal mahal: 1 call LLM per dokumen saat ingestion.
3.5 Size-Based / Token-Based
Split buta di N karakter/token. Cepat, murah, tapi abaikan boundary makna — motong tengah kalimat. Hampir selalu kalah dari recursive.
3.6 Sentence-Based
Satu chunk = beberapa kalimat lengkap. Baik untuk QA factoid; buruk kalau jawaban butuh konteks lintas paragraf.
3.7 Late Chunking ⭐
Pendekatan terbalik [1][2]: jangan split dulu. Embed seluruh dokumen dengan long-context embedding model, baru turunkan chunk embedding dari token embeddings di dalamnya. Tiap chunk jadi sadar konteks dokumen penuh.
# Conventional: split → embed each chunk (context hilang)
chunks = split(doc); vecs = [embed(c) for c in chunks]
# Late chunking: embed full doc → pool per chunk
tok_embs = long_ctx_model.encode(doc) # per-token embeddings
vecs = [mean_pool(tok_embs[c.start:c.end]) for c in chunks]
- Complexity: High. Butuh embedding model dengan long context.
- Best for: case study, manual komprehensif, laporan analisis panjang di mana chunk butuh kesadaran konteks dokumen.
4. Trade-off & Pendekatan Alternatif
| Strategi | Cara Kerja | Complexity | Biaya Indexing | Best For |
|---|---|---|---|---|
| Recursive | Split di boundary hierarkis | Low | Sangat rendah | Default semua teks |
| Semantic | Split di topic shift | Med-High | Tinggi (embed tiap kalimat) | Paper, textbook, naratif |
| Page-level | 1 chunk = 1 halaman | Low | Rendah | PDF terpaginate |
| LLM-based | LLM tentukan boundary | High | Sangat tinggi | Korpus kecil high-value |
| Size-based | Split di N char | Low | Sangat rendah | Baseline/prototipe |
| Sentence | Beberapa kalimat | Low | Rendah | QA factoid |
| Late | Embed dok penuh, pool | High | Tinggi | Dokumen butuh context-aware chunk |
Tidak ada pemenang universal [2]. 3 faktor penentu: 1. Embedding model — arsitektur berbeda → strategi optimal berbeda. 2. Tipe dokumen — PDF bertabel ≠ blog post ≠ source code. 3. Pola query — lookup factoid ≠ pertanyaan analitis.
5. Use Case Produksi
- Enterprise doc search / internal knowledge base: recursive 512 token + overlap 15% + reranker. Titik awal yang paling murah menuju akurasi layak.
- Legal / medical contract QA: LLM-based atau semantic chunking — dokumen bernilai tinggi, korpus kecil, salah chunk = risiko besar.
- Technical manual multi-halaman: late chunking — chunk harus tahu konteks prosedur keseluruhan.
- Chatbot FAQ: sentence-based atau size-based kecil — query factoid, jawaban lokal.
- Agent long-term memory [1]: chunk yang well-formed menentukan apa yang bisa di-recall agent nanti. Chunking di sini = desain memori.
RAG adopsi enterprise [2]: 51% pada 2024 (naik dari 31% pada 2023, per Menlo Ventures). Pasar RAG diproyeksi US$9.86 miliar pada 2030 (MarketsandMarkets).
6. Failure Mode Umum
- Chunk multi-topik (terlalu besar) → embedding "averaged", noise → retrievability anjlok. Solusi: chunk lebih kecil, atau hierarchical chunking.
- Chunk terpotong di tengah → info setengah, LLM menebak. Solusi: reranker + semantic/recursive boundary.
- "Lost in the middle" → context panjang bikin model abaikan info di tengah. Solusi: kecilkan jumlah chunk yang di-pass, rerank, atau reorder (relevan di awal/akhir).
- Overlap hilang → "train of thought" putus lintas boundary. Solusi: overlap 10–20%.
- Chunk tanpa header konteks → chunk isi tabel/potongan tak tahu dia bagian apa. Solusi: prepend parent header (mis.
H2 > H3path) ke tiap chunk. - Chunking dianggap afterthought → tim fokus vector DB & embedding, lupakan persiapan data. Ini penyebab tersembunyi paling sering [1].
7. Latihan Praktis Kecil
# Self-check chunking — jalankan pada korpus kalian, ukur retrieval
import numpy as np
def recursive_split(text, size=512, overlap=0.15): ...
def self_check(chunks, queries):
"""
chunks: list[str]
queries: list[(query, gold_chunk_idx)]
Ukur hit-rate@5, bukan cuma "kelihatan bagus".
"""
embs = embed(chunks)
hits = 0
for q, gold_idx in queries:
qe = embed([q])[0]
ranked = np.argsort(-(embs @ qe))[:5]
hits += gold_idx in ranked
return hits / len(queries)
# Bandingkan: size-based vs recursive vs semantic
# Assert: recursive harus ≥ size-based pada korpus dengan boundary jelas
Buat 20 query berlabel dari dokumen kalian. Ubah strategi chunking, lihat hit-rate@5. Ini lebih berguna daripada memilih embedding model baru.
8. Poin Kunci
- Chunking = interface antara dokumen manusia dan retriever mesin. Desain di sini menentukan seluruh pipeline.
- Mulai dari recursive 400–512 token, overlap 10–20%. Ukur. Baru naik ke semantic/late kalau ada bukti kurang.
- Chunk jelek permanen sampai re-index → invest di depan.
- Test cepat tanpa benchmark: kalau chunk tidak masuk akal dibaca sendirian, LLM juga bingung.
- Page-level menang di benchmark NVIDIA 2024 (0.648) tapi hanya untuk dokumen terpaginate.
- Semantic chunking = +9% recall dengan biaya embed tiap kalimat.
- Late chunking = jawaban untuk "chunk butuh konteks dokumen penuh".
9. Eksplorasi Lanjut
- Hierarchical / parent-child chunking: retrieve chunk kecil (presisi) tapi pass parent besar (konteks) ke LLM — gabungan dua strategi terbaik.
- Contextual retrieval (Anthropic): prepend ringkasan konteks Dokumen-ke-Chunk ke tiap chunk sebelum embed.
- Query transformation: HyDE, multi-query, query rewrite — sering memperbaiki retrieval lebih banyak daripada tuning chunk.
- Reranker (cross-encoder): retrieve 50 → rerank → pass 5 terbaik. Mitigasi chunk besar yang noisy.
- Benchmark sendiri wajib. Angka NVIDIA/Chroma tidak otomatis berlaku ke domain kalian — embedding model dan tipe dokumen mengubah hasil.
🔗 Sumber
- Weaviate. "Chunking Strategies to Improve Your RAG Performance" — weaviate.io/blog/chunking-strategies-for-rag (diakses 16 Okt 2026). Semantic, late chunking, table strategi.
- Firecrawl (Bex Tuychiev). "Best Chunking Strategies for RAG (and LLMs) in 2026" — firecrawl.dev/blog/best-chunking-strategies-rag, updated 24 Feb 2026. Angka NVIDIA 2024 benchmark, recall +9%, config 400–512 token.
- Pinecone. "Chunking Strategies for LLM Applications" — pinecone.io/learn/chunking-strategies.
- Menlo Ventures. "2024: The State of Generative AI in the Enterprise" — via [2].
- MarketsandMarkets. "Retrieval-Augmented Generation (RAG)" press release — via [2].
⚠️ Catatan verifikasi: angka benchmark (0.648 accuracy page-level, +9% recall semantic) dikutip dari [2] merujuk benchmark NVIDIA 2024 dan Chroma — tidak diverifikasi langsung ke sumber primer NVIDIA/Chroma dalam sesi ini. Angka adopsi enterprise & proyeksi pasar dari Menlo Ventures & MarketsandMarkets via [2], tidak dicek ke laporan asli. Perlakukan sebagai indikatif, bukan presisi absolut. Strategi & mekanisme (recursive, semantic, late chunking, "lost in the middle") adalah DIKETAHUI dari dokumentasi teknikal; angka spesifik = DIINFERENSI dari sumber sekunder.