Tutorial Build GraphRAG Lokal: Python, Neo4j & Ollama Data Kompleks
Poin Kunci Artikel Ini:
- LLM menerima pertanyaan pengguna dan mengompilasi menjadi Cypher statement:
- Query dieksekusi langsung pada engine Neo4j.
- Data relasional mentah hasil query dikembalikan ke LLM sebagai konteks eksplisit.
Latar Belakang: Keterbatasan Vektor RAG pada Data Relasional
Retrieval-Augmented Generation (RAG) vektor standar mengandalkan representasi matematika berbasis dense embeddings. Teks dipecah menjadi potongan independen (chunks), dikonversi menjadi matrik numerik, lalu disimpan di database vektor. Saat pencarian berjalan, sistem menghitung kemiripan kosinus (cosine similarity) antara query pengguna dan potongan dokumen. Pendekatan ini efisien untuk pencarian dokumen tunggal, namun gagal total saat menangani struktur data relasional terdistribusi.
Masalah utama RAG vektor terletak pada hilangnya konteks terstruktur saat eksekusi multi-hop reasoning. Pemotongan teks (chunking) memisahkan entitas terikat ke dalam potongan dokumen terpisah. Vektor RAG mengambil dokumen berdasarkan kedekatan semantik query, bukan keterhubungan logika antar entitas. Jika relasi entitas terpisah sejauh dua atau tiga tingkat dokumen, pencarian berbasis vektor hanya mengembalikan potongan teks acak tanpa dapat menghubungkan keterkaitannya.
Contoh Kegagalan Vektor RAG:
[Dokumen A]
"PT Tech Utama akuisisi 100% saham PT Data Nusantara."
[Dokumen B]
"Budi Santoso jabat CEO PT Data Nusantara dan desain arsitektur NusaMind."
[Dokumen C]
"Sistem NusaMind alami insiden kerentanan kritis pada modul API Gateway."
Query: "Apa dampak risiko teknis bagi PT Tech Utama dari entitas anak perusahaannya?"
Hasil Vektor RAG: Mengembalikan Dokumen A karena kemiripan nama perusahaan,
namun gagal menghubungkan Dokumen B dan C. LLM tidak mendapat konteks NusaMind.
GraphRAG menyelesaikan masalah ini dengan mengombinasikan kekuatan Knowledge Graph dan Vector Search. Entitas diekstrak sebagai titik (Nodes) dan hubungan diekstrak sebagai garis (Edges). Struktur Property Graph ini mempertahankan hierarki, kausalitas, dan dependensi antar entitas, memungkinkan pengelusuran rantai relasi secara presisi.
Arsitektur Sistem GraphRAG Lokal
Sistem ini dirancang berjalan penuh di infrastruktur lokal tanpa dependensi API eksternal. Kerahasiaan data terjamin, latensi jaringan minimal, dan tanpa biaya token LLM cloud.
Komponen Utama Arsitektur:
- Python 3.10+: Runtime eksekusi utama pipeline ekstraksi data dan skrip orkestrasi.
- Neo4j Database (v5.18+): Database graph untuk menyimpan nodes, edges, properti entitas, serta mendukung bahasa query Cypher.
- Ollama Runtime: Engine pengjalan LLM lokal (menggunakan model
llama3:8buntuk inferensi/ekstraksi danmxbai-embed-largeuntuk embedding). - LangChain Framework: Library abstraksi integrasi antara Ollama dan Neo4j via modul
langchain-experimentaldanlangchain-ollama.
Persiapan Environment: Neo4j Docker & Ollama
Setup infrastruktur memerlukan alokasi Docker container untuk Neo4j dan instalasi model Ollama via terminal.
1. Jalankan Engine Database Neo4j via Docker
Eksekusi perintah berikut untuk mengunduh dan menjalankan Neo4j Community Edition yang dilengkapi plugin APOC (Awesome Procedures on Cypher):
docker run -d \
--name neo4j-graphrag \
-p 7474:7474 -p 7687:7687 \
-e NEO4J_AUTH=neo4j/password123 \
-e NEO4J_PLUGINS=\'["apoc", "graph-data-science"]\' \
-e NEO4J_dbms_memory_heap_initial__size=512m \
-e NEO4J_dbms_memory_heap_max__size=2G \
neo4j:5.18.0Verifikasi status container via browser di http://localhost:7474. Login menggunakan protokol Bolt (bolt://localhost:7687), username neo4j, dan password password123.
2. Setup Model LLM dan Embedding pada Ollama
# Unduh model LLM untuk ekstraksi entitas dan generasi query Cypher
ollama pull llama3:8b
# Unduh model embedding untuk pencarian berbasis vektor pada node
ollama pull mxbai-embed-large3. Instalasi Dependency Python
pip install langchain langchain-community langchain-experimental langchain-ollama neo4jEkstraksi Knowledge Graph dengan Python & Ollama
Proses konversi teks unstruktur menjadi Knowledge Graph terstruktur dilakukan melalui LLM parsing. Kita tentukan skema eksplisit agar node dan edge yang dihasilkan tidak acak.
from langchain_community.graphs import Neo4jGraph
from langchain_experimental.graph_transformers import LLMGraphTransformer
from langchain_ollama import ChatOllama
from langchain_core.documents import Document
# 1. Inisialisasi Koneksi Neo4j Database
graph = Neo4jGraph(
url="bolt://localhost:7687",
username="neo4j",
password="password123"
)
# 2. Inisialisasi LLM Lokal Ollama
llm = ChatOllama(model="llama3:8b", temperature=0)
# 3. Definisikan Transformer Graph dengan Pembatasan Skema Entitas
allowed_nodes = ["Company", "Person", "System", "Vulnerability"]
allowed_relationships = ["ACQUIRED", "MANAGED_BY", "DEVELOPED", "HAS_VULNERABILITY"]
llm_transformer = LLMGraphTransformer(
llm=llm,
allowed_nodes=allowed_nodes,
allowed_relationships=allowed_relationships
)
# 4. Input Teks Data Kompleks
raw_text = """
PT Tech Utama mengakuisisi PT Data Nusantara pada tahun 2022.
PT Data Nusantara dipimpin oleh Budi Santoso yang menjabat sebagai CEO.
Budi Santoso merancang platform AI bernama NusaMind.
NusaMind mengalami kerentanan keamanan pada komponen API Gateway.
"""
documents = [Document(page_content=raw_text)]
# 5. Ekstraksi Dokumen ke Node dan Edge
graph_documents = llm_transformer.convert_to_graph_documents(documents)
# 6. Simpan Dokumen Graph ke Neo4j (Otomatis MERGE Node & Relasi)
graph.add_graph_documents(graph_documents)
print("Ingestion Knowledge Graph ke Neo4j berhasil.")Implementasi Pipeline Retrieval GraphCypherQAChain
Setelah Knowledge Graph terbentuk di Neo4j, sistem memerlukan pipeline untuk mengubah pertanyaan bahasa alami pengurus menjadi statement query Cypher secara rasional.
from langchain.chains import GraphCypherQAChain
from langchain_ollama import ChatOllama
from langchain_community.graphs import Neo4jGraph
from langchain.prompts import PromptTemplate
# Inisialisasi Database
graph = Neo4jGraph(
url="bolt://localhost:7687",
username="neo4j",
password="password123"
)
# Refresh Schema Graph agar LLM mengenali struktur data terbaru
graph.refresh_schema()
llm = ChatOllama(model="llama3:8b", temperature=0)
# Template Prompt Khusus Penggerak Cypher
CYPHER_GENERATION_TEMPLATE = """
Task: Generate Cypher statement to query a Neo4j graph database.
Instructions:
Use only the provided relationship types and properties in the schema.
Do not use any other relationship types or properties that are not mentioned.
Schema:
{schema}
Note: Do not include any explanations or text pre/post the cypher query.
String Match Rules:
- Entity names are case-sensitive. Use lower() function if needed.
Question: {question}
Cypher Query:
"""
CYPHER_PROMPT = PromptTemplate(
input_variables=["schema", "question"],
template=CYPHER_GENERATION_TEMPLATE
)
# Inisialisasi QA Chain
chain = GraphCypherQAChain.from_llm(
llm=llm,
graph=graph,
verbose=True,
cypher_prompt=CYPHER_PROMPT,
allow_dangerous_requests=True
)
# Eksekusi Pertanyaan Multi-Hop Reasoning
query = "Apa nama sistem yang dikembangkan oleh CEO anak perusahaan PT Tech Utama?"
response = chain.invoke({"query": query})
print("
Hasil Jawaban GraphRAG:")
print(response["result"])
Mekanisme Internal Text-to-Cypher:
- LLM membaca skema database Neo4j: Node Label
(Company),(Person),(System)dan Relasi[:ACQUIRED],[:MANAGED_BY],[:DEVELOPED]. - LLM menerima pertanyaan pengguna dan mengompilasi menjadi Cypher statement:
MATCH (c:Company {id: 'PT Tech Utama'})-[:ACQUIRED]->(sub:Company)
MATCH (sub)<-[:MANAGED_BY]-(p:Person)-[:DEVELOPED]->(sys:System)
RETURN sys.id AS SystemName- Query dieksekusi langsung pada engine Neo4j.
- Data relasional mentah hasil query dikembalikan ke LLM sebagai konteks eksplisit.
- LLM menyusun narasi final yang akurat berdasarkan jalur data graph.
Teknik Optimasi Graph Traversal dan Token Context Window
Masalah utama GraphRAG adalah graph explosion. Ketika node memiliki relasi tinggi (hub node), pencarian traversal tanpa batas mengembalikan ribuan data turunan yang melebihi batas context window LLM.
1. Pembatasan Hop Traversal (Depth Limiting)
Gunakan batas rentang relasi pada query Cypher untuk mencegah pengelusuran tak terbatas.
MATCH (n:Company {id: 'PT Tech Utama'})-[r:*1..2]-(m)
RETURN n, r, m LIMIT 302. Filtering Node Berdasarkan Algoritma Centrality
Gunakan plugin Neo4j Graph Data Science (GDS) untuk menghitung skor PageRank entitas. Masukkan hanya node berpola dominan ke dalam konteks prompt.
CALL gds.pageRank.stream({
nodeProjection: '*',
relationshipProjection: '*'
})
YIELD nodeId, score
RETURN gds.util.asNode(nodeId).id AS Node, score
ORDER BY score DESC LIMIT 103. Hybrid Retrieval: Integrasi Vector Index pada Graph Node
Buat index vektor langsung di dalam database Neo4j untuk mengombinasikan pencarian kemiripan teks cepat dan traversal relasi terstruktur.
// Buat Vector Index pada properti deskripsi Node
CREATE VECTOR INDEX entity_embeddings IF NOT EXISTS
FOR (n:System) ON (n.description)
OPTIONS {indexConfig: {
`vector.dimensions`: 1024,
`vector.similarity_function`: 'cosine'
}};Checklist Implementasi & Matrix Perbandingan
Checklist Validasi Produksi:
- [x] Docker Container Neo4j aktif, port 7474 & 7687 dapat diakses.
- [x] Plugin APOC dan GDS terverifikasi aktif pada Neo4j instance.
- [x] Model Ollama
llama3:8bdanmxbai-embed-largeberjalan di sistem lokal. - [x] Schema entitas terdefinisi ketat pada
LLMGraphTransformeruntuk cegah perkembangbiakan node liar. - [x] GraphCypherQAChain membatasi hak akses perintah destruktif (
DELETE,DETACH,DROP).
Tabel Matrix Skenario: Vector RAG vs GraphRAG vs Hybrid RAG
| Kriteria Evaluasi | Vector RAG | GraphRAG | Hybrid RAG (Vector + Graph) |
|---|---|---|---|
| Format Input Utama | Teks Bebas / PDF Unstructured | Data Relasional Terstruktur | Teks Unstructured & Graph Relasional |
| Multi-hop Reasoning | Sangat Lemah (Terpisah Per Chunk) | Sangat Kuat (Konektivitas Edge) | Sangat Kuat (Gabungan Semantic & Path) |
| Latensi Ingestion Data | Sangat Cepat | Lambat (Perlu Parsing LLM) | Sedang hingga Lambat |
| Presisi Kausalitas | Rendah (Potensi Halusinasi) | Tinggi (Terikat Jalur Graph) | Sangat Tinggi |
| Konsumsi Memory/Token | Rendah | Tinggi jika Traversal Luas | Tergantung Batas Filtering Index |
Kesimpulan
Penggabungan Python, Neo4j, dan Ollama menghasilkan stack RAG terisolasi penuh tanpa risiko kebocoran data enterprise. GraphRAG memperbaiki kelemahan fatal RAG berbasis vektor pada struktur data relasional terkompleks. Penerapan skema eksplisit, pembatasan traversal Cypher, dan integrasi hybrid vector-graph adalah kunci utama menjaga inferensi RAG lokal tetap presisi, efisien, dan deterministik.


