Blog

· rag · llm · pencarian

Membangun RAG

Retrieval-augmented generation (RAG) menggabungkan pencarian informasi dengan model bahasa. Saat seseorang bertanya, sistem mencari bagian dokumen yang relevan, memasukkannya ke konteks model, lalu meminta jawaban berdasarkan bagian tersebut. Gagasan dasarnya sederhana; kualitasnya ditentukan oleh keputusan di setiap langkah.

Tulisan ini membahas alur yang bisa dibangun dan diuji secara bertahap: siapkan dokumen, cari bukti, susun jawaban, lalu ukur kegagalannya. Istilah chunk di bawah berarti potongan dokumen yang disimpan untuk pencarian.

Kapan RAG berguna

RAG cocok ketika jawaban perlu merujuk ke informasi yang berubah atau tidak ada dalam pengetahuan umum model: dokumentasi internal, kebijakan, atau katalog produk. Dokumen dapat diperbarui dan diindeks ulang tanpa melatih model bahasa dari awal. Ini juga memberi kesempatan untuk menampilkan sumber yang dipakai dalam jawaban. Gagasan menggabungkan model dengan sumber eksternal dijelaskan dalam makalah RAG.

Namun, sumber yang ditampilkan belum tentu mendukung kalimat yang dihasilkan. Sistem tetap perlu memeriksa apakah kutipan mengarah ke dokumen yang benar dan apakah isi dokumen itu benar-benar mendukung klaimnya.

Kapan tidak perlu RAG

Jika tugasnya hanya mengubah gaya, nada, atau format tulisan, contoh dan instruksi sering lebih tepat daripada membuat indeks dokumen. Untuk data terstruktur yang harus persis, seperti saldo atau stok saat ini, kueri ke database atau API bisa lebih sesuai. RAG berguna ketika sistem perlu mencari bukti di antara banyak teks, bukan sebagai pengganti semua sumber data.

Memecah dokumen

Sebelum memilih ukuran chunk, lihat bentuk dokumennya. Judul, paragraf, daftar, tabel, dan blok kode memberi petunjuk tentang bagian yang sebaiknya tetap bersama. Jika sebuah tabel dipotong dari judul kolomnya, potongan itu sulit dipahami meskipun berhasil ditemukan.

Mulai dari struktur, lalu ukuran

Untuk Markdown, pecah dokumen berdasarkan heading dan paragraf. Jika satu bagian masih terlalu panjang, bagi lagi pada batas paragraf atau kalimat. Hitung panjang dengan tokenizer yang dipakai dalam pipeline, bukan dengan jumlah karakter. Pertahankan heading bersama isi yang dijelaskannya dan jangan memotong tabel atau blok kode sembarangan.

Ukuran tetap dengan sedikit tumpang tindih bisa menjadi pembanding awal, tetapi tidak ada angka chunk yang cocok untuk semua dokumen. Bandingkan beberapa strategi pada pertanyaan nyata: apakah bagian yang dibutuhkan ditemukan, dan apakah konteksnya cukup untuk menjawab?

Simpan asal setiap chunk

Simpan identitas dokumen, versi atau waktu pembaruan, urutan heading, serta posisi chunk. Contohnya, Panduan > Akun > Mengganti kata sandi memberi konteks yang tidak ada dalam paragraf pendek tentang “tautan reset”. Metadata ini juga diperlukan untuk membuat tautan sumber yang bisa dibuka dan untuk menghapus versi dokumen yang sudah tidak berlaku.

Jika dokumen memiliki batas akses, bawa informasi izin ke indeks dan terapkan filter sebelum hasil pencarian diberikan ke model. Sumber yang tidak boleh dilihat pembaca tidak boleh masuk ke konteks jawaban.

Memilih embedding

Embedding mengubah teks menjadi vektor agar pertanyaan dan chunk dapat dibandingkan berdasarkan kedekatan makna. Kualitasnya bergantung pada bahasa, istilah domain, dan jenis pertanyaan yang akan diterima sistem.

Uji pada pertanyaan milikmu

Benchmark seperti MTEB membantu menyaring calon model, tetapi peringkat umum tidak menggantikan uji pada dokumenmu. Buat kumpulan pertanyaan yang mencakup sinonim, istilah internal, kode error, dan pertanyaan yang memang tidak punya jawaban. Tandai dokumen atau chunk yang relevan, lalu bandingkan beberapa model pada kumpulan yang sama.

Dimensi dan biaya

Vektor yang lebih panjang memakai lebih banyak ruang penyimpanan dan dapat menambah biaya pencarian. Dimensi yang lebih besar tidak otomatis memberi hasil yang lebih baik. Jika model embedding mendukung representasi yang dapat dipotong, seperti pada Matryoshka Representation Learning, uji ukuran yang lebih kecil terhadap kualitas pencarian sebelum memakainya. Jangan memangkas dimensi model biasa tanpa memastikan model itu mendukungnya.

Cache dengan versi yang jelas

Simpan embedding agar dokumen yang tidak berubah tidak perlu diproses ulang. Kunci cache sebaiknya mencakup isi chunk, model dan versinya, serta aturan pemrosesan teks. Jika salah satunya berubah, buat embedding baru. Hash isi saja tidak cukup ketika model atau cara memecah dokumen sudah berganti.

Mencari bukti

Mulai dengan satu metode pencarian, ukur hasilnya, lalu tambah kompleksitas ketika terlihat jenis pertanyaan yang gagal. Pencarian semantik dengan embedding dapat menemukan hubungan makna; pencarian leksikal seperti BM25 berguna untuk istilah persis, misalnya ERR_CONN_RESET atau nomor kebijakan. BEIR membandingkan beberapa keluarga metode pencarian di beragam tugas dan menunjukkan mengapa pengujian lintas jenis kueri penting.

Gabungkan hasil bila perlu

Jika kedua metode saling melengkapi pada data uji, gabungkan peringkatnya. Reciprocal rank fusion (RRF) memakai posisi hasil, sehingga skor dari dua metode tidak harus berada pada skala yang sama. Contoh sederhana ini menerima daftar ID chunk dari beberapa pencarian:

from collections import defaultdict


def rrf(rankings: list[list[str]], k: int = 60) -> list[str]:
    scores: dict[str, float] = defaultdict(float)
    for ranking in rankings:
        for rank, chunk_id in enumerate(ranking, start=1):
            scores[chunk_id] += 1 / (k + rank)
    return sorted(scores, key=lambda chunk_id: scores[chunk_id], reverse=True)

Nilai k di sini adalah konstanta dalam rumus RRF, bukan jumlah chunk yang akan dikirim ke model. Prinsip metode ini dijelaskan dalam makalah RRF.

Urutkan ulang seperlunya

Model reranker dapat membaca pertanyaan bersama tiap kandidat chunk dan mengurutkannya lagi. Coba pada sejumlah kandidat yang masuk akal untuk biaya dan latensi aplikasi. Reranker tidak bisa menyelamatkan jawaban jika chunk yang dibutuhkan sama sekali tidak ditemukan pada tahap pencarian.

Jangan mengirim jumlah chunk yang sama untuk setiap pertanyaan tanpa melihat hasilnya. Terlalu banyak konteks dapat menambah biaya dan menyulitkan model memakai bukti yang relevan; posisi informasi dalam konteks panjang juga dapat memengaruhi hasil, seperti ditunjukkan dalam Lost in the Middle. Tetapkan batas kandidat, uji kualitas hasil teratas, dan izinkan sistem menjawab “belum menemukan sumber yang cukup” ketika bukti tidak memadai.

Menyusun jawaban

Kirim chunk dengan ID, judul dokumen, dan tautan atau lokasi sumber yang stabil. Minta model menjawab berdasarkan sumber yang tersedia serta menandai bagian yang belum didukung. Contoh instruksi singkat:

Jawab pertanyaan hanya berdasarkan kutipan yang tersedia. Sertakan ID sumber untuk klaim faktual. Jika sumber tidak cukup atau saling bertentangan, jelaskan keterbatasannya; jangan menebak.

Instruksi ini membantu, tetapi tidak menjamin jawaban benar. Cocokkan ID kutipan dengan chunk yang benar-benar dikirim, lalu periksa apakah kalimat yang dikutip didukung oleh isinya. Perlakukan teks hasil pencarian sebagai data, bukan instruksi baru yang boleh mengubah perilaku sistem.

Mengukur kualitas

Pisahkan evaluasi pencarian dari evaluasi jawaban. Jika chunk yang benar tidak pernah ditemukan, mengubah prompt jawaban tidak akan memperbaiki akar masalahnya.

Ukur pencarian

Buat kumpulan pertanyaan dengan sumber relevan yang ditandai manusia. Recall@k mengukur proporsi sumber relevan yang muncul di antara k hasil teratas. Jika cukup menemukan satu sumber untuk menjawab, ukur juga berapa banyak pertanyaan yang mendapat setidaknya satu hasil relevan. Tambahkan pertanyaan dengan istilah persis, sinonim, dokumen mirip, dan kasus tanpa jawaban. Simpan hasil per jenis pertanyaan agar penurunan pada satu kelompok tidak tertutup oleh rata-rata keseluruhan.

Ukur jawaban dan kutipan

Periksa apakah jawaban menjawab pertanyaan, apakah setiap klaim penting didukung sumber, dan apakah sistem berani menyatakan bukti tidak cukup. Penilai berbasis model bisa membantu mempercepat pemeriksaan, seperti dalam RAGAS, tetapi kalibrasikan dengan contoh yang telah diperiksa manusia. Nilai dari penilai otomatis adalah sinyal, bukan pengganti pembacaan atas jawaban dan sumbernya.

Jadikan perubahan terukur

Simpan contoh gagal sebagai kasus regresi. Setelah mengganti strategi chunk, embedding, atau reranker, jalankan pertanyaan yang sama dan bandingkan akurasi pencarian, dukungan sumber, latensi, serta biaya. Perubahan yang meningkatkan satu metrik bisa memperburuk metrik lain.

Menjalankan di aplikasi

Catat waktu untuk embedding pertanyaan, pencarian, pengurutan ulang, dan generasi secara terpisah. Tetapkan anggaran latensi berdasarkan pengukuran aplikasimu, bukan angka contoh dari sistem lain. Pengguna juga perlu tahu kapan sistem sedang mencari dan kapan jawaban sudah siap.

Saat salah satu tahap gagal

Jika reranker gagal, hasil pencarian awal mungkin masih dapat dipakai, asalkan kualitasnya memadai. Jika indeks vektor tidak tersedia, pencarian leksikal bisa menjadi cadangan bila memang disiapkan dan tetap menghormati izin akses. Namun, jika pencarian tidak menghasilkan bukti yang cukup, nyatakan keterbatasannya. Jawaban yang terdengar yakin tanpa sumber adalah kegagalan yang lebih serius daripada tidak menjawab.

Urutan membangun versi pertama

  1. Kumpulkan pertanyaan nyata dan tandai sumber yang seharusnya menjawabnya.
  2. Pecah dokumen menurut struktur, simpan metadata dan izin akses, lalu buat indeks pencarian sederhana.
  3. Ukur pencarian sebelum menambahkan model pembuat jawaban.
  4. Tambahkan generasi dengan kutipan yang dapat dibuka dan respons ketika bukti tidak cukup.
  5. Evaluasi jawaban, latensi, dan biaya. Simpan kasus gagal untuk perbandingan setelah setiap perubahan.

Apa yang bisa ditunda

Perluasan kueri, pencarian bertahap oleh agen, dan beberapa lapis reranker menambah biaya serta titik kegagalan. Mulai dari alur sederhana yang punya data uji. Tambahkan teknik yang lebih rumit ketika kasus gagal menunjukkan manfaatnya dan hasil evaluasi membuktikan perbaikannya.

RAG yang baik bukan yang memiliki tahap paling banyak, melainkan yang menemukan bukti yang tepat, menunjukkan sumbernya, dan tahu kapan bukti itu belum cukup.