--- doc_type: developer_guide audience: developer scope: workflow, testing, architecture, modules status: active version: 2.6 context: "Umfassender Guide für Entwickler: Architektur, Modul-Interna (Deep Dive), Setup, Git-Workflow und Erweiterungs-Anleitungen." --- # Mindnet Developer Guide & Workflow **Quellen:** `developer_guide.md`, `dev_workflow.md`, `Architecture_Audit_v2.6` Dieser Guide ist die zentrale technische Referenz für Mindnet v2.6. Er vereint das technische Verständnis der Module mit dem operativen Workflow zwischen Windows (Dev) und Linux (Runtime). --- ## 1. Einführung & Systemüberblick ### Was ist Mindnet? Mindnet ist ein **Hybrides Knowledge Management System**, das klassische Notizen (Markdown) mit KI-gestützter Analyse verbindet. Es kombiniert **RAG** (Retrieval Augmented Generation) mit einer **Graphen-Datenbank** (Qdrant), um Wissen nicht nur semantisch zu finden, sondern auch strukturell zu vernetzen. ### Kern-Philosophie 1. **Filesystem First:** Die Wahrheit liegt immer auf der Festplatte (Markdown-Dateien). Die Datenbank ist ein abgeleiteter Index. 2. **Hybrid Retrieval:** Relevanz entsteht aus Textähnlichkeit (Semantik) + Graphen-Verbindungen (Edges) + Wichtigkeit (Centrality). 3. **Active Intelligence:** Das System wartet nicht nur auf Anfragen, sondern schlägt beim Schreiben proaktiv Verbindungen vor ("Matrix Logic"). 4. **Local Privacy:** Alle KI-Berechnungen (Ollama) laufen lokal. Keine Cloud-Abhängigkeit für Inference. --- ## 2. Architektur ### 2.1 High-Level Übersicht Das System folgt einer strikten Trennung zwischen Frontend (Streamlit) und Backend (FastAPI), wobei bestimmte Performance-Pfade (Graph-Visualisierung) optimiert wurden. ```mermaid graph TD User((User)) subgraph "Frontend Layer (Streamlit)" UI[ui.py Router] ViewChat[Chat View] ViewGraph[Graph View] ViewEditor[Editor View] Logic[Callbacks & State] end subgraph "Backend Layer (FastAPI)" API[main.py] RouterChat[Chat / RAG] RouterIngest[Ingest / Write] CoreRet[Retriever Engine] CoreIngest[Ingestion Pipeline] end subgraph "Infrastructure & Services" LLM[Ollama (Phi3/Nomic)] DB[(Qdrant Vector DB)] FS[File System (.md)] end User <--> UI UI --> API : REST (Chat, Save, Feedback) UI -.-> DB : Direct Read (Graph Viz Performance) API --> LLM : Embeddings & Completion API --> DB : Read/Write API --> FS : Read/Write (Source of Truth) ``` ### 2.2 Datenfluss-Muster 1. **Ingestion (Write):** `Markdown` -> `Parser` -> `Chunker` -> `SemanticAnalyzer (LLM)` -> `Embedder` -> `Qdrant (Points)` 2. **Retrieval (Read):** `Query` -> `Embedding` -> `Hybrid Search (Vector + Graph)` -> `Re-Ranking` -> `LLM Context` 3. **Visualisierung (Graph):** `UI` -> `GraphService` -> `Qdrant (Edges Collection)` -> `Cytoscape` --- ## 3. Physische Architektur Mindnet läuft in einer verteilten Umgebung (Post-WP15 Setup). * **Windows 11 (VS Code):** Entwicklungsumgebung. **Nie** direkt auf `main` arbeiten! * **Beelink (Runtime):** Der Server hostet zwei Instanzen via Systemd: * **PROD:** API (Port 8001) + UI (Port 8501). Home: `~/mindnet`. * **DEV:** API (Port 8002) + UI (Port 8502). Home: `~/mindnet_dev`. * **Gitea (Raspberry Pi):** Versionskontrolle ("Safe"). Speichert den Code. --- ## 4. Projektstruktur & Modul-Referenz (Deep Dive) Das System ist modular aufgebaut. Hier ist die detaillierte Analyse aller Komponenten. ### 4.1 Verzeichnisbaum ```text mindnet/ ├── app/ │ ├── core/ # Business Logic & Algorithms │ ├── routers/ # API Interface (FastAPI) │ ├── services/ # External Integrations (LLM, DB) │ ├── models/ # Pydantic DTOs │ └── frontend/ # UI Logic (Streamlit) ├── config/ # Configuration Files (YAML) ├── scripts/ # CLI Tools (Ops & Maintenance) └── vault/ # Local Content Storage ``` ### 4.2 Frontend Architecture (`app/frontend/`) Das Frontend ist eine Streamlit-App, die sich wie eine Single-Page-Application (SPA) verhält. | Modul | Status | Verantwortung | | :--- | :--- | :--- | | **`ui.py`** | 🟢 Core | **Main Router.** Initialisiert Session-State und entscheidet anhand der Sidebar-Auswahl, welche View gerendert wird. | | **`ui_config.py`** | 🟢 Config | **Constants.** Zentraler Ort für Farben (`GRAPH_COLORS`), API-URLs und Timeouts. Änderungen am Look & Feel passieren hier. | | **`ui_chat.py`** | 🟢 View | **Chat UI.** Rendert Nachrichtenverlauf, Intent-Badges, Quellen-Expanders und Feedback-Buttons. | | **`ui_editor.py`** | 🟢 View | **Editor UI.** Markdown-Editor mit Live-Vorschau. Integriert "Intelligence" (KI-Link-Vorschläge). | | **`ui_graph_cytoscape.py`**| 🟢 View | **Modern Graph.** Interaktiver Graph basierend auf Cytoscape.js (COSE Layout). | | **`ui_graph.py`** | 🟡 Legacy | **Graph UI (Fallback).** Alte Implementierung mittels `streamlit-agraph`. | | **`ui_callbacks.py`** | 🟢 Logic | **State Controller.** Handhabt komplexe State-Übergänge (z.B. Graph -> Editor). | | **`ui_utils.py`** | 🟢 Logic | **Helper.** Enthält den **Healing Parser** (`parse_markdown_draft`), der defektes JSON/YAML von LLMs repariert. | | **`ui_api.py`** | 🟢 Data | **API Client.** Wrapper für Backend REST-Calls. | | **`ui_graph_service.py`** | 🟢 Data | **Performance Hack.** Greift direkt auf Qdrant zu (bypass API), um Graphen schnell zu laden. | #### Frontend Design Patterns (Wichtig!) 1. **Active Inspector Pattern (`ui_graph_cytoscape.py`)** Um Re-Renders im Graphen zu vermeiden, nutzen wir CSS-Klassen. Wird ein Knoten angeklickt, ändert sich nur die CSS-Klasse (`.inspected`), aber die Physik-Simulation startet nicht neu. Das sorgt für ein stabiles UI-Gefühl. 2. **Resurrection Pattern (`ui_editor.py`)** Streamlit neigt dazu, Eingaben bei Re-Runs zu "vergessen". Der Editor synchronisiert seinen Inhalt aggressiv in den `session_state`. * Logik: `if widget_key not in session_state: restore_from_data_key()`. * Ergebnis: Texteingaben überleben Tab-Wechsel. 3. **Filesystem First (`ui_callbacks.py`)** Wenn man im Graphen auf "Bearbeiten" klickt: 1. Versucht das System, die **echte Datei** von der Festplatte zu lesen. 2. Nur wenn das fehlschlägt, wird der Text aus den Datenbank-Chunks rekonstruiert ("Stitching"). Dies verhindert, dass veraltete Datenbank-Stände die echten Dateien überschreiben. --- ### 4.3 Backend Architecture (`app/`) Das Backend stellt die Logik via REST-API bereit. | Modul | Typ | Verantwortung | | :--- | :--- | :--- | | **Core Engine** | | | | `core/ingestion.py` | Engine | **Pipeline Controller.** Koordiniert den 13-Schritte-Import, Parsing, Hash-Check und DB-Upserts. | | `core/retriever.py` | Engine | **Search Engine.** Berechnet Hybrid-Score: `(Semantic * W) + (Edge Bonus * 0.25) + (Centrality * 0.05)`. | | `core/chunker.py` | Engine | **Segmentation.** Zerlegt Text intelligent. Orchestriert `SemanticAnalyzer` für Smart Edges. | | `core/derive_edges.py`| Engine | **Link Extractor.** Findet Wikilinks, Callouts und Typed Relations im Text. | | `core/qdrant_points.py`| Mapper | **Object Mapper.** Wandelt Payloads in Qdrant `PointStruct`s um. | | `core/graph_adapter.py` | Algo | **Graph Logic.** Baut In-Memory Graphen für Re-Ranking und Pfad-Analysen. | | **Router (API)** | | | | `routers/chat.py` | Router | **Hybrid Router.** Entscheidet: RAG-Antwort vs. Interview-Modus. | | `routers/ingest.py` | Router | **Write API.** Nimmt Markdown entgegen, steuert Ingestion und Discovery-Analyse. | | `routers/query.py` | Router | **Search API.** Klassischer Hybrid-Retriever Endpunkt. | | `routers/graph.py` | Router | **Viz API.** Liefert Knoten/Kanten für Frontend. | | **Services** | | | | `services/llm_service.py`| Service | **Traffic Control.** Async Client für Ollama. Nutzt **Semaphore**, um Hintergrund-Jobs (Import) zu drosseln. | | `services/discovery.py`| Service | **Intelligence.** "Matrix Logic" für Link-Vorschläge (WP-11). | | `services/semantic_analyzer.py`| Service | **Filter.** KI-Validierung von Kanten im Hintergrund. | | `services/feedback_service.py`| Service | **Logging.** Schreibt Interaktions-Logs (JSONL). | --- ### 4.4 Scripts & Tooling (Die Admin-Toolbox) Der Ordner `scripts/` enthält verifizierte Werkzeuge für den Betrieb. | Skript | Status | Zweck | Wichtiges Argument | | :--- | :--- | :--- | :--- | | **`import_markdown.py`** | 🟢 Prod | **Master-Sync.** Der zentrale Importer. | `--apply`, `--purge-before-upsert` | | **`reset_qdrant.py`** | ⚠️ Ops | **Wipe.** Löscht Collections für Rebuilds. | `--mode wipe`, `--yes` | | **`export_markdown.py`** | 🟢 Backup| **Backup.** Exportiert DB-Inhalt zurück zu MD. | -- | | **`health_check_mindnet.py`**| 🟢 Ops | **Monitoring.** Prüft ob API/DB laufen. | (Exit Code 0/1) | | **`payload_dryrun.py`** | 🟢 Test | **Audit.** Simuliert Import (Schema Check). | -- | | **`edges_full_check.py`** | 🟢 Test | **Integrity.** Prüft Graph-Logik. | -- | | **`resolve_unresolved.py`**| 🟡 Maint | **Repair.** Versucht, kaputte Links zu heilen. | -- | --- ## 5. Maintenance & "Kill List" Folgende Dateien wurden im Audit v2.6 als veraltet, redundant oder "Zombie-Code" identifiziert und sollten entfernt werden. | Datei | Diagnose | Empfohlene Aktion | | :--- | :--- | :--- | | `app/embed_server.py` | **Zombie.** Alter Standalone-Server. | 🗑️ Löschen | | `app/embeddings.py` | **Zombie.** Veraltete lokale Lib. | 🗑️ Löschen | | `app/core/edges.py` | **Redundant.** Ersetzt durch `derive_edges.py`. | 🗑️ Löschen | | `app/core/ranking.py` | **Redundant.** Logik in `retriever.py` integriert. | 🗑️ Löschen | | `app/core/type_registry.py` | **Redundant.** Logik in `ingestion.py` integriert. | 🗑️ Löschen | | `app/core/env_vars.py` | **Veraltet.** Ersetzt durch `config.py`. | 🗑️ Löschen | | `app/routers/qdrant_router.py`| **Deprecated.** Keine Logik, nur CRUD. | 📂 Verschieben nach `scripts/archive/` | --- ## 6. Lokales Setup (Development) **Voraussetzungen:** Python 3.10+, Docker, Ollama. **Installation:** ```bash # 1. Repo & Venv git clone mindnet cd mindnet python3 -m venv .venv source .venv/bin/activate # 2. Dependencies pip install -r requirements.txt # 3. Ollama (Nomic ist Pflicht!) ollama pull phi3:mini ollama pull nomic-embed-text ``` **Konfiguration (`.env`):** ```ini QDRANT_URL="http://localhost:6333" MINDNET_OLLAMA_URL="http://localhost:11434" MINDNET_LLM_MODEL="phi3:mini" MINDNET_EMBEDDING_MODEL="nomic-embed-text" COLLECTION_PREFIX="mindnet_dev" VECTOR_DIM=768 MINDNET_LLM_BACKGROUND_LIMIT=2 MINDNET_API_URL="http://localhost:8002" ``` --- ## 7. Der Entwicklungs-Zyklus (Workflow) ### Phase 1: Windows (Code) 1. **Basis aktualisieren:** `git checkout main && git pull`. 2. **Branch erstellen:** `git checkout -b feature/mein-feature`. 3. **Coden & Committen.** 4. **Push:** `git push origin feature/mein-feature`. ### Phase 2: Beelink (Test / Dev) Hier prüfst du, ob dein Code auf Linux läuft. 1. **Einloggen:** `ssh user@beelink`. 2. **Ordner:** `cd ~/mindnet_dev`. 3. **Code holen:** `git fetch && git checkout feature/mein-feature && git pull`. 4. **Dependencies:** `pip install -r requirements.txt`. 5. **Restart:** `sudo systemctl restart mindnet-dev`. 6. **Validierung (Smoke Tests):** * **Last-Test:** Starte `python3 -m scripts.import_markdown ...` im Terminal und chatte gleichzeitig im UI (Port 8502). * **API Check:** `curl -X POST "http://localhost:8002/ingest/analyze" ...` ### Phase 3: Release & Deployment (Prod) Wenn alles getestet ist: 1. **Gitea:** Pull Request erstellen und mergen. 2. **Deploy auf Prod (Beelink):** ```bash cd ~/mindnet git pull origin main # Sicherstellen, dass Prod-Dependencies aktuell sind source .venv/bin/activate pip install -r requirements.txt ollama pull nomic-embed-text # Falls neue Modelle nötig sind # Restart sudo systemctl restart mindnet-prod sudo systemctl restart mindnet-ui-prod ``` 3. **Cleanup:** Branch löschen (lokal und remote). --- ## 8. Erweiterungs-Guide: "Teach-the-AI" Mindnet lernt nicht durch Training (Fine-Tuning), sondern durch **Konfiguration** und **Vernetzung**. ### Workflow A: Neuen Typ implementieren (z. B. `type: risk`) 1. **Physik (`config/types.yaml`):** ```yaml risk: chunk_profile: sliding_short retriever_weight: 0.90 # Sehr wichtig edge_defaults: ["blocks"] # Automatische Kante detection_keywords: ["gefahr", "risiko"] ``` 2. **Strategie (`config/decision_engine.yaml`):** ```yaml DECISION: inject_types: ["value", "risk"] # <--- "risk" hinzufügen ``` *Ergebnis:* Wenn der Intent `DECISION` erkannt wird, sucht das System nun auch aktiv nach Risiken. ### Workflow B: Graph-Farben ändern 1. Öffne `app/frontend/ui_config.py`. 2. Bearbeite das Dictionary `GRAPH_COLORS`. ```python GRAPH_COLORS = { "project": "#FF4B4B", "risk": "#8B0000" # Neu } ``` --- ## 9. Tests & Debugging **Unit Tests (Pytest):** ```bash pytest tests/test_retriever_basic.py pytest tests/test_chunking.py ``` **Pipeline Tests (Integration):** ```bash # JSON-Schema prüfen python3 -m scripts.payload_dryrun --vault ./test_vault # Graph-Integrität prüfen python3 -m scripts.edges_full_check ``` **E2E Smoke Tests:** ```bash # Decision Engine python tests/test_wp06_decision.py -p 8002 -e DECISION -q "Soll ich X tun?" # Feedback python tests/test_feedback_smoke.py --url http://localhost:8002/query ``` --- ## 10. Troubleshooting & One-Liners **DB komplett zurücksetzen (Vorsicht!):** ```bash # --yes überspringt die Bestätigung python3 -m scripts.reset_qdrant --mode wipe --prefix "mindnet_dev" --yes ``` **Einen einzelnen File inspizieren (Parser-Sicht):** ```bash python3 tests/inspect_one_note.py --file ./vault/MeinFile.md ``` **Live-Logs sehen:** ```bash journalctl -u mindnet-dev -f journalctl -u mindnet-ui-dev -f ``` **"UnicodeDecodeError in .env":** * **Ursache:** Umlaute oder Sonderzeichen in der `.env`. * **Lösung:** Datei bereinigen (nur ASCII) und sicherstellen, dass UTF-8 ohne BOM genutzt wird. **"Read timed out" im Frontend:** * **Ursache:** Smart Edges brauchen länger als 60s. * **Lösung:** `MINDNET_API_TIMEOUT=300.0` in `.env`.