# Graph & Vector Database Benchmark Plan

## Judul
Rencana Pengujian Terisolasi (Benchmark) Neo4j Vector Knowledge Graph & Edge Generation

## Tanggal
Kamis, 14 Mei 2026

## Deskripsi
Dokumen ini merupakan panduan dan cetak biru (blueprint) untuk membangun skrip benchmark mandiri (`benchmark_graph.py`). Skrip ini bertujuan untuk menguji operasi Neo4j secara terisolasi namun berkesinambungan—mulai dari *Node Injection*, *Vector Embedding*, *Semantic Retrieval*, hingga *Edge Reasoning & Creation*.

Pengujian ini menggunakan data *hardcoded* asli dari tahap ekstraksi pipeline sebelumnya (`archive/Testing-Pipeline/benchmark-extraction/Output-JSON/`). Tujuannya adalah memastikan fungsi-fungsi inti di `app.services.ingestion` bekerja dengan benar di instance Neo4j yang kosong, serta mengukur latensi setiap fase tanpa mengubah kode utama aplikasi sedikit pun.

## Metodologi
1.  **Isolation without Modification**: Skrip berada di `scripts/Testing-Pipeline/` dan memanipulasi `sys.path` untuk mengimpor modul `app` seolah-olah dieksekusi dari *root*. Dilarang mengubah kode di dalam `@app/**`.
2.  **Deterministic Input**: Menggunakan 2 sampel jurnal dari hasil *extraction benchmark* yang dimasukkan ke dalam skrip sebagai struktur data *hardcoded*.
3.  **Real Cryptography**: Menghitung MD5 Hash secara *real-time* langsung dari file PDF fisik yang ada di `Literature/`, selaras dengan data ekstraksi.
4.  **Real Network Operations**: Sepenuhnya menggunakan OpenAI API (`text-embedding-3-small`) untuk embedding vektor dan Alibaba DashScope untuk *edge reasoning* serta evaluasi domain.
5.  **Strict Integrity**: Mematuhi ambang batas (`PILLAR_THRESHOLD_MATRIX`) bawaan. Tidak ada penurunan standar demi memaksa terbentuknya *edge*.
6.  **Dual Matrix Reporting**: Output performa dipisah menjadi dua tabel untuk mencatat operasi tingkat *Node* dan operasi tingkat *Edge* secara terpisah.

## Keputusan
*   **[DEC-01] Data Sumber**: Data metadata dan pilar untuk `MOCK_DATA` akan disalin persis dari `archive/Testing-Pipeline/benchmark-extraction/Output-JSON/` untuk file RAGAS dan SciLit.
*   **[DEC-02] Data Fisik**: Path PDF di dalam `MOCK_DATA` di-*hardcode* menunjuk relatif ke folder `Literature/` di *root* proyek.
*   **[DEC-03] Instance Baru**: Skrip akan mengeksekusi *cypher query* untuk `CREATE VECTOR INDEX` secara mandiri pada saat inisialisasi agar instance Neo4j yang kosong siap digunakan.
*   **[DEC-04] Full Real Edge Gen**: Eksekusi *LLM reasoning* (Gate 3 dan pembuatan kalimat relasi) tidak di-*bypass*. Semua dipanggil menggunakan DashScope API.
*   **[DEC-05] Output Format**: Laporan terminal direpresentasikan dalam bentuk dua matriks Markdown (`performance_matrix_node.md` dan `performance_matrix_edge.md`) yang disimpan di lokasi tersendiri.

## Alur Diagram

```mermaid
flowchart TD
    Start[Mulai Skrip Benchmark] --> Setup[Setup Sys.Path & Load .env]
    Setup --> Index[Inisiasi & Setup Neo4j Vector Indexes]
    Index --> Hash[Hitung MD5 Hash Aktual dari File PDF]
    Hash --> Embed[Generate 5 Vectors per Dokumen via OpenAI]
    Embed --> InjectNode[Injeksi Node ke Neo4j]
    
    InjectNode --> Check{Semua Masuk?}
    Check -- Belum --> Embed
    Check -- Sudah --> Retrieval[Semantic Retrieval: find_similar_nodes dari Jurnal A ke B]
    
    Retrieval --> Thresh{Lolos Threshold?}
    Thresh -- Tidak --> End[Selesai - Catat Log]
    Thresh -- Ya --> Bundle[Bundle Candidates & Coherence Check]
    
    Bundle --> Coh{Lolos Coherence?}
    Coh -- Tidak --> End
    Coh -- Ya --> LLMDomain[LLM Domain Compatibility Gate]
    
    LLMDomain --> Dom{Lolos Domain?}
    Dom -- Tidak --> End
    Dom -- Ya --> LLMReason[Generate Edge Reasoning via DashScope]
    
    LLMReason --> EvalReason{Reasoning Valid?}
    EvalReason -- Tidak --> End
    EvalReason -- Ya --> InjectEdge[Batch Insert Edge ke Neo4j]
    
    InjectEdge --> EndBenchmark[Simpan ke Performance Matrix Node & Edge]
    End --> EndBenchmark
```

## Struktur Folder (Tree)
Sesuai dengan arahan terbaru, struktur folder dipisah secara spesifik:

```text
backend-sre/
├── archive/
│   └── benchmark-graph/
│       ├── Perform-Matrix/
│       │   ├── performance_matrix_node.md   <-- (Tabel Metrik Node)
│       │   └── performance_matrix_edge.md   <-- (Tabel Metrik Edge)
│       └── Log-Error/
│           └── graph_errors.log             <-- (Log Error Skrip)
├── Markdown/
│   └── Testing-Pipeline/
│       └── benchmark-graph/
│           ├── Plan/
│           │   └── Graph_Benchmark_Plan.md  <-- (Anda berada di sini)
│           └── Report/
│               └── Execution_Report.md      <-- (Log eksekusi akan disalin ke sini)
├── scripts/
│   └── Testing-Pipeline/
│       └── benchmark_graph.py               <-- (Skrip uji utama)
└── app/
    └── services/
        └── ingestion.py                     <-- (Target uji, tidak dimodifikasi)
```

## Asumsi & Batasan
1.  **Asumsi Lingkungan**: File `.env` yang berada di *root* memiliki konfigurasi `NEO4J_URI`, `NEO4J_USERNAME`, `NEO4J_PASSWORD`, `OPENAI_API_KEY`, dan `DASHSCOPE_API_KEY` yang valid.
2.  **Asumsi Integritas File**: Kedua file PDF "RAGAS" dan "SciLit" benar-benar eksis di folder `Literature/`.
3.  **Batasan Kode Utama**: Dilarang mengedit `app/services/ingestion.py`.
4.  **Batasan Biaya**: Eksekusi memakan biaya token riil dari OpenAI dan DashScope.
5.  **Batasan Output Edge**: Relasi Neo4j mungkin tidak terbentuk jika teks ekstraksi antara RAGAS dan SciLit secara semantik tidak cukup mirip untuk melewati `PILLAR_THRESHOLD_MATRIX`.

## Konsep Tabel Metriks (Output Markdown)

Karena kompleksitas dari generasi Edge yang melibatkan berlapis-lapis *Gating*, laporan matriks dipecah menjadi dua bagian yang berfokus pada tahapan yang berbeda, dan disimpan di `archive/benchmark-graph/Perform-Matrix/`.

### 1. Matrix Node Generation (`performance_matrix_node.md`)
Berfokus pada pemantauan performa saat mengonversi teks pilar menjadi vektor (OpenAI Embedding) lalu menyimpannya ke dalam database Neo4j.

| Header Kolom | Penjelasan Informasi |
| :--- | :--- |
| `Timestamp` | Waktu eksekusi dalam format `YYYY-MM-DD HH:MM:SS`. |
| `Document` | Nama file dokumen (*truncated*) yang sedang diproses. |
| `Embed Model` | Model yang digunakan untuk menghasilkan vektor (contoh: `text-embedding-3-small`). |
| `Pillars Count` | Jumlah pilar yang berhasil diproses/di-embed dari dokumen tersebut (Maksimal 5: background, methodology, gap, objective, futurework). |
| `Token Input` | Total token dari teks pilar yang dikirim ke API OpenAI untuk diubah menjadi vektor. |
| `Embed Cost ($)` | Estimasi biaya *embedding* berdasarkan total `Token Input` (contoh: $0.020 per 1M token). |
| `Embed Latency` | Waktu tunggu total (detik) untuk memanggil API OpenAI bagi ke-5 pilar. |
| `DB Insert Latency` | Waktu tunggu total (detik) untuk memanggil fungsi `MERGE` Node di Neo4j. |
| `Total Time` | Waktu total (`Embed Latency` + `DB Insert Latency`) yang diperlukan untuk menyelesaikan 1 Node. |
| `Status` | Status akhir dari pembentukan Node (`Success` atau `Failed`). |

**Contoh Format Output:**
```markdown
| Timestamp | Document | Embed Model | Pillars Count | Token Input | Embed Cost ($) | Embed Latency | DB Insert Latency | Total Time | Status |
| :--- | :--- | :--- | :---: | :---: | :---: | :---: | :---: | :---: | :--- |
| 2026-05-14 19:00:00 | RAGAS_Auto... | text-embed... | 5 | 850 | $0.000017 | 1.80s | 0.40s | 2.20s | Success |
```

### 2. Matrix Edge Generation (`performance_matrix_edge.md`)
Berfokus pada pemantauan performa pencarian relasi dan generasi kalimat perantara (Reasoning) yang dikendalikan oleh LLM.

| Header Kolom | Penjelasan Informasi |
| :--- | :--- |
| `Timestamp` | Waktu saat iterasi pembentukan tipe Edge ini dimulai. |
| `Source Doc` | Nama dokumen sumber yang menjadi titik awal panah relasi (A -> B). |
| `Target Doc` | Nama dokumen target yang menjadi titik akhir panah relasi (A -> B). |
| `Edge Type` | Jenis pilar kesamaan akademik (Contoh: `BACKGROUND`, `METHODOLOGY`, `GAP`). |
| `Token In` | Jumlah token *prompt* yang dikirim ke LLM (DashScope) untuk mengevaluasi tipe relasi tersebut. |
| `Token Out` | Jumlah token respons (alasan/reasoning) yang dihasilkan oleh LLM (DashScope) untuk tipe relasi tersebut. |
| `Cost ($)` | Estimasi biaya LLM gabungan dari `Token In` dan `Token Out` untuk satu `Edge Type`. |
| `Total Time` | Waktu komputasi gabungan (Retrieval + Gating + LLM Gen + DB Insert) dari proses Edge ini. |
| `Status` | `Success` (Edge terbentuk) atau `Reject` (Gagal di salah satu Gate). |
| `Gating: Retrieval` | Status lolos/gagal pada tahap pencarian vektor Neo4j beserta skor Cosine Similarity (misal: `Pass (0.85)`). |
| `Gating: Coherence` | Status lolos/gagal pada validasi struktur pilar (misal: `Pass (3 Match)` atau `Fail (Single Match)`). |
| `Gating: Domain` | Status lolos/gagal dari analisis bidang ilmu via LLM (`Pass` atau `Fail`). |
| `Gating: Reasoning` | Status lolos/gagal dari filter validasi kalimat generik (misal: `Pass` atau `Fail (Generik)`). |

**Contoh Format Output:**
```markdown
| Timestamp | Source Doc | Target Doc | Edge Type | Token In | Token Out | Cost ($) | Total Time | Status | Gating: Retrieval | Gating: Coherence | Gating: Domain | Gating: Reasoning |
| :--- | :--- | :--- | :--- | :---: | :---: | :---: | :---: | :--- | :--- | :--- | :--- | :--- |
| 19:00:05 | RAGAS... | SciLit... | BACKGROUND | 400 | 60 | $0.00005 | 4.80s | Success | Pass (0.85) | Pass (3 Match) | Pass | Pass |
```

## Konsep Prompting
Skrip ini akan memanggil `evaluate_domain_compatibility_with_llm` dan `generate_edge_reasoning` yang berada di `app.services.ingestion.py`. Prompt yang dieksekusi adalah prompt asli (tanpa diubah) yang menuntut format JSON terstruktur untuk mengevaluasi koherensi akademik dan menyusun narasi persimpangan (*intersection*) antar literatur dalam Bahasa Indonesia.

## Langkah Implementasi
1.  Buat file `benchmark_graph.py` di `scripts/Testing-Pipeline/`.
2.  Manipulasi `sys.path` untuk mengakses modul `app` dari root.
3.  Konfigurasi `logging` untuk menyimpan log ke `archive/benchmark-graph/Log-Error/graph_errors.log`.
4.  *Hardcode* struktur `MOCK_DATA` dengan JSON dari RAGAS dan SciLit, beserta *path* PDF-nya yang mengarah ke `Literature/`.
5.  Eksekusi cypher `CREATE VECTOR INDEX` secara *hardcode* sebelum proses dimulai.
6.  *Loop* `MOCK_DATA`: Hitung MD5 dari PDF, buat *embedding* (OpenAI), dan suntikkan Node (Neo4j). Kumpulkan latensi dan biaya, lalu simpan ke `archive/benchmark-graph/Perform-Matrix/performance_matrix_node.md`.
7.  Ambil `node_id` RAGAS, cari kemiripan (*similarity*) dengan SciLit.
8.  Jika ada yang mirip, jalankan gerbang koherensi dan kompatibilitas domain.
9.  Jika lolos, panggil LLM untuk merangkai alasan (*reasoning*). 
10. Sisipkan Relasi (*Edge*) jika validasi alasan lolos.
11. Rekap status setiap gerbang per pilar (sebagai *Edge Type*), hitung biaya LLM, lalu cetak hasilnya ke `archive/benchmark-graph/Perform-Matrix/performance_matrix_edge.md`.
12. Terakhir, salin ouput terminal eksekusi tersebut ke dalam file report di `Markdown/Testing-Pipeline/benchmark-graph/Report/Execution_Report.md`.

## Tabel Eksekusi Task

| [ ] | Fase | Task | Detail Task | Deskripsi | Acceptance Criteria |
|:---:|:---|:---|:---|:---|:---|
| [x] | Phase 1 | Setup Direktori & Logging | Buat direktori dan file `benchmark_graph.py`. | Setup *path injection*, load `.env`, dan konfigurasi file logger ke `archive/benchmark-graph/Log-Error/graph_errors.log`. | Eksekusi file sukses, modul `app` dapat di-import, dan error tertulis ke log file yang benar. |
| [x] | Phase 1 | Inisialisasi Database | Jalankan pembuatan Indeks Neo4j. | Eksekusi cypher `CREATE VECTOR INDEX` di awal script agar *instance* kosong dapat dikueri. | Indeks `background_emb`, dst tercipta tanpa error. |
| [x] | Phase 2 | Injeksi MOCK_DATA | Susun variabel `MOCK_DATA`. | Salin JSON ekstraksi RAGAS dan SciLit ke dalam skrip, lalu tautkan dengan *path* `Literature/*.pdf`. | Variabel memuat metadata dan pilar asli dari *Output-JSON*. |
| [x] | Phase 2 | Hashing PDF Fisik | Hitung MD5 dari PDF. | Panggil `get_md5_hash` pada file PDF asli sebelum menginjeksi Node. | Output hash valid dan tidak menimbulkan error. |
| [x] | Phase 3 | Injeksi Node & Embedding | *Looping* pembuatan Node. | Panggil `embed_text()` (OpenAI) 5 kali, lalu `create_literature_node()`. Lacak latensi dan token *in*. | Node tersimpan. Metrik latensi, token, dan biaya tercatat di Matrix 1. |
| [x] | Phase 4 | Semantic Retrieval | Evaluasi `find_similar_nodes()`. | Jalankan *retrieval* dari RAGAS ke target potensial. Lacak skor dan status kelolosan *threshold*. | Status *pass/fail* retrieval per pilar dapat disiapkan untuk dicatat. |
| [x] | Phase 5 | Logic Gating | Cek Coherence & Domain. | Kirim kandidat ke `validate_semantic_coherence` dan `evaluate_domain_compatibility_with_llm`. Lacak latensi dan token. | Status *pass/fail* coherence dan domain gate disiapkan. |
| [x] | Phase 6 | Edge Reasoning | Bangun `generate_edge_reasoning`. | Panggil API DashScope untuk *reasoning*. Validasi kualitas *reasoning*. Lacak token *in/out* secara akurat. | Menghasilkan JSON alasan. Status *pass/fail* reasoning disiapkan. |
| [x] | Phase 7 | Injeksi Edge | Batch Insert Edge. | Panggil `create_lexicographical_edges_batch`. Lacak latensi. | Edge `SIMILAR_*` muncul di Neo4j. |
| [x] | Phase 8 | Reporting Matrix | Simpan ke 2 File MD. | Format metrik operasi ke dalam `performance_matrix_node.md` dan kompilasi rekam jejak setiap pilar target ke `performance_matrix_edge.md`. | File terbentuk di folder `Perform-Matrix` dengan format persis sesuai spesifikasi kolom. |
| [x] | Phase 9 | Execution Report | Simpan log eksekusi. | Simpan rangkuman eksekusi atau terminal output ke `Markdown/Testing-Pipeline/benchmark-graph/Report/Execution_Report.md`. | Laporan eksekusi tes tersedia dengan rapi. |
