v1.0.0-019 : Dynamic RAG Knowledge Injection untuk OCR Engine
Refaktor arsitektur OCR Engine dari prompt hardcode menjadi Dynamic RAG Injection. Pengetahuan penafsiran nota spesifik (seperti format Faktur FI RINCINSARI / KRT.LSN.SAT) kini disuplai secara dinamis dari Vector Database RAG saat runtime, bukan dikodekan statis di source code.
Pada sesi sebelumnya (v1.0.0-018), aturan penafsiran nota spesifik vendor seperti kolom KRT.LSN.SAT (Faktur FI RINCINSARI) dan deteksi nama supplier di footer bawah nota di-hardcode langsung ke dalam prompt statis ocrTool.ts. Hal ini merupakan antipattern arsitektur yang merusak generisitas OCR Engine dan menyulitkan pemeliharaan jangka panjang.
Sebelum (Masalah): Aturan penafsiran spesifik vendor/layout ter-hardcode di prompt statis:
// Aturan hardcode yang MERUSAK generisitas engine (SUDAH DIHAPUS):// - "PENAFSIRAN QTY FAKTUR GROSIR (KRT.LSN.SAT / KRT.TSN.SAT): Split string berdasarkan titik..."// - "Periksa Kop Atas MAUPUN Footer Paling Bawah nota. Seringkali akibat potongan printer..."Sesudah (Solusi):
- Prompt dasar dikembalikan ke 10 aturan generik yang berlaku untuk semua jenis nota (kejujuran OCR, format tanggal ISO, logika harga, anti-double-counting diskon, dsb).
- Dynamic RAG Lookup ditambahkan sebelum pemanggilan Gemini Vision:
- Engine melakukan pencarian kesamaan vektor (
searchVectorContext) ke tabelknowledge_vectorsdenganapp_context: "sajen_ocr". - Jika ada RAG Knowledge dengan similarity ≥ 75%, aturan penafsiran khusus (
_rag_rules) disuntikkan secara DINAMIS ke dalam prompt. - Log diagnostik dicetak:
✅ RAG Knowledge ditemukan (similarity: 92%). Menyuntikkan panduan penafsiran secara dinamis... - Jika tidak ada match, engine berjalan dengan prompt generik murni tanpa error.
- Engine melakukan pencarian kesamaan vektor (
// Pola baru: Lookup RAG sebelum Vision AI dipanggilconst ragDocs = await searchVectorContext({ embedding: ragEmbedding, tenant_id: tenantId, app_context: "sajen_ocr", agent_role: "", limit: 2});const bestMatch = ragDocs.find(d => (d.similarity ?? 0) >= 0.75);if (bestMatch) { ragContextPrompt = `\n\n--- PETUNJUK PENAFSIRAN NOTA DARI RAG KNOWLEDGE ---\n${ragRules}\n--- AKHIR PETUNJUK RAG ---`;}tenant_idkini ikut dikirim dalamcontextpayload ke MCP OCR Tool.- RAG lookup bisa menemukan aturan penafsiran yang spesifik per-toko/tenant.
- RAG Knowledge berisi panduan penafsiran nota PT. DELTA GUNA UTAMA SALATIGA / RINCINSARI (Faktur FI) telah berhasil di-ingest ke
knowledge_vectorsdi MCP Vector DB dengan IDc7c9ad73-2fd0-42d6-b52a-6ee43845c6b9. - Isi
_rag_rulesmencakup:- Nama supplier ada di BAGIAN BAWAH nota (bukan header/penerima).
- Tanggal format
DD/MM/YYYY→ ISOYYYY-MM-DD. - Kolom
KRT.TSN.SAT / KRT.LSN.SAT: split titik, ambil angka > 0. - Harga satuan dari kolom
HRG.PCS+PPN, diskon dari kolomDiskon(nominal).
| Sebelumnya | Sesudah |
|---|---|
| Aturan hardcode di kode sumber | Aturan di-ingest ke Vector DB |
| Harus deploy ulang jika ada nota baru | Cukup ingest RAG knowledge baru |
| Prompt engine makin kotor & panjang | Prompt engine bersih & generik |
| Tidak bisa belajar dari koreksi pengguna | Knowledge terakumulasi otomatis via feedback |
- Menambahkan penegasan pada aturan #2 prompt generik di
ocrTool.tsbahwa penambahan item secara tulisan tangan (oleh sales/staff) di atas nota cetak adalah hal yang LAZIM dan UMUM terjadi. Jika terbaca dengan jelas, item tersebut WAJIB diekstrak dan dimasukkan ke daftaritems. - RAG Knowledge Faktur FI di Vector DB di-update ke versi terbaru yang memuat aturan #8 untuk penanganan item tulisan tangan (ID ingest:
39eed53a-ac99-4a4f-bc6c-b9cb0521e57c).
- Masalah: Sajen OCR Worker memiliki filter penyeleksi JSON yang sangat ketat. Skema JSON dari MCP OCR Hub menggunakan key
"merchant"dan"readability_status"yang sebelumnya tidak dikenali oleh validatorocr_worker.py. Hal ini memicu fallback otomatis ke call LLM lokal (non-RAG) untuk menstrukturkan ulang teks mentah, sehingga data diskon/harga/nama toko kembali salah serta membuat proses berjalan lambat karena double LLM call. - Solusi: Memodifikasi filter regex dan parser di
ocr_worker.pyagar mengenali key"items"dan"readability_status"dari format output MCP secara langsung. JSON hasil ekstraksi dari RAG MCP sekarang dapat digunakan secara instan tanpa fallback berulang.
| Sebelumnya | Sesudah |
|---|---|
| Aturan hardcode di kode sumber | Aturan di-ingest ke Vector DB |
| Harus deploy ulang jika ada nota baru | Cukup ingest RAG knowledge baru |
| Prompt engine makin kotor & panjang | Prompt engine bersih & generik |
| Tidak bisa belajar dari koreksi pengguna | Knowledge terakumulasi otomatis via feedback |
| Double LLM Call (lambat & salah RAG) | Single LLM Call instan dengan validasi skema yang tepat |
mcp-backend— berhasil, port 3000 ✅sajen-api— berhasil, port 8005 (termasuk update parser JSON diocr_worker.py) ✅sajen-worker— berhasil, port 8005 ✅