# Artifact Plan: Adaptive Hybrid Graph-RAG Agentic Chatbot (BRAIN MySRE)

## 1. Judul
Rancang Bangun Agentic Chatbot Hybrid Graph-RAG (BRAIN MySRE Migration ke Arsitektur Neo4j-Supabase)

## 2. Tanggal
Rabu, 6 Mei 2026

## 3. Deskripsi
Dokumen ini mendetailkan rencana implementasi chatbot agen cerdas yang menggabungkan kemampuan navigasi semantik relasional dari Neo4j Knowledge Graph dan ekstraksi konten teknis mendalam dari Supabase Vector Search. Chatbot berfungsi sebagai "Asisten Peneliti Akademik" yang memiliki kemampuan *adaptive context routing*—ia mampu berfokus tajam pada satu dokumen, memperluas wawasan ke literatur terkait secara otonom, atau menjawab dari *general knowledge* jika tidak ada literatur yang relevan, sambil mempertahankan standar sitasi dan gaya bahasa ilmiah.

## 4. Metodologi
Chatbot diimplementasikan menggunakan paradigma **PRAL (Perceive, Reason, Act, Learn)**:

*   **P - Perceive (Persepsi):** Analisis mendalam atas input pengguna. Modul ini mengekstrak *intent* (apakah pertanyaan teknis, komparatif, atau umum), mengekstrak *entities* (kata kunci kunci), dan memvalidasi ketersediaan *Node Context* awal.
*   **R - Reason (Penalaran Navigasi):** Otak pengambilan keputusan. Berdasarkan *intent*, modul ini memilih jalur *retrieval* yang disebut "Layers of Context":
    *   *Lapis 1 (Spesifik):* Fokus 100% pada *chunks* dari *node* yang sedang dibuka.
    *   *Lapis 2 (Ekspansif):* Navigasi melalui *edge* `SIMILAR_*` di Neo4j untuk menarik *node* tetangga yang memiliki relevansi (dibatasi oleh skor kemiripan dan bobot `visual_pagerank_size`).
    *   *Lapis 3 (General):* Evaluasi bahwa pertanyaan "Out-of-the-Box" dan harus dijawab via LLM *Base Knowledge* dengan *disclaimer* ketat.
*   **A - Act (Eksekusi & Sintesis):** Pengumpulan data secara paralel dari Neo4j (untuk *reasoning edge*) dan Supabase (untuk teks murni berdasarkan `file_hash`). Hasil difilter ulang melalui *Reranker* sebelum dikirim ke LLM menggunakan *Research Policy Protocol* untuk menghasilkan jawaban ber-sitasi.
*   **L - Learn (Pembelajaran & State):** Pencatatan metrik kinerja sesi dan pemeliharaan *Chat History* di Supabase untuk memastikan *turn-by-turn context continuity*.

## 5. Keputusan
*   **Penyimpanan Sejarah:** Riwayat percakapan (*Chat History*) disimpan persisten di Supabase (tabel `chat_messages`) dengan mekanisme limitasi jendela konteks otomatis (hanya N pesan terakhir).
*   **Batas Ekspansi Graf (Lapis 2):** Maksimal 5 artikel gabungan (1-2 Primary Node + 2-3 Neighbor Nodes) untuk mencegah *token overflow* dan menjaga ketajaman sintesis.
*   **Standar Model Embedding:** Google Gemini `models/gemini-embedding-001` (768 dimensi) wajib digunakan untuk semua proses pencarian vektor di Supabase agar sinkron dengan pipeline *ingestion*.
*   **Titik Integrasi Node Utama:** Relasi antara Neo4j dan Supabase dihubungkan melalui `file_hash` (idempotent), BUKAN melalui internal `elementId` Neo4j yang dapat berubah.
*   **Penamaan Prompt Utama:** Mengubah istilah "Master Prompt" menjadi **"Research Policy Protocol"** untuk menekankan bahwa ini adalah batasan perilaku terstruktur, bukan sekadar instruksi teks bebas.
*   **Fase Uji Coba:** Pengujian dilakukan melalui Terminal/CLI Python (`test_chatbot_cli.py`) sebelum di-ekspos melalui *endpoints* FastAPI.

## 6. Alur Diagram
```mermaid
flowchart TD
    User["💬 User Input\n(Query + Active Hash)"] --> P["🧠 Perceive\n(Extract Intent & Entities)"]
    P --> R["🤔 Reason\n(Determine Context Strategy)"]
    
    subgraph Adaptive_Retrieval_Layers
        R --> |Specific| L1["Layer 1: Deep Focus\n(Only Active Hash)"]
        R --> |Comparative| L2["Layer 2: Graph Expansion\n(Active + Neighbors via PageRank)"]
        R --> |Generic/Out-of-Box| L3["Layer 3: Zero-Context\n(General LLM Knowledge)"]
    end
    
    L1 & L2 --> N4J["🔍 Neo4j Query\n(Get Edge Reasoning & Neighbor Hashes)"]
    L1 & L2 --> SUPA["📦 Supabase Vector\n(Fetch Pillar Chunks by Hashes)"]
    
    N4J & SUPA --> RK["🛡️ Reranker Module\n(Score & Filter Top 5 Chunks)"]
    RK --> A["🚀 Act\n(Apply Research Policy Protocol)"]
    L3 --> A
    
    A --> LLM["🤖 LLM Generation\n(Stream Response + Inline Citations)"]
    LLM --> Hist["📝 Learn\n(Save to Chat History DB)"]
    Hist --> Output["✅ Output to User"]
```

## 7. Struktur Folder (Tree)
```text
app/
├── api/
│   └── routes/
│       └── chat.py                # (FastAPI endpoints untuk Chatbot)
└── services/
    └── chatbot/
        ├── __init__.py
        ├── agent_orchestrator.py  # (Pengelola Siklus PRAL & Router)
        ├── research_policy.py     # (Konfigurasi Persona & Aturan Sitasi)
        ├── graph_retriever.py     # (Koneksi ke Neo4j: Traverse & PageRank)
        ├── vector_retriever.py    # (Koneksi ke Supabase: Hash-based Search)
        ├── chat_history.py        # (Manajemen Sesi di Supabase)
        └── reranker.py            # (Penyaringan Relevansi Chunks)

scripts/
└── test_chatbot_cli.py            # (Skrip interaktif Terminal)
```

## 8. Asumsi
1.  **Infrastruktur Backend:** Proses *ingestion* (ekstraksi, *chunking*, Neo4j *merge*) sudah selesai untuk artikel yang dicari, sehingga Neo4j dan Supabase dalam keadaan sinkron.
2.  **API Kesesuaian:** Tabel `chat_messages` akan dibuat secara terpisah di Supabase dengan skema minimal: `id`, `session_id`, `role` (user/assistant), `content`, `timestamp`.
3.  **Konteks Awal:** Frontend selalu memberikan setidaknya satu *hash* dari artikel yang sedang dilihat pengguna saat memulai inisiasi *chat*.
4.  **Isolasi SDK:** Kode di dalam `app/services/chatbot` akan mendahulukan penggunaan pustaka resmi (seperti `google-genai` atau LangChain LCEL) tanpa campur aduk *wrapper* usang.

## 9. Konsep Tabel Metriks (Evaluation Logging)
Sistem akan menyimpan metrik interaksi di log atau DB terpisah untuk analisis performa (Fase *Learn* lanjutan):

| Metric Column | Tipe Data | Deskripsi |
| :--- | :--- | :--- |
| `session_id` | String | ID Sesi percakapan. |
| `query_intent` | String | Hasil *Perceive* (e.g., "specific", "comparative"). |
| `layer_strategy` | Int | Lapis konteks yang terpicu (1, 2, atau 3). |
| `neo4j_ms` | Float | Latensi pengambilan data relasi dari Neo4j. |
| `supabase_ms` | Float | Latensi pengambilan vektor dari Supabase. |
| `total_sources` | Int | Jumlah artikel unik yang dijadikan sitasi akhir. |
| `hallucination_flag`| Boolean | Nilai peringatan jika *Reranker* mengembalikan skor 0 tapi LLM tetap menjawab spesifik. |

## 10. Konsep Logika Prompting (`research_policy.py`)
Meninggalkan konsep "Master Prompt" yang ambigu, *Research Policy Protocol* adalah objek konfigurasi ketat yang berisi:

*   **Identitas (Persona):** Asisten Analis Riset Senior. Menggunakan Bahasa Indonesia formal, objektif, dan tanpa emosi berlebih.
*   **Regulasi Bukti (Groundedness):** 
    *   Jika strategi Lapis 1 & 2: Dilarang keras menyebutkan fakta spesifik yang tidak ada dalam *chunks* yang diberikan.
    *   Jika strategi Lapis 3: Wajib menambahkan klausa "Berdasarkan pengetahuan umum..."
*   **Regulasi Sitasi (Citation Rules):**
    *   Sitasi BUKAN daftar pustaka di akhir teks.
    *   Sitasi WAJIB berformat *inline*, contoh: "Menurut analisis metodologi pada literatur ini [hash_dokumen_A], pendekatan SVM lebih stabil..."
*   **Resolusi Konflik:** Jika dua artikel dari Lapis 2 memiliki klaim bertentangan, sebutkan kedua klaim tersebut secara netral beserta sitasinya.

## 11. Langkah Implementasi
1.  **Preparation:** Setup skema Supabase untuk `chat_messages`.
2.  **Core Retrieval:** Pembangunan modul `graph_retriever.py` (Cypher) dan `vector_retriever.py` (Supabase Client).
3.  **Refinement:** Pembangunan `reranker.py` (menggunakan LLM *low-cost* untuk menyortir *chunks* yang didapat dari tahap retrieval).
4.  **Orchestration:** Pembuatan `agent_orchestrator.py` untuk mengontrol aliran data dari P ke R, lalu ke A.
5.  **Policy Encoding:** Merumuskan struktur *string* ketat di `research_policy.py`.
6.  **Integration:** Pengujian siklus penuh menggunakan `test_chatbot_cli.py`.
7.  **Exposure:** Membungkus *Orchestrator* ke dalam FastAPI Endpoint (`app/api/routes/chat.py`).

## 12. Tabel Eksekusi Task

| Check | Fase | Task | Detail Task | Deskripsi | Acceptance Criteria |
| :---: | :---: | :--- | :--- | :--- | :--- |
| [x] | 1 | **Foundation** | Define Research Policy | Pembuatan file `research_policy.py` | Modul berisi string konstanta yang memuat aturan *Groundedness*, Persona (Indo Akademis), dan Standar Sitasi (*Inline*). |
| [x] | 1 | **Foundation** | History Setup | Pembuatan file `chat_history.py` | Modul memiliki fungsi simpan dan ambil pesan dari Supabase berdasarkan `session_id`, memotong *history* berlebih jika token > X. |
| [x] | 2 | **Retrieval** | Neo4j Explorer | Pembuatan file `graph_retriever.py` | Fungsi `get_neighbors(hash)` mengembalikan *hash* artikel tetangga & `edge_reasoning` menggunakan *driver* Neo4j, terfilter skor *PageRank*. |
| [x] | 2 | **Retrieval** | Supabase Fetcher | Pembuatan file `vector_retriever.py` | Fungsi `get_chunks(hash_list)` mengembalikan teks pilar dari Supabase berdasarkan `.in_("file_hash", hash_list)`. |
| [x] | 3 | **Agentic** | Context Reranker | Pembuatan file `reranker.py` | Fungsi menerima N *chunks*, mengirim ke *mini-LLM* untuk *scoring* relevansi terhadap *query*, dan mengembalikan top 5 *chunks*. |
| [x] | 3 | **Agentic** | PRAL Orchestrator | Pembuatan file `agent_orchestrator.py` | Modul menyatukan *Perceive* (Tentukan Lapis 1/2/3), *Reason* (Atur Retrieval), dan *Act* (Kirim ke LLM Utama). |
| [x] | 4 | **Testing** | CLI Interface | Pembuatan file `scripts/test_chatbot_cli.py` | Skrip terminal berjalan interaktif, bisa melakukan "mock" *Active Hash*, dan mensimulasikan *turn-by-turn chat* ber-sitasi. |
| [x] | 5 | **API** | Endpoint Integration | Update `app/api/routes/chat.py` | *Endpoint* REST siap dikonsumsi Frontend, idealnya dengan *StreamingResponse* dan kompatibel dengan arsitektur FastAPI yang ada. |