🧩 Advanced Chunking Strategies β€” The Architecture of Precision Retrieval

Dari Fixed-Size ke Parent-Child: Arsitektur Representasi Data untuk RAG Production-Grade

Chunking adalah tindakan pertama dan paling fundamental dalam pipeline Retrieval-Augmented Generation (RAG). Ini adalah keputusan arsitektural tentang bagaimana Anda mendefinisikan unit atomik makna yang akan di-retrieve. Pilihan yang salah menghasilkan jawaban yang terfragmentasi, kehilangan konteks, atau halusinasi. Pilihan yang tepat menghasilkan retrieval yang presisi, jawaban yang kaya konteks, dan efisiensi komputasi. Dokumen ini membedah spektrum strategi chunking, dari yang naif hingga production-grade, dengan fokus pada arsitektur Parent-Child Chunking yang menyelesaikan trade-off fundamental antara presisi pencarian dan kelengkapan konteks.

Hubungan ke Vault

Nota ini adalah fondasi teoretis dari implementasi RAG di project vault-rag. Strategi chunking yang dijelaskan di sini diimplementasikan secara konkret di index_vault.py dengan arsitektur Parent-Child + Structure-Aware untuk vault markdown. Terkait dengan ai-engineering-stack-roadmap (Fase 2: Data Pipeline & Vector Infrastructure), cognitive-architecture-engineering (memori hierarkis), dan math-and-algorithms (cosine similarity untuk semantic chunking).

Implementasi di vault-rag

Di scripts/index_vault.py, chunking sudah menggunakan Structure-Aware Parent-Child:

  • Parent: H1/H2 section boundaries
  • Child: H3/paragraph/sentence dengan CHILD_MAX_CHARS=600
  • Section path: heading hierarchy ([β€œFoundation”, β€œTechnical Deep-Dive”])
  • DB: parents table + chunks table dengan FK parent_id

Daftar Isi


1. First Principles: Atom Makna dalam Ruang Vektor

1.1 The Semantic Atom Problem

Mengapa chunking begitu sulit? Karena makna tidak memiliki ukuran yang tetap. Sebuah kalimat tunggal bisa menjadi atom makna yang sempurna untuk sebuah fakta (β€œIbu kota Indonesia adalah Jakarta.”), tetapi tidak cukup untuk sebuah argumen atau penjelasan. Sebuah paragraf bisa menangkap sebuah konsep, tetapi bisa juga berisi beberapa ide yang berbeda.

Dalam RAG, kita menghadapi dua kebutuhan yang saling bertentangan:

  • Presisi Pencarian (Search Precision): Chunk yang kecil dan fokus secara semantik akan menghasilkan kemiripan embedding yang tinggi dengan kueri. Ini meminimalkan noise dan memaksimalkan relevansi.
  • Kelengkapan Konteks (Context Completeness): Chunk yang terlalu kecil kehilangan konteks sekitarnya, membuat LLM tidak dapat memahami nuansa, anteseden, atau implikasi dari teks yang di-retrieve.

Parent-Child Chunking adalah solusi arsitektural untuk kontradiksi ini.

1.2 Trade-off Fundamental

Presisi                                     Konteks
◄──────────────────────────────────────────────►

  Fixed-Size    Sentence     Semantic   Struct-Aware   Parent-Child
  (rendah)      (rendah)     (sedang)   (tinggi)       (sangat tinggi)
  presisi       konteks      balanced   presisi        presisi +
  tinggi                                      konteks tertinggi
PendekatanPresisiKonteksTrade-off
Fixed-Size kecil (100 token)🟒 TinggiπŸ”΄ RendahDapet fakta tepat tapi gak paham konteks
Fixed-Size besar (1000 token)πŸ”΄ Rendah🟒 TinggiBanyak noise, relevansi rendah
Parent-Child🟒 Sangat Tinggi🟒 Sangat TinggiKompleksitas implementasi naik

2. Spektrum Strategi Chunking

2.1 Fixed-Size Chunking β€” The Naive Baseline

Filosofi: β€œSaya tidak tahu apa-apa tentang data Anda, jadi saya potong rata.”

Input: [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
        [ABCDE][FGHIJ][KLMNO][PQRST][UVWXY][Z]
AspekDetail
MekanismeTeks dipotong setiap N token/karakter, seringkali dengan overlap (N/10 token)
KeunggulanPaling sederhana. Deterministis, prediktabel, mudah di-debug. Tidak perlu library NLP
KelemahanBoundary Problem. Kalimat terpotong, paragraf terputus, kode terbelah. Informasi terfragmentasi acak. Overlap sedikit membantu tapi gak solve masalah koherensi semantik
Kapan dipakaiHanya prototype cepat, atau data homogen pendek (tweet, title)
# Paling mentah β€” potong per karakter
def fixed_size_chunk(text, chunk_size=500, overlap=50):
    chunks = []
    start = 0
    while start < len(text):
        end = min(start + chunk_size, len(text))
        chunks.append(text[start:end])
        start += chunk_size - overlap
    return chunks
 
# Lebih cerdas β€” RecursiveCharacterTextSplitter (LangChain)
from langchain.text_splitter import RecursiveCharacterTextSplitter
splitter = RecursiveCharacterTextSplitter(
    chunk_size=500,
    chunk_overlap=50,
    separators=["\n\n", "\n", ". ", " ", ""]
    # Coba split di double-newline dulu, lalu newline, lalu titik, lalu spasi,
    # baru kalau gak ada pilihan: potong karakter
)

2.2 Sentence-Based Chunking β€” The Linguistic Baseline

Filosofi: β€œKalimat adalah unit linguistik alami. Hormati itu.”

AspekDetail
MekanismeSentence tokenizer (NLTK, spaCy) β†’ pisah kalimat β†’ grup 5-10 kalimat per chunk
KeunggulanGak ada kalimat terpotong. Setiap chunk punya integritas gramatikal
KelemahanContext Collapse. Kata ganti (β€œini”, β€œmereka”), singkatan, referensi implisit bikin kalimat tunggal ambigu. β€œIni adalah contoh yang baik” gak berguna tanpa kalimat sebelumnya
Kapan dipakaiFAQ, chat logs, data QA pendek yang mandiri
import spacy
nlp = spacy.load("en_core_web_sm")
 
def sentence_based_chunk(text, max_sentences=5):
    doc = nlp(text)
    sentences = [sent.text for sent in doc.sents]
    chunks = []
    for i in range(0, len(sentences), max_sentences):
        chunks.append(" ".join(sentences[i:i+max_sentences]))
    return chunks

2.3 Semantic Chunking β€” The Embedding-Based Approach

Filosofi: β€œMakna adalah tentang koherensi, bukan panjang. Ikuti alur topik.”

Kalimat:  [A] [B] [C] [D] [E] [F] [G] [H]
Similaritas: 0.95 0.93 0.89 0.45 0.91 0.94 0.88
             └───── Chunk 1 β”€β”€β”€β”€β”˜ └── Chunk 2 β”€β”€β”˜
                        ^ threshold 0.7 β€” putus di sini
AspekDetail
MekanismeEmbed tiap kalimat β†’ sliding window dengan threshold similaritas β†’ grup kalimat mirip. Kalo similaritas turun drastis = ganti topik = chunk baru
KeunggulanChunk koheren secara topik. Adaptif: teks mudah β†’ chunk panjang, teks kompleks β†’ chunk pendek
KelemahanHyperparameter sensitivity. Threshold tergantung domain. Terlalu tinggi β†’ over-split (ratusan chunk kecil). Terlalu rendah β†’ under-split (chunk raksasa campur aduk). Gak ada one-size-fits-all
Kapan dipakaiDokumen tanpa struktur jelas (transkrip, esai, artikel). Kalo gak bisa andelin struktur Markdown
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
 
def semantic_chunking(sentences, embeddings, threshold=0.7):
    """
    sentences: list of strings
    embeddings: list of embedding vectors (same order)
    threshold: kalo similaritas < threshold, mulai chunk baru
    """
    chunks = []
    current_chunk = [sentences[0]]
 
    for i in range(1, len(sentences)):
        sim = cosine_similarity([embeddings[i-1]], [embeddings[i]])[0][0]
        if sim < threshold:
            chunks.append(" ".join(current_chunk))
            current_chunk = [sentences[i]]
        else:
            current_chunk.append(sentences[i])
 
    if current_chunk:
        chunks.append(" ".join(current_chunk))
    return chunks

2.4 Structure-Aware Chunking β€” The Production Baseline

Filosofi: β€œSaya tahu strukturnya (Markdown, HTML, JSON). Gunakan itu sebagai panduan.”

AspekDetail
MekanismeParser Markdown β†’ ekstrak judul, sub-judul, paragraf, tabel, kode β†’ chunk dengan hormati batas elemen
KeunggulanUntuk vault markdown, ini paling presisi. Heading = ringkasan topik alami. Metadata (judul, heading) bisa disimpan per chunk
KelemahanFragility. Bergantung kualitas markup. PDF OCR, plain text, HTML kacau gak punya struktur
Kapan dipakaiDefault untuk vault ini. Setiap .md adalah kanvas sempurna
from langchain.text_splitter import MarkdownHeaderTextSplitter
 
headers_to_split_on = [
    ("##", "H2"),
    ("###", "H3"),
    ("####", "H4"),
]
splitter = MarkdownHeaderTextSplitter(headers_to_split_on=headers_to_split_on)
chunks = splitter.split_text(markdown_text)
# Setiap chunk punya metadata:
# {"H2": "2. Spektrum Strategi Chunking", "H3": "2.1 Fixed-Size"}

3. Parent-Child Chunking β€” Production-Grade Architecture

Filosofi: β€œSaya butuh presisi pencarian dari chunk kecil, dan kelengkapan konteks dari chunk besar. Saya akan menyimpan keduanya.”

Parent-Child bukan teknik tunggal β€” ini arsitektur data dual-layer.

3.1 Arsitektur Dual-Layer

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    LAYER PEMANFAATAN                              β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                   β”‚
β”‚  PARENT LAYER (Konteks β€” disimpan, TIDAK di-embed)              β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”       β”‚
β”‚  β”‚ [## Foundation] [Teks lengkap section Foundation      β”‚       β”‚
β”‚  β”‚  dari awal "TCP three-way..." sampai "sequence n."]  β”‚       β”‚
β”‚  β”‚  id: "p_abc123"                                      β”‚       β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜       β”‚
β”‚                        β–² β–² β–² (dilihat via FK)                     β”‚
β”‚                        β”‚ β”‚ β”‚                                     β”‚
β”‚  CHILD LAYER (Presisi β€” di-embed + di-search)                     β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”           β”‚
β”‚  β”‚ Child 1  β”‚ β”‚ Child 2  β”‚ β”‚ Child 3  β”‚ β”‚ Child 4  β”‚           β”‚
β”‚  β”‚ 140 char β”‚ β”‚ 150 char β”‚ β”‚ 70 char  β”‚ β”‚ 130 char β”‚           β”‚
β”‚  β”‚ parent:  β”‚ β”‚ parent:  β”‚ β”‚ parent:  β”‚ β”‚ parent:  β”‚           β”‚
β”‚  β”‚ p_abc123 β”‚ β”‚ p_abc123 β”‚ β”‚ p_abc123 β”‚ β”‚ p_abc123 β”‚           β”‚
β”‚  β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜           β”‚
β”‚       β”‚             β”‚             β”‚             β”‚               β”‚
β”‚       β–Ό             β–Ό             β–Ό             β–Ό               β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚                VECTOR STORE (Embedded)                      β”‚ β”‚
β”‚  β”‚  Query β†’ cosine similarity β†’ Top-3 children                 β”‚ β”‚
β”‚  β”‚         β†’ resolve parent β†’ context utuh                    β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

3.2 Alur Kerja Arsitektural

Ingestion Pipeline

[Dokumen Markdown]
       β”‚
       β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   Structure      β”‚
β”‚   -Aware Parser  β”‚  Ekstrak struktur: H2, H3, Paragraf, List
β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚
         β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Parent-Child Splitter      β”‚
β”‚  β€’ Parent = H1/H2 section   β”‚
β”‚  β€’ Child = pecahan parent   β”‚
β”‚    (H3 β†’ paragraph β†’ sntnc) β”‚
β”‚  β€’ Each child stores        β”‚
β”‚    parent_id as FK          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
               β”‚
               β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  DB: parents table + chunks table      β”‚
β”‚  β€’ chunks: text, embedding, parent_id  β”‚
β”‚  β€’ parents: id, text (full section)    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Retrieval Pipeline

[Query: "gimana SYN flood bekerja?"]
       β”‚
       β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  1. Vector Search     β”‚
β”‚  β†’ Top-5 child chunks  β”‚
β”‚  β†’ Dapet chunk ttg    β”‚
β”‚    "SYN flood attack" β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
           β”‚
           β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  2. Resolve Parent    β”‚
β”‚  β†’ child.parent_id    β”‚
β”‚  β†’ SELECT FROM parentsβ”‚
β”‚  β†’ Dapet FULL section β”‚
β”‚    "Foundation"       β”‚
β”‚    (mencakup SYN      β”‚
β”‚    flood, SYN cookies,β”‚
β”‚    sequence pred.)    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
           β”‚
           β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  3. LLM Generation    β”‚
β”‚  Konteks = parent textβ”‚
β”‚  (child + context)    β”‚
β”‚  Jawaban LEBIH LENGKAPβ”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

3.3 Implementasi di vault-rag

Implementasi konkret ada di scripts/index_vault.py dan scripts/query.py:

Indexer β€” chunking:

# Parent: H1/H2 section (full text)
parent_boundaries = []
h1h2_positions = [i for i, m in enumerate(headings) if len(m.group(1)) <= 2]
 
for idx, heading_idx in enumerate(h1h2_positions):
    m = headings[heading_idx]
    start = m.start()
    # End at next H1/H2, or EOF
    if idx + 1 < len(h1h2_positions):
        end = headings[h1h2_positions[idx + 1]].start()
    else:
        end = len(text)
    parent_boundaries.append((start, end, m.group(2).strip()))
 
# Child: within each parent, split at H3 β†’ paragraph β†’ sentence
# _split_by_headings β†’ _split_by_paragraphs β†’ _split_by_sentences
# CHILD_MAX_CHARS = 600, CHILD_MIN_CHARS = 40

Query β€” parent context:

# 1. Search child chunks (dense cosine + BM25 FTS5)
# 2. For each hit, look up parent_id:
SELECT text FROM parents WHERE id = ?
 
# 3. Attach parent_text to each result
# 4. LLM prompt includes parent_text as full context

3.4 Kapan Parent-Child Wajib

SkenarioKenapa WajibContoh
Dokumen teknis panjangKonteks section dibutuhkan untuk interpretasiVault note 30KB
Pertanyaan multi-hop”Jelaskan hubungan X dan Y” butuh konteks luas”Apa hubungan SYN flood dan sequence prediction?”
Detil penting untuk akurasiLatar belakang diperlukan”Kenapa SYN cookies mengorbankan window scaling?”
Menghindari halusinasiChunk kecil bikin LLM nebak-nebak”Jelaskan cara kerja TCP state machine” β€” tanpa parent, LLM gak tau ini tentang detection

4. Matriks Perbandingan

StrategiPresisi PencarianKelengkapan KonteksKompleksitasKetahanan NoiseTerbaik Untuk
Fixed-SizeπŸ”΄ RendahπŸ”΄ Rendah🟒 Sangat RendahπŸ”΄ RendahPrototipe, data homogen
Sentence-Based🟑 SedangπŸ”΄ Rendah🟒 Rendah🟑 SedangFAQ, chat logs
Semantic🟒 Tinggi🟑 Sedang🟑 Tinggi (threshold tuning)🟒 TinggiDokumen tanpa struktur
Structure-Aware🟒 Tinggi🟒 Tinggi🟑 SedangπŸ”΄ Rendah (bergantung markup)Vault markdown
Parent-Child🟒 Sangat Tinggi🟒 Sangat TinggiπŸ”΄ Tinggi🟒 TinggiProduction-grade

Cost Analysis

StrategiEmbedding CostStorage CostRetrieval LatencyContext Quality
Fixed-Size (256 token)1x per chunk1x vectorRendahRendah
Fixed-Size (1024 token)1x per chunk1x vectorRendahSedang
Semantic1x per kalimat + per chunk1x vector per chunkSedang (ekstra embed)Tinggi
Structure-Aware1x per chunk1x vector per chunkRendahTinggi
Parent-Child1x per child (parent gak di-embed)1x vector per child (parent cuma text)Rendah (search child β†’ lookup parent)Sangat Tinggi

Cost Efficiency Parent-Child

Parent-Child tidak menggandakan embedding cost. Hanya child yang di-embed. Parent cuma disimpan sebagai text biasa. Jadi biaya embedding β‰ˆ Structure-Aware dengan chunk_size = CHILD_MAX_CHARS.


5. Rekomendasi untuk Vault Ini

Berdasarkan analisis struktur vault β€” semua file markdown dengan heading hierarchy (## Foundation β†’ ### Technical Deep-Dive β†’ #### Case Studies):

Cetak Biru

  1. Parser: H1/H2 boundaries β†’ Parent Chunks (full section context)
  2. Child Splitter: H3 β†’ paragraph β†’ sentence β†’ Child Chunks (~600 chars)
  3. Metadata: section_path (heading hierarchy), parent_id, filepath, chunk_index
  4. Retrieval: Vector search on children β†’ deduplicate parents β†’ send parent text as context

Status Implementasi

KomponenStatusLokasi
Structure-Aware Parserβœ… Donescripts/index_vault.py
Parent-Child Splitterβœ… Donescripts/index_vault.py:make_parents_and_children()
DB Schema (parents + chunks)βœ… Donescripts/index_vault.py:init_db()
Parent Context Augmentationβœ… Donescripts/query.py:augment_with_parent()
Re-index commandβœ… Done./vault-rag.sh index --reindex
FTS5 BM25 on childrenβœ… Donescripts/index_vault.py
Heading hierarchy metadataβœ… Donesection_path column
Semantic Chunking (embed-based)❌ Not implementedFallback ke Structure-Aware sudah cukup untuk vault
LangChain/Qdrant integration❌ Not implementedPakai sqlite-vec + API sendiri (lebih ringan)

Koneksi ke Vault


References

  1. LangChain. Text Splitters. https://python.langchain.com/docs/modules/data_connection/document_transformers/
  2. Qdrant. Parent-Child Document Retrieval. https://qdrant.tech/articles/parent-child/
  3. Pinecone. Chunking Strategies. https://www.pinecone.io/learn/chunking-strategies/
  4. Anthropic. Contextual Retrieval. https://www.anthropic.com/news/contextual-retrieval
  5. LlamaIndex. Node Parser. https://docs.llamaindex.ai/en/stable/module_guides/loading/node_parsers/
  6. UnstructuredIO. Chunking Strategies. https://docs.unstructured.io/open-source/core-functionality/chunking
  7. Cohere. Chunking for RAG. https://docs.cohere.com/docs/chunking-for-rag
  8. McInnes, L. et al. UMAP: Uniform Manifold Approximation and Projection. 2018. β€” Fondasi untuk visualisasi embedding chunk.
  9. Reimers, N. & Gurevych, I. Sentence-BERT: Sentence Embeddings using Siamese BERT-Networks. 2019. β€” Fondasi sentence embedding untuk semantic chunking.
  10. Karpathy, A. Tokenization in LLMs. https://github.com/karpathy/minbpe β€” Prinsip tokenisasi yang memengaruhi chunk_size.
  11. sqlite-vec. Vector Search in SQLite. https://github.com/asg017/sqlite-vec
  12. SQLite FTS5. Full-Text Search. https://www.sqlite.org/fts5.html

Bottom Line

Chunking bukan preprocessing β€” ini keputusan arsitektural. Fixed-size chunking adalah β€œmagic number” yang paling berbahaya di RAG karena memberikan ilusi presisi sambil merusak koherensi semantik. Parent-Child Chunking menyelesaikan trade-off fundamental: search di child (presisi tinggi), context dari parent (konteks lengkap). Untuk vault markdown, Structure-Aware (hormati heading) adalah langkah pertama yang wajib. Implementasi di vault-rag sudah menggunakan arsitektur ini β€” jalankan ./vault-rag.sh index --reindex untuk mengaktifkannya.