mindnet/docs/05_Development/05_developer_guide.md
Lars 5225090490
All checks were successful
Deploy mindnet to llm-node / deploy (push) Successful in 3s
Dokumentationsaupdate
2025-12-28 10:56:34 +01:00

22 KiB

doc_type audience scope status version context
developer_guide developer workflow, testing, architecture, modules, modularization active 2.9.1 Umfassender Guide für Entwickler: Modularisierte Architektur (WP-14), Two-Pass Ingestion (WP-15b), Modul-Interna, Setup und Git-Workflow.

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).


Inhaltsverzeichnis


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.

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"]
        
        subgraph "Core Packages (WP-14)"
            PkgRet["retrieval/ (Search)"]
            PkgIng["ingestion/ (Import)"]
            PkgGra["graph/ (Logic)"]
            PkgDb["database/ (Infrastr.)"]
            Registry["registry.py (Neutral)"]
        end
    end
    
    subgraph "Infrastructure & Services"
        LLM["Ollama / Cloud (Hybrid)"]
        DB[("Qdrant Vector DB")]
        FS["File System (.md)"]
    end

    User <--> UI
    UI -- "REST Call" --> API
    PkgRet -- "Direct Query" --> PkgDb
    PkgIng -- "Process & Write" --> PkgDb
    PkgDb -- "API" --> DB
    API -- "Inference" --> LLM```

### 2.2 Datenfluss-Muster

#### A. Ingestion (Write)
Vom Markdown zur Vektor-Datenbank.
```mermaid
graph LR
    MD["Markdown File"] --> Pass1["Pass 1: Pre-Scan"]
    Pass1 --> Cache[("LocalBatchCache<br/>(Titles/Summaries)")]
    MD --> Pass2["Pass 2: Processing"]
    Cache -- "Context" --> SmartEdges{"Smart Edge<br/>Validation"}
    SmartEdges --> Embedder("Embedder")
    Embedder --> DB[("Qdrant Points")]

B. Retrieval (Read)

Die hybride Suche für Chat & RAG.

graph LR
    Query(["Query"]) --> Embed("Embedding")
    Embed --> Seed["Seed Search (Vector)"]
    Seed --> Expand{"Graph Expansion"}
    Expand --> Scoring["Scoring Engine (WP-22)"]
    Scoring --> Rank("Final Ranking")
    Rank --> Ctx["LLM Context"]

C. Visualisierung (Graph)

Der optimierte Pfad für das Frontend.

graph LR
    UI["Frontend UI"] --> Service("GraphService")
    Service -- "Direct Read" --> DB[("Qdrant<br/>Edges Collection")]
    DB --> Cyto["Cytoscape<br/>Rendering"]

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

mindnet/
├── app/
│   ├── core/           # Business Logic & Algorithms
│   │   ├── database/    # WP-14: Qdrant Client & Point Mapping
│   │   ├── ingestion/   # WP-14: Pipeline, Multi-Hash, Validation
│   │   ├── retrieval/   # WP-14: Search Orchestrator & Scoring
│   │   ├── graph/       # WP-14: Subgraph-Logik & Weights
│   │   ├── registry.py  # SSOT: Circular Import Fix & Text Cleanup
│   │   └── *.py (Proxy) # Legacy Bridges für Abwärtskompatibilität
│   ├── 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 ist das Herzstück. Es stellt die Logik via REST-API bereit.

Wichtig: Seit WP-14 ist die Core-Logik in spezialisierte Pakete unterteilt:

Core-Pakete (Modularisierung WP-14)

Paket Zweck Wichtige Module
app/core/chunking/ Text-Segmentierung chunking_strategies.py (Sliding/Heading), chunking_processor.py (Orchestrierung)
app/core/database/ Qdrant-Infrastruktur qdrant.py (Client), qdrant_points.py (Point-Mapping)
app/core/graph/ Graph-Logik graph_subgraph.py (Expansion), graph_weights.py (Scoring)
app/core/ingestion/ Import-Pipeline ingestion_processor.py (Two-Pass), ingestion_validation.py (Mistral-safe Parsing)
app/core/parser/ Markdown-Parsing parsing_markdown.py (Frontmatter/Body), parsing_scanner.py (File-Scan)
app/core/retrieval/ Suche & Scoring retriever.py (Orchestrator), retriever_scoring.py (Mathematik)
app/core/registry.py SSOT & Utilities Text-Bereinigung, Circular-Import-Fix

Legacy-Bridges: Die alten Dateien (app/core/retriever.py, app/core/qdrant.py) existieren noch als Proxy-Adapter für Abwärtskompatibilität, delegieren aber an die neuen Pakete.

Layer Datei Status Verantwortung
Entry app/main.py 🟢 Core Entrypoint. Initialisiert FastAPI, CORS, und bindet alle Router ein.
Config app/config.py 🟢 Core Settings. Zentrale Konfiguration (Pydantic). Lädt Env-Vars für Qdrant, LLM und Pfade.
Router app/routers/chat.py 🟢 API Conversation API. Haupt-Endpunkt für Chat. Entscheidet zwischen Interview- und RAG-Modus.
app/routers/ingest.py 🟢 API Write API. Nimmt Markdown entgegen, steuert Ingestion und Discovery-Analyse.
app/routers/query.py 🟢 API Search API. Klassischer Hybrid-Retriever Endpunkt.
app/routers/graph.py 🟢 API Viz API. Liefert Knoten/Kanten für Frontend-Graphen (Cytoscape).
app/routers/tools.py 🟢 API Agent Specs. Liefert JSON-Schemas für die Integration in externe Agenten (Ollama/MCP).
Engine app/core/ingestion.py ⚙️ Core Pipeline Controller. Koordiniert Parsing, Hashing (Change-Detection) und DB-Upserts.
app/core/retriever.py ⚙️ Core Search Engine. Berechnet Scores (Vektor + Graph + Centrality) und baut Erklärungen.
app/core/chunker.py ⚙️ Core Segmentation. Zerlegt Text intelligent. Orchestriert SemanticAnalyzer für Smart Edges.
app/core/parser.py ⚙️ Core I/O. Liest Markdown robust (Encoding-Fallback), trennt Frontmatter/Body.
app/core/derive_edges.py ⚙️ Core Link Extractor. Findet Wikilinks, Callouts und Typed Relations im Text.
app/core/note_payload.py ⚙️ Core Builder. Erzeugt JSON für mindnet_notes. Vererbt Configs (Frontmatter > Type > Default).
app/core/qdrant_points.py ⚙️ Core Object Mapper. Wandelt Payloads in Qdrant PointStructs um. Handhabt UUIDs.
Services app/services/llm_service.py 🧠 AI AI Client. Async Client für Ollama. Verwaltet Concurrency (Semaphore).
app/services/embeddings_client.py 🧠 AI Vector Client. Unified Client für Embeddings (Ollama/Nomic). Ersetzt lokale Modelle.
app/services/discovery.py 🧠 AI Intelligence. "Matrix Logic" für Link-Vorschläge (WP-11).
app/services/semantic_analyzer.py 🧠 AI Filter. KI-Validierung von Kanten im Hintergrund (Background Priority).

4.4 Scripts & Tooling (Die Admin-Toolbox)

Der Ordner scripts/ enthält verifizierte Werkzeuge für den Betrieb.

1. Script-Übersicht

Skript Status Zweck Argumente & Parameter Beispielaufruf
import_markdown.py 🟢 Core Ingestion. Scannt den Vault und importiert Dateien asynchron in Qdrant. Beachtet Hashes. --vault PATH (Quellordner)
--prefix TEXT (Collection Prefix)
--force (Erzwingt Re-Index)
--apply (Schreibt in DB; sonst Dry-Run)
python3 scripts/import_markdown.py --vault ./vault --apply
reset_qdrant.py 🟢 Core DB-Reset. Löscht Collections (wipe) oder leert sie (truncate). Legt Indizes neu an. --mode {wipe,truncate}
--prefix TEXT
--yes (Keine Rückfrage)
--no-indexes (Skip Index-Erstellung)
python3 -m scripts.reset_qdrant --mode wipe --yes
health_check_mindnet.py 🟢 Ops Monitoring. Prüft API-Verfügbarkeit (/query) und Antwortqualität. Standalone (keine Imports). --url URL
--query TEXT
--top-k INT
--strict (Exit-Code 1 bei Warnings)
python3 scripts/health_check_mindnet.py --strict
payload_dryrun.py 🟡 Dev Debugger. Simuliert die JSON-Erstellung (Payloads) ohne DB-Schreibzugriff. Prüft types.yaml. --vault PATH
--note-id ID (Filter)
--with-edges (Zeigt Kanten)
python3 -m scripts.payload_dryrun --vault ./vault --note-id "projekt-alpha"
edges_full_check.py 🟡 Audit Integritäts-Check. Zählt Kanten in der DB und prüft logische Konsistenz (z.B. Chunk-Reihenfolge). Keine (Liest Konfiguration nur aus Umgebungsvariablen .env) python3 -m scripts.edges_full_check
resolve_unresolved_references.py 🔵 Maint Link-Healer. Repariert "tote" Links in der DB nachträglich und erzeugt Backlinks. --prefix TEXT
--limit INT
--apply (Schreibt Änderungen)
python3 -m scripts.resolve_unresolved_references --apply
export_markdown.py Utility Reverse ETL. Exportiert den Datenbank-Inhalt zurück in Markdown-Dateien (Backup/Recovery). --out PATH (Ziel)
--note-id ID
--include-edges {yaml,footer}
--flatten-paths
python3 -m scripts.export_markdown --out ./backup

2. Einsatzszenarien & Bewertung

  • 🟢 Essentiell für den Betrieb (Must-Have):

    • import_markdown.py: Das Arbeitspferd. Ohne dieses Skript kommen keine Daten ins System.
    • reset_qdrant.py: Zwingend notwendig für CI/CD-Pipelines.
    • health_check_mindnet.py: Ideal für Docker-Healthchecks.
  • 🟡 Hilfreich für Entwicklung & Debugging (Should-Have):

    • payload_dryrun.py: Wertvoll, wenn man an der config/types.yaml arbeitet.
    • edges_full_check.py: Wichtiges Diagnose-Tool für den Graphen.
  • 🔵 Wartung & Spezialfälle (Nice-to-Have):

    • resolve_unresolved_references.py: Sinnvoll in einem "Knowledge Garden", wo oft Links auf noch nicht existierende Notizen gesetzt werden ("Red Links"). Dieses Skript "heilt" den Graphen nachträglich.
    • export_markdown.py: Ein Notfall-Tool. Da Mindnet nach dem Prinzip "Filesystem First" arbeitet, ist ein Export aus der DB selten nötig, kann aber bei versehentlichem Löschen von Dateien lebensrettend sein.

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. (Achtung: Erst Importe in main.py entfernen!) 🗑️ Löschen
app/routers/embed_router.py Zombie. Nutzt embeddings.py. 🗑️ Löschen
app/routers/qdrant_router.py Deprecated. Keine Logik, nur CRUD. 🗑️ 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/services/llm_ollama.py Veraltet. Ersetzt durch llm_service.py. 🗑️ Löschen
app/core/type_registry.py Redundant. Logik in app/core/registry.py integriert. 🗑️ Löschen
app/core/ranking.py Redundant. Logik in retrieval/retriever_scoring.py integriert. 🗑️ Löschen

6. Lokales Setup (Development)

Voraussetzungen: Python 3.10+, Docker, Ollama.

Installation:

# 1. Repo & Venv
git clone <repo> 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):

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.

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):
    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):
    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):
    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.
GRAPH_COLORS = {
    "project": "#FF4B4B",
    "risk": "#8B0000" # Neu
}

9. Tests & Debugging

Unit Tests (Pytest):

pytest tests/test_retriever_basic.py
pytest tests/test_chunking.py

Pipeline Tests (Integration):

# 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:

# 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!):

# --yes überspringt die Bestätigung
python3 -m scripts.reset_qdrant --mode wipe --prefix "mindnet_dev" --yes

Graphen reparieren (Red Links auflösen): Nutze dies, wenn Kanten im Graphen ins Leere zeigen (weil die Notiz beim Import noch nicht da war).

python3 -m scripts.resolve_unresolved_references --apply

Einen einzelnen File inspizieren (Parser-Sicht):

python3 tests/inspect_one_note.py --file ./vault/MeinFile.md

Live-Logs sehen:

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.