Belajar AI #33: Embedding & Vector DB Lebih Dalam — Chunking, Hybrid Search, dan Cosine Similarity

Di episode #31 kita sudah membandingkan prompting, RAG, dan fine-tuning, dan sampai pada kesimpulan: kalau datanya banyak dan sering berubah, RAG jawabannya. Tapi “RAG” itu sendiri berdiri di atas tiga tiang: embedding, vector database, dan strategi pencarian. Hari ini saya coba membongkar ketiganya lebih dalam — karena ternyata kualitas RAG di lapangan lebih sering ditentukan oleh hal-hal “membosankan” ini, bukan oleh pemilihan model LLM-nya.

Embedding: teks yang jadi koordinat

Inti embedding sebenarnya sederhana: sebuah teks dipetakan menjadi deretan angka (vektor), dan teks yang maknanya mirip mendapat koordinat yang saling berdekatan. Kata “kucing” dan “kitten” mungkin tidak pernah bertemu di kosakata yang sama, tapi di ruang vektor mereka tetangga. Ini yang membedakan pencarian semantik dengan pencarian kata kunci biasa.

Untuk mengukur kedekatan dua vektor, ukuran paling umum adalah cosine similarity — mengukur sudut antara dua vektor tanpa peduli panjangnya. Kalau dua vektor sudah dinormalisasi (panjangnya 1), cosine similarity dan dot product memberi hasil yang sama persis. Euclidean distance (L2) juga bisa dipakai, tapi untuk teks yang dinormalisasi ketiganya sebenarnya memberi peringkat yang sama — yang penting konsisten, jangan campur metric di indeks yang sama.

import numpy as np

def cosine_similarity(a, b):
    return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))

# dua vektor hasil model embedding (disederhanakan)
dokumen = np.array([0.9, 0.1, 0.0])
pertanyaan = np.array([0.8, 0.2, 0.1])

print(cosine_similarity(dokumen, pertanyaan))  # mendekati 1 = mirip

Chunking: seni memotong dokumen

Model embedding punya batas konteks. Dokumen 50 halaman tidak bisa dikirim utuh ke satu vektor — maknanya akan “encer”. Solusinya dipotong jadi potongan kecil (chunk), tiap chunk di-embedding sendiri-sendiri, lalu dicocokkan dengan pertanyaan pengguna di level chunk.

Di sinilah keputusan paling underrated dalam RAG: cara memotong. Beberapa strategi yang umum:

  • Fixed-size — potong per N token dengan overlap 10-20%. Sederhana, cepat, tapi bisa memotong kalimat atau paragraf di tengah jalan.
  • Recursive — coba potong di separator alami (paragraf, kalimat, baris) sebelum jatuh ke potongan per karakter. Ini default banyak framework dan secara konsisten jadi baseline yang sulit dikalahkan.
  • Semantic — hitung kesinambungan makna antar kalimat (misalnya dengan embedding per kalimat), potong di titik di mana topik bergeser. Terdengar pintar, tapi mahal dan tidak selalu menang.

Menariknya, studi “Is Semantic Chunking Worth the Computational Cost?” (Findings of NAACL 2025) justru menemukan bukti sistematis yang tipis bahwa semantic chunking memberi keunggulan nyata dibanding fixed-size setelah memperhitungkan biaya komputasinya. Sementara analisis multi-dataset oleh Bhat dkk. (2025) menyimpulkan tidak ada satu ukuran chunk terbaik untuk semua kasus. Bahkan beberapa eksperimen head-to-head menemukan recursive fixed-size bisa mengalahkan semantic chunking pada dokumen panjang. Bagi saya ini pelajaran penting: mulai dari recursive + overlap dulu, baru bereksperimen dengan yang lebih canggih kalau metrik eval bilang perlu (eval-nya sudah kita bahas di episode #30).

BM25, dense, dan hybrid search

Vector search punya kelemahan yang sering dilupakan: ia lemah pada exact match. Kalau pengguna mencari kode error “E-2049” atau nomor faktur, embedding bisa saja menganggapnya mirip dengan kode lain yang tidak ada hubungannya. Di sisi lain, BM25 (algoritma di balik Elasticsearch klasik) justru kuat di exact match tapi buta terhadap sinonim dan parafrase.

AspekBM25 (sparse)Dense vector
Cocok untukKata kunci tepat, kode, istilah teknisMakna, sinonim, parafrase
Lemah padaSinonim dan pertanyaan berbeda kataExact match, angka, ID
Butuh GPU/biayaTidakYa (model embedding + index)

Solusi modernnya: hybrid search — jalankan keduanya lalu gabungkan hasilnya dengan Reciprocal Rank Fusion (RRF), sederhananya: posisi tiap dokumen di dua daftar hasil dijumlahkan dengan bobot terbalik, dokumen yang muncul di dua daftar naik ke atas. Praktik ini jadi standar de facto dan didokumentasikan resmi oleh Microsoft di docs Cosmos DB hybrid search-nya. Kalau biaya masih mengizinkan, tambahkan lagi satu lapis reranker cross-encoder di atas hybrid — ini yang memberi lonjakan kualitas paling terasa menurut pengalaman banyak praktisi RAG.

Kapan BM25 saja sudah cukup?

Pertanyaan ini perlu jujur dijawab, karena jawabannya menghemat banyak waktu: kalau korpus Anda kecil, kata kuncinya sudah bisa diprediksi (FAQ, dokumentasi teknis dengan istilah tetap), dan pertanyaan pengguna cenderung literal — BM25 saja sering sudah memadai, tanpa perlu embed satu token pun. RAG penuh baru terasa manfaatnya ketika korpus besar, bahasa pertanyaan bervariasi, atau kontennya multi-bahasa. Mulai dari yang paling sederhana yang menyelesaikan masalah; infrastruktur vector DB itu tambahan kompleksitas yang harus dibayar maintainencenya.

Vector DB: sekilas peta

Untuk penyimpanan vektor, pilihannya sudah banyak: Chroma dan pgvector (PostgreSQL extension) untuk yang butuh sederhana, Qdrant dan Weaviate untuk dedicated vector DB, Milvus untuk skala besar. Rekomendasi pribadi saya: kalau sudah punya PostgreSQL, coba pgvector dulu sampai benar-benar butuh fitur khusus — satu database lebih mudah dirawat daripada menambah satu service lagi di infrastruktur.

Rangkuman yang saya catat untuk diri sendiri: embedding menentukan makna, chunking menentukan apa yang bisa ditemukan, pencarian (BM25/dense/hybrid) menentukan bagaimana menemukannya. Sisanya urusan eval — dan itu sudah urusan episode #30.

Sumber

Tinggalkan Balasan

Alamat email Anda tidak akan dipublikasikan. Ruas yang wajib ditandai *

Situs ini menggunakan Akismet untuk mengurangi spam. Pelajari bagaimana data komentar Anda diproses