# 08 — GraphRAG: Structural Knowledge & Relations > ⚠️ **Open decision (see [11-open-questions](./11-open-questions.md))**: this document describes the design with **Neo4j**. The earlier deployment draft referenced **Ontotext GraphDB** (SPARQL). Pick one before Phase 3.4. ## GraphRAG für Nexa — Strukturelles Wissen & Beziehungen ## 🧠 Zwei-Säulen-Memory-Architektur Nexa nutzt zwei komplementäre Speicher für vollständiges Verständnis: ### Säule 1: Qdrant (Vector DB) - Semantische Ähnlichkeit - **Frage**: "Was ist ähnlich, was ist relevant?" - **Speichert**: Embeddings von Memos, Obsidian-Notes, E-Mail-Digests - **Suche**: Cosine Similarity über 1536-dimensionale Vektoren - **Antwort**: Top-k semantisch ähnliche Dokumente (RAG) **Beispiel:** ``` Frage: "Wie war die JWT-Implementation in unserem letzten Projekt?" → Qdrant findet: 10 ähnliche Snippets → Prompt-Context ``` ### Säule 2: Neo4j (Graph DB) - Strukturelle Beziehungen - **Frage**: "Wer ist beteiligt? Was hängt davon ab? Wie ist es organisiert?" - **Speichert**: - **Knoten (Nodes)**: Projects, Tasks, People, Technologies, Dates - **Kanten (Relationships)**: `USES`, `OWNS`, `DEPENDS_ON`, `MENTIONS`, `CREATED_BY` - **Suche**: Cypher-Queries über Netzwerk-Topologie - **Antwort**: Pfade, zentrale Knoten, Abhängigkeitsanalyse **Beispiel:** ```cypher MATCH (tech:Technology)-[USES*]->*(service:Service), (tech)-[:MENTIONED_IN]->(task:Task) WHERE tech.name = "JWT" AND task.status = "DONE" RETURN tech, service, task ``` --- ## 📊 Neo4j Schema für Nexa ### Node-Typen ```cypher (Project {name, startDate, status, priority}) (Task {title, description, status, urgency: 1-5, context: "work"|"personal"}) (Person {name, role, email}) (Technology {name, category: "framework"|"language"|"tool"}) (Topic {name, domain}) (File {path, type, lastModified}) (Note {id, content_hash, created_at}) ``` ### Relationship-Typen | Beziehung | Von | Zu | Beschreibung | |-----------|-----|-----------|-------------| | `OWNS` | Person | Task/Project | Wer ist verantwortlich | | `USES` | Task/Project | Technology | Welche Tech wird verwendet | | `DEPENDS_ON` | Task/Project | Task/Project | Hängt davon ab | | `CREATED_BY` | Note | Person | Autor einer Notiz | | `MENTIONS` | Note/Task | Topic/Technology | Verweist auf | | `RELATED_TO` | Task | Task | Zusammenhängend | | `CHILD_OF` | Task | Project | Task gehört zu Project | | `SCHEDULED_FOR` | Task | Date | Zeitliche Zuordnung | --- ## 🔄 Synchronisierungs-Flows ### 1. **Memos → Neo4j** (automatisch beim Erstellen) Wenn ein Memo mit `- [ ]` erstellt wird: ``` Memo-Content: "Muss JWT-Middleware für Auth-Service refaktorieren" ↓ SAIA extrahiert Entitäten: - Technologie: "JWT-Middleware", "Auth-Service" - Kontext: "work" - Urgenz: 3 ↓ Erstelle in Neo4j: - Task node (title="JWT-Middleware refaktorieren") - Technology nodes: JWT, Auth-Service - Relationships: Task -[USES]-> JWT, Task -[USES]-> Auth-Service - Task -[CREATED_BY]-> Me (Person node) ``` ### 2. **Obsidian → Neo4j** (#nexa:sync-obsidian) Beim Sync von Obsidian-Vault: ``` File: obsidian/projects/nexa-deployment.md ↓ Header Struktur wird zu Graph: - Project "Nexa Deployment" - Technologies: Docker, n8n, Nextcloud - Dependencies: "requires infrastructure setup" ↓ Erstelle: - Project nodes mit Metadata - Hierarchie: Project -[CONTAINS]-> Task -[USES]-> Technology ``` ### 3. **Nextcloud Tasks → Neo4j** (bidirektional) Wenn Task in Nextcloud erstellt/gelöcht: ``` Nextcloud Task: "Review JWT implementation" (in Work-List) ↓ n8n Trigger erkennt Änderung ↓ Update Neo4j: - Task node status = "active" - Task -[DEPENDS_ON]-> related Task (falls Beziehung existiert) ``` --- ## 🤖 GraphRAG Queries - Praktische Anwendungen ### Query 1: "Zeige alle offenen Tasks, die JWT betreffen" ```cypher MATCH (tech:Technology {name:"JWT"}), (tech)-[:MENTIONED_IN|USES]-(task:Task), (task)-[:CHILD_OF]->(project:Project) WHERE task.status IN ["NEEDS-ACTION", "IN-PROGRESS"] RETURN project.name, task.title, task.urgency ORDER BY task.urgency DESC ``` ### Query 2: "Von welchen Tasks/Projects hängt Auth-Service ab?" ```cypher MATCH path = (dependent)-[:DEPENDS_ON*]->(service:Technology {name:"Auth-Service"}) RETURN [x IN nodes(path) | x.name], length(path) ORDER BY length(path) ASC ``` ### Query 3: "Wer arbeitet an diesem Projekt und auf welchen Technologien?" ```cypher MATCH (person:Person)-[:OWNS]->(task:Task)-[:CHILD_OF]->(project:Project {name:"Nexa"}), (task)-[:USES]->(tech:Technology) RETURN person.name, collect(task.title), collect(tech.name) ``` ### Query 4: "Was ist seit gestern neu an Technologien/Themen gelernt?" ```cypher MATCH (note:Note)-[:MENTIONS]->(topic:Topic) WHERE note.created_at > datetime.now() - duration('P1D') RETURN DISTINCT topic.name, count(note) as mentions ORDER BY mentions DESC ``` --- ## 🔗 GraphRAG-Enhanced Answer Generation Wenn Nutzer `#nexa:ask` fragt: ``` #nexa:ask Wie stehen die JWT-Tasks zur Deadline? ↓ ┌─────────────┴──────────────┐ ↓ ↓ [Qdrant] [Neo4j] Semantic Structural Search Search ↓ ↓ Top-3 Notes (JWT)-[DEPENDS_ON] mit ähnlichem → Connected Tasks Kontext → Critical Path ↓ ↓ Combine: Merge + Rank ↓ System Prompt (SAIA): "Basierend auf diesem Wissen und diesen Abhängigkeiten, beantworte:" ↓ Response mit: - Semantisch relevanter Information (Qdrant) - Strukturellem Kontext (Neo4j) - Abhängigkeitsanalyse ``` --- ## 🛠️ n8n Integration (Phase 3) ### Workflow: Graph-Sync Trigger ``` [Memos Webhook] ↓ [Parse Content] ↓ [SAIA: Extract Entities] ├→ Tasks, Projects, Technologies, People └→ Relationships (uses, depends_on, mentions) ↓ [Neo4j: Create/Update Nodes & Relationships] ↓ [Index in Qdrant Metadata: Add graph_node_id] ``` ### Workflow: Question Router ``` [#nexa:ask Query] ↓ [Parallel Search] ├→ [Qdrant: Vector Similarity] ├→ [Neo4j: Graph Query (auto-generated Cypher)] └→ [Rank & Merge Results] ↓ [SAIA: Generate Answer with Context] ``` --- ## 📋 Commands für Graph-Management ### #nexa:graph-status Zeigt Statistiken der Graph-DB ``` #nexa:graph-status ``` Response: ``` 📊 Neo4j Graph Status: - Nodes: 342 (Tasks: 145, Projects: 12, Technologies: 52, Notes: 133) - Relationships: 1,247 - Density: 0.34 - Most Connected: "JWT-Middleware" (27 connections) ``` ### #nexa:graph-trace [entity] Zeigt alle Verbindungen für eine Entität ``` #nexa:graph-trace JWT-Middleware ``` ### #nexa:graph-rebuild Rekonstruiert Graph aus Obsidian + Memos (einmalig, danach inkrementell) ``` #nexa:graph-rebuild --force ``` --- ## 🚀 Phase 3 Roadmap (Graph Integration) - [ ] **3.1 Neo4j Setup**: Collection, Constraints, Indexes - [ ] **3.2 Graph-Sync Workflow**: Automatische Entity Extraction - [ ] **3.3 GraphRAG Pipeline**: Kombinierte Qdrant + Neo4j Queries - [ ] **3.4 Dependency Tracker**: Warnt vor zirkulären Dependencies - [ ] **3.5 Critical Path Analysis**: Berechnet längsten Weg im Graph --- ## 💡 Warum zwei DBs? | Szenario | Qdrant | Neo4j | Kombi | |----------|--------|-------|-------| | "Welche Note war ähnlich?" | ✅ Best | ❌ | Qdrant | | "Welche Tasks blockieren diesen Task?" | ❌ | ✅ Best | Neo4j | | "Erkläre mir dieses Projekt umfassend" | ✅ Context | ✅ Structure | **Beide!** | | "Finde alle JWT-bezogenen offenen Work" | ✅ Semantic | ✅ Crisp | **Beide!** | Kombiniert: **Vollständiges Verständnis** statt nur Suchindex oder nur Struktur.