RAG Produksi dalam Skala Besar: Pelajaran dari 10.000+ Listing Setiap Hari
Saya membangun pipeline RAG untuk sebuah papan lowongan kerja. Semuanya berjalan lancar di staging, tetapi kesulitan saat menghadapi beban kerja nyata. Memproses ribuan listing setiap hari membutuhkan lebih dari sekadar vector store yang bagus. Anda harus memahami di mana sistem tersebut akan mengalami kegagalan.
Berikut adalah pelajaran saya mengenai chunking, embeddings, biaya, dan observability.
1. Jangan menebak strategi chunking Anda
Kebanyakan tutorial menganggap chunking sebagai pengaturan sederhana. Dalam produksi, strategi Anda menentukan akurasi dan biaya.
Saya menguji tiga metode untuk listing pekerjaan:
- Fixed-size chunks: Metode ini gagal. Ia memecah bagian seperti "requirements" dan "benefits" pada titik yang acak. Hal ini menciptakan retrieval yang berisik (noisy).
- Semantic chunking: Ini lebih baik tetapi tidak konsisten. Beberapa chunk terlalu panjang dan yang lainnya terlalu pendek.
- Recursive character splitting with overlap: Ini yang paling berhasil. Saya memecah berdasarkan baris baru (newlines) dan kalimat. Saya menggunakan ukuran 400 token dengan overlap 50 token. Ini memastikan kalimat yang terbagi ke dalam dua chunk tetap terhubung.
Tips pro: Normalisasi data Anda sebelum melakukan chunking. Sumber yang berbeda seperti Greenhouse atau Lever mengembalikan format yang berbeda. Bersihkan teks terlebih dahulu agar chunker Anda melihat struktur yang konsisten.
2. Embeddings: Biaya vs. Akurasi
Saya menguji Llama 3.1 melalui Ollama terhadap OpenAI text-embedding-3-small. Model lokal memang gratis tetapi kesulitan dengan istilah spesifik domain seperti "equity compensation." Hasilnya berisik (noisy). OpenAI lebih mahal tetapi memberikan kecocokan yang akurat. Saya memilih OpenAI karena retrieval yang buruk akan memakan biaya lebih besar pada pemanggilan LLM nantinya.
Untuk menghemat waktu, saya melakukan batching pada permintaan saya. Saya mengirim hingga 100 chunk dalam satu panggilan. Ini mengurangi latensi dan menjaga pipeline tetap cepat.
3. Trade-off Vector Store
Saya menggunakan Pinecone untuk prototyping karena cepat untuk disiapkan. Namun, dalam skala besar, biayanya menjadi terlalu tinggi.
Saya beralih ke pgvector di dalam PostgreSQL.
- Membutuhkan lebih banyak usaha untuk disiapkan.
- Menghemat biaya dalam jumlah besar.
- Memberikan konsistensi transaksional. Karena embeddings berada di database yang sama dengan data pekerjaan, Anda memiliki satu sumber kebenaran (source of truth). Anda tidak perlu menyinkronkan dua sistem yang berbeda.
4. Mengontrol Biaya LLM
Memberikan skor pada setiap listing dengan GPT-4o sangatlah mahal. Saya menggunakan tiga taktik untuk menekan biaya:
- OpenAI Batch API: Saya memproses pekerjaan pemberian skor pada malam hari. Ini memberikan diskon yang besar.
- Caching: Saya menyimpan cache hasil untuk profil kandidat yang berulang.
- Model tiering: Saya menggunakan GPT-4o-mini untuk peran umum seperti "Sales Representative." Saya hanya menggunakan GPT-4o untuk peran niche di mana presisi sangat penting.
5. Bangun Observability Terlebih Dahulu
Pipeline saya pernah gagal secara diam-diam (failed silently). Data yang malformed menyebabkan chunk kosong, yang kemudian dilewati oleh sistem tanpa pesan error.
Saya memperbaikinya dengan menambahkan structured logging dengan correlation ID. Ini memungkinkan saya untuk melacak satu listing dari tahap ingestion hingga scoring. Saya akhirnya bisa melihat sumber data mana yang menyebabkan kegagalan.
Pelajaran terbesar: Sebagian besar masalah berasal dari data yang berantakan, bukan dari AI. Perbaiki infrastruktur data (data plumbing) Anda terlebih dahulu.
Optional learning community: https://t.me/GyaanSetuAi
