Kebanyakan prototaip RAG kelihatan sama di sebalik tabir. Seseorang memasukkan PDF ke dalam saluran paip, memotong teks kepada cebisan 512-token yang kemas, memasukkannya ke dalam pangkalan data vektor, dan menganggap tugas tersebut selesai. Untuk demo ringkas, ini mungkin kelihatan mengagumkan. Namun dalam produksi, ia akan gagal.
Cebisan tetap tidak mempedulikan apa yang dipotongnya. Ia akan memotong kontrak undang-undang di tengah-tengah klausa indemniti. Ia akan memasukkan lima titik akhir API yang tidak berkaitan ke dalam tetingkap konteks yang sama dan menenggelamkan model dalam gangguan. Ia akan memaksa anda untuk mendapatkan lebih banyak fragmen daripada yang diperlukan, sekali gus meningkatkan kependaman dan membazirkan token. Hasilnya adalah jawapan separuh jalan, halusinasi, dan pengguna yang kecewa.
Kami merombak sepenuhnya lapisan pencarian kami dan membinanya semula. Hasilnya ialah sistem yang mencapai 95 peratus recall sambil mengurangkan kependaman sebanyak 40 peratus. Berikut adalah cara tepat bagaimana kami melakukannya.
Mengapa Cebisan Tetap Gagal dalam Produksi
Tetapan lalai 512-token bukanlah satu pilihan reka bentuk. Ia adalah produk sampingan daripada tetingkap konteks model embedding awal dan tetapan lalai perpustakaan yang kemas. Ia mudah untuk dilaksanakan tetapi membawa bencana jika bergantung kepadanya.
Dokumen tidak seragam. Satu klausa undang-undang boleh mencecah tujuh ratus token tanpa noktah pemisah yang jelas. Jika anda memotongnya pada lima ratus dua belas, anda akan mencipta dua fragmen yang terasing. Apabila peguam atau pegawai pematuhan bertanya tentang had liabiliti, sistem hanya mengembalikan separuh daripada obligasi tersebut. Model bahasa akan berhalusinasi tentang bahagian yang hilang, atau lebih teruk lagi, menafikan kewujudan had tersebut.
Dokumentasi API pula mengalami masalah yang sebaliknya. Satu cebisan lima ratus token mungkin menelan keseluruhan modul: header pengesahan, kod ralat, had kadar, dan skema webhook. Apabila pembangun bertanya cara mengendalikan AUTH_4027, pencari akan memaparkan campuran fungsi yang tidak berkaitan. Model tidak mempunyai pilihan selain mencampurkan semuanya menjadi maklumat yang tidak bermakna.
Cebisan yang buruk juga meningkatkan kependaman. Fragmen yang lemah bermakna anda memerlukan top-k yang lebih besar untuk merangkumi sesuatu topik. Lebih banyak cebisan bermakna prompt yang lebih panjang. Prompt yang lebih panjang bermakna penjanaan yang lebih lambat dan bil yang lebih tinggi. Pengalaman pengguna musnah akibat ralat-ralat kecil yang berterusan.
Padankan Cebisan dengan Dokumen
Kami berhenti mengira token dan mula membaca bahan tersebut. Strategi cebisan yang betul bergantung pada struktur sumber.
Dokumen undang-undang memerlukan cebisan aksara rekursif dengan sempadan yang peka terhadap klausa. Pemotong tersebut menghormati hierarki: ia mencari pengepala bahagian terlebih dahulu, kemudian perenggan bernombor, kemudian pemisah ayat semula jadi. Ia tidak akan sesekali memutuskan sub-klausa atau memisahkan frasa obligasi merentasi cebisan. Apabila anda mendapatkan petikan tentang indemnifikasi, anda akan mendapat klausa penuh, had, dan pengecualiannya.
Dokumentasi API menuntut cebisan peka struktur. Kami melakukan analisis mengikut definisi fungsi, bukan bajet token. Setiap cebisan mengandungi tandatangan fungsi yang lengkap, huraian parameternya, dan nota pengendalian ralat yang berdekatan. Jika pembangun mencari kaedah tertentu, mereka akan menerima keseluruhan kontrak, bukan fragmen yang terperangkap di dalam pembahagian rawak.
Tiket sokongan adalah bising dan tidak linear. Satu rantaian mungkin bermula dengan laporan pepijat, memperkenalkan jalan penyelesaian sementara, dan berakhir dengan nota eskalasi dalaman. Cebisan semantik mengesan peralihan topik dengan mengukur kesamaan embedding antara ayat. Kami hanya membenarkan pemisahan pada sempadan tematik semula jadi, supaya perbualan tentang kegagalan log masuk kekal berasingan daripada susulan tentang kitaran pengebilan.
Wiki adalah yang paling sukar. Ia luas, saling berpautan, dan disusun secara longgar. Kami menggunakan cebisan ejen (agentic chunking), di mana LLM ringan membaca halaman dan memutuskan pemisahan berdasarkan koheren tematik. Ia menelan kos yang sedikit lebih tinggi semasa masa pengambilan data, tetapi cebisan yang terhasil adalah lengkap dan sedia untuk dicari. Satu halaman tentang amalan terbaik penggunaan akan dipecahkan kepada unit logik: pemeriksaan pra-penerbangan, prosedur rollback, dan penyediaan pemantauan, dan bukannya blok teks rawak.
Carian Hibrid: Kata Kunci dan Vektor Bersama
Carian vektor padat memahami makna. Namun, ia sangat lemah dalam mengendalikan rentetan tepat. Jika pengguna mencari kod ralat yang tepat seperti AUTH_4027 atau nama pelanggan seperti "Stark Industries," embedding vektor mungkin terlepas sasaran kerana ia mengoptimumkan kedekatan konseptual, bukan ketepatan tahap aksara.
Carian kata kunci tulen melalui BM25 mempunyai kelemahan sebaliknya. Ia akan mencari AUTH_4027 dengan sempurna, tetapi ia akan terlepas jambatan konseptual antara "kegagalan pengesahan" dan "log masuk ditolak."
We run both in parallel. BM25 and vector search operate independently over the same corpus. Their result lists are merged using Reciprocal Rank Fusion, which reorders candidates by balancing their positional ranks. You do not need calibrated weights. You simply get the precision of exact match and the intuition of semantic search in a single ranked list.
Then we add a cross-encoder reranker. This is a separate model that scores each passage against the original query, producing a relevance signal far finer than either retriever alone. It adds about 50 milliseconds of latency. It increases recall by 15 percent. If you care about answer quality, that trade is non-negotiable.
Query Expansion: Fix the Search Before It Starts
Bad queries are the dirty secret of every retrieval system. Users do not write like your embedding space. They type "it broke." They paste truncated stack traces. They use internal jargon your index has never seen.
We transform the query before it ever touches the index. First, we expand a single query into three to five diverse search terms. If the original is "payment failed," we also search for "transaction error," "billing declined," and "charge unsuccessful
