# Mindnet v2.4 – Developer Guide **Datei:** `docs/mindnet_developer_guide_v2.6.md` **Stand:** 2025-12-12 **Status:** **FINAL** (Inkl. Async Core, Nomic, Traffic Control & Frontend State) **Quellen:** `mindnet_technical_architecture.md`, `Handbuch.md`, `DEV_WORKFLOW.md`. > **Zielgruppe:** Entwickler:innen. > **Zweck:** Anleitung zum Aufsetzen der Entwicklungsumgebung, Verständnis der Modulstruktur und Durchführung von Tests. --- - [Mindnet v2.4 – Developer Guide](#mindnet-v24--developer-guide) - [1. Projektstruktur (Post-WP15)](#1-projektstruktur-post-wp15) - [2. Lokales Setup (Development)](#2-lokales-setup-development) - [2.1 Voraussetzungen](#21-voraussetzungen) - [2.2 Installation](#22-installation) - [2.3 Konfiguration (Environment)](#23-konfiguration-environment) - [2.4 Dienste starten (API \& UI)](#24-dienste-starten-api--ui) - [3. Core-Module \& Entwicklung](#3-core-module--entwicklung) - [3.1 Der Importer (`scripts.import_markdown`)](#31-der-importer-scriptsimport_markdown) - [3.2 Der Hybrid Router (`app.routers.chat`)](#32-der-hybrid-router-approuterschat) - [3.3 Der Retriever (`app.core.retriever`)](#33-der-retriever-appcoreretriever) - [3.4 Das Frontend (`app.frontend.ui`)](#34-das-frontend-appfrontendui) - [3.5 Embedding Service (`app.services.embeddings_client`)](#35-embedding-service-appservicesembeddings_client) - [3.6 Traffic Control (`app.services.llm_service`)](#36-traffic-control-appservicesllm_service) - [4. Tests \& Debugging](#4-tests--debugging) - [4.1 Unit Tests (Pytest)](#41-unit-tests-pytest) - [4.2 Integration / Pipeline Tests](#42-integration--pipeline-tests) - [4.3 Smoke Tests (E2E)](#43-smoke-tests-e2e) - [5. Das "Teach-the-AI" Paradigma (Context Intelligence)](#5-das-teach-the-ai-paradigma-context-intelligence) - [A. Workflow: Einen neuen Typ implementieren (z. B. `type: risk`)](#a-workflow-einen-neuen-typ-implementieren-z-b-type-risk) - [B. Workflow: Neue Beziehungen (Edges) nutzen (z. B. `beeinflusst_von`)](#b-workflow-neue-beziehungen-edges-nutzen-z-b-beeinflusst_von) - [C. Workflow: Interview-Schema anpassen (WP07)](#c-workflow-interview-schema-anpassen-wp07) - [Fazit](#fazit) - [6. Nützliche Einzeiler](#6-nützliche-einzeiler) --- ## 1. Projektstruktur (Post-WP15) Der Code ist modular in `app` (Logik), `scripts` (CLI) und `config` (Steuerung) getrennt. mindnet/ ├── app/ │ ├── core/ # Kernlogik │ │ ├── ingestion.py # NEU: Async Ingestion Service mit Change Detection │ │ ├── chunker.py # Smart Chunker Orchestrator │ │ ├── derive_edges.py # Edge-Erzeugung (WP03 Logik) │ │ ├── retriever.py # Scoring & Hybrid Search │ │ ├── qdrant.py # DB-Verbindung │ │ └── ... │ ├── models/ # Pydantic DTOs │ │ └── dto.py # Zentrale DTO-Definition │ ├── routers/ # FastAPI Endpoints │ │ ├── query.py # Suche │ │ ├── ingest.py # NEU: Save/Analyze (WP11) │ │ ├── chat.py # Hybrid Router v5 & Interview Logic │ │ ├── feedback.py # Feedback (WP04c) │ │ └── ... │ ├── services/ # Interne & Externe Dienste │ │ ├── llm_service.py # Ollama Client mit Traffic Control │ │ ├── semantic_analyzer.py# NEU: LLM-Filter für Edges (WP15) │ │ ├── embeddings_client.py# Async Embeddings (HTTPX) │ │ ├── feedback_service.py # Logging (JSONL Writer) │ │ └── discovery.py # NEU: Intelligence Logic (WP11) │ ├── frontend/ # NEU (WP10) │ │ └── ui.py # Streamlit Application inkl. Healing Parser │ └── main.py # Entrypoint der API ├── config/ # YAML-Konfigurationen (Single Source of Truth) │ ├── types.yaml # Import-Regeln & Smart-Edge Config │ ├── prompts.yaml # LLM Prompts & Interview Templates │ ├── decision_engine.yaml # Router-Strategien (Actions only) │ └── retriever.yaml # Scoring-Regeln & Kantengewichte ├── data/ │ └── logs/ # Lokale Logs (search_history.jsonl, feedback.jsonl) ├── scripts/ # CLI-Tools (Import, Diagnose, Reset) ├── tests/ # Pytest Suite & Smoke Scripts └── vault/ # Dein lokaler Markdown-Content (Git-ignored) --- ## 2. Lokales Setup (Development) ### 2.1 Voraussetzungen * **Python:** 3.10 oder höher. * **Docker:** Für Qdrant. * **Ollama:** Für lokale LLM-Inference (erforderlich für `/chat` und Embeddings). * **Vault:** Ein Ordner mit Markdown-Dateien (z.B. `./mindnet_v2_test_vault` für Tests). ### 2.2 Installation # 1. Repository klonen & Verzeichnis wechseln git clone mindnet cd mindnet # 2. Virtual Environment erstellen python3 -m venv .venv source .venv/bin/activate # 3. Abhängigkeiten installieren (inkl. Streamlit) pip install -r requirements.txt # 4. Ollama Setup (Modelle laden) # Chat-Modell (Phi-3) ollama pull phi3:mini # Embedding-Modell (Nomic) - PFLICHT für v2.4! ollama pull nomic-embed-text ### 2.3 Konfiguration (Environment) Erstelle eine `.env` Datei im Root-Verzeichnis. # Qdrant Verbindung QDRANT_URL="http://localhost:6333" QDRANT_API_KEY="" # Leer lassen für lokal # Mindnet Core Settings COLLECTION_PREFIX="mindnet_dev" VECTOR_DIM=768 # NEU: 768 für Nomic (vorher 384) MINDNET_TYPES_FILE="./config/types.yaml" MINDNET_RETRIEVER_CONFIG="./config/retriever.yaml" MINDNET_VAULT_ROOT="./vault" # LLM / RAG Settings (WP06/07) MINDNET_LLM_MODEL="phi3:mini" MINDNET_EMBEDDING_MODEL="nomic-embed-text" # NEU MINDNET_OLLAMA_URL="http://127.0.0.1:11434" MINDNET_LLM_TIMEOUT=300.0 # Timeout für CPU-Inference Cold-Starts MINDNET_DECISION_CONFIG="./config/decision_engine.yaml" MINDNET_LLM_BACKGROUND_LIMIT=2 # NEU: Limit für parallele Import-Tasks # Frontend Settings (WP10) MINDNET_API_URL="http://localhost:8002" MINDNET_API_TIMEOUT=300.0 # Erhöht wegen Smart Edge Berechnung # Import-Strategie MINDNET_HASH_COMPARE="Body" MINDNET_HASH_SOURCE="parsed" ### 2.4 Dienste starten (API & UI) Wir entwickeln mit zwei Services. Du kannst sie manuell in zwei Terminals starten oder die Systemd-Services nutzen (siehe `admin_guide.md`). **Terminal A: Backend (API)** # Startet auf Port 8002 (Dev Standard) uvicorn app.main:app --host 0.0.0.0 --port 8002 --env-file .env --reload **Terminal B: Frontend (UI)** # Startet auf Port 8502 (Dev Standard) # --server.port 8502 verhindert Konflikte mit Prod (8501) streamlit run app/frontend/ui.py --server.port 8502 --- ## 3. Core-Module & Entwicklung ### 3.1 Der Importer (`scripts.import_markdown`) Dies ist das komplexeste Modul. * **Einstieg:** `scripts/import_markdown.py` -> `main_async()`. * **Smart Edges:** Nutzt `app.core.chunker` und `app.services.semantic_analyzer` zur Kanten-Filterung. * **Idempotenz:** Der Importer muss mehrfach laufen können, ohne Duplikate zu erzeugen. Wir nutzen deterministische IDs (UUIDv5). * **Robustheit:** In `ingestion.py` sind Mechanismen wie Change Detection und Robust File I/O (fsync) implementiert. ### 3.2 Der Hybrid Router (`app.routers.chat`) Hier liegt die Logik für Intent Detection (WP06) und Interview-Modus (WP07). * **Question Detection:** Prüft zuerst, ob der Input eine Frage ist. Falls ja -> RAG. * **Keyword Match:** Prüft Keywords in `decision_engine.yaml` und `types.yaml`. * **Priority:** Ruft `llm_service` mit `priority="realtime"` auf. ### 3.3 Der Retriever (`app.core.retriever`) Hier passiert das Scoring. * **Hybrid Search:** Der Chat-Endpoint erzwingt `mode="hybrid"`. * **Strategic Retrieval:** In `chat.py` wird der Retriever *zweimal* aufgerufen, wenn ein Intent (z.B. `DECISION`) eine Injection (`value`) erfordert. ### 3.4 Das Frontend (`app.frontend.ui`) Eine Streamlit-App (WP10). * **Resurrection Pattern:** Das UI nutzt ein spezielles State-Management, um Eingaben bei Tab-Wechseln (Chat <-> Editor) zu erhalten. Widgets synchronisieren sich mit `st.session_state`. * **Healing Parser:** Die Funktion `parse_markdown_draft` repariert defekte YAML-Frontmatter (fehlendes `---`) automatisch. * **Logik:** Ruft `/chat`, `/feedback` und `/ingest/analyze` Endpoints der API auf. ### 3.5 Embedding Service (`app.services.embeddings_client`) **Neu in v2.4:** * Nutzt `httpx.AsyncClient` für non-blocking Calls an Ollama (Primary Mode). * Besitzt einen **Fallback** auf `requests` (Synchron), falls Legacy-Skripte ihn nutzen. * Unterstützt dediziertes Embedding-Modell (`nomic-embed-text`) getrennt vom Chat-Modell. ### 3.6 Traffic Control (`app.services.llm_service`) **Neu in v2.6 (Version 2.8.0):** * Stellt sicher, dass Batch-Prozesse (Import) den Live-Chat nicht ausbremsen. * **Methode:** `generate_raw_response(..., priority="background")` aktiviert eine Semaphore. * **Limit:** Konfigurierbar über `MINDNET_LLM_BACKGROUND_LIMIT` (Default: 2) in der `.env`. --- ## 4. Tests & Debugging Wir unterscheiden drei Test-Ebenen. Ein Pull Request sollte alle passieren. ### 4.1 Unit Tests (Pytest) Für isolierte Logik (Parsing, Scoring). pytest tests/test_retriever_basic.py pytest tests/test_chunking.py pytest tests/test_edges_all.py ### 4.2 Integration / Pipeline Tests Prüfen den Datenfluss von Markdown bis Qdrant-JSON. * **Payload Dryrun:** Prüft JSON-Schema Konformität. python3 -m scripts.payload_dryrun --vault ./mindnet_v2_test_vault * **Edge Checks:** Prüft Graph-Invarianten. python3 -m scripts.edges_full_check ### 4.3 Smoke Tests (E2E) Prüfen das laufende System gegen eine echte Qdrant-Instanz und Ollama. # 1. API Test (Decision Engine) python tests/test_wp06_decision.py -p 8002 -e DECISION -q "Soll ich X tun?" # 2. UI Test (Manuell) # Öffne http://localhost:8502 # Stelle eine Frage und prüfe Intent-Badge und Quellen-Anzeige. # 3. Feedback Test python tests/test_feedback_smoke.py --url http://localhost:8002/query # 4. Intelligence Test (WP11) python debug_analysis.py --- ## 5. Das "Teach-the-AI" Paradigma (Context Intelligence) Mindnet lernt nicht durch Training (Fine-Tuning), sondern durch **Konfiguration**, **Vernetzung** und **Prompting**. Dies ist der **Core-Workflow** für Erweiterungen. ### A. Workflow: Einen neuen Typ implementieren (z. B. `type: risk`) **1. Daten-Ebene (`config/types.yaml`)** Definiere die "Physik" des Typs (Import-Regeln und Basis-Wichtigkeit). risk: chunk_profile: sliding_short # Risiken sind oft kurze Statements retriever_weight: 0.90 # Sehr wichtig edge_defaults: ["blocks"] # Automatische Kante zu verlinkten Projekten detection_keywords: ["gefahr", "risiko"] **2. Strategie-Ebene (`config/decision_engine.yaml`)** Damit dieser Typ aktiv geladen wird, musst du ihn einer Strategie zuordnen. DECISION: inject_types: ["value", "principle", "goal", "risk"] # <--- "risk" hinzugefügt *Ergebnis:* Wenn der Intent `DECISION` erkannt wird, sucht das System nun auch aktiv nach Risiken. **3. Kognitive Ebene (`config/prompts.yaml`)** Erkläre dem LLM im Template, was es damit tun soll. ### B. Workflow: Neue Beziehungen (Edges) nutzen (z. B. `beeinflusst_von`) Beziehungen sind der Klebstoff für die "Why"-Erklärungen. **1. Erfassung im Vault (Markdown)** Nutze die Inline-Syntax im Fließtext: > "Die Entscheidung für Qdrant wurde [[rel:beeinflusst_von Budgetkürzung 2024]]." **2. Gewichtung (`config/retriever.yaml`)** Konfiguriere `edge_weights`, wenn Kausalität wichtiger ist als Ähnlichkeit. ### C. Workflow: Interview-Schema anpassen (WP07) Wenn Mindnet neue Fragen stellen soll: **1. Schema erweitern (`config/types.yaml`)** Füge das Feld in die Liste ein (Neu: Schemas liegen jetzt hier). project: schema: - "Titel" - "Ziel" - "Budget (Neu)" **2. Keine Code-Änderung nötig** Der `One-Shot Extractor` (Prompt Template) liest diese Liste dynamisch. ### Fazit * **Vault:** Liefert das Wissen. * **Config:** Liefert die Strategie (Router & Weights). * **Prompt:** Liefert die Interpretation. --- ## 6. Nützliche Einzeiler **DB komplett zurücksetzen (Vorsicht!):** # --yes überspringt die Bestätigung python3 -m scripts.reset_qdrant --mode wipe --prefix "mindnet_dev" --yes **Einen einzelnen File inspizieren (Parser-Sicht):** python3 tests/inspect_one_note.py --file ./vault/MeinFile.md **Live-Logs sehen (Systemd):** # Backend journalctl -u mindnet-dev -f # Frontend journalctl -u mindnet-ui-dev -f