12 KiB
Mindnet v2.4 – Developer Guide
Datei: docs/mindnet_developer_guide_v2.4.md
Stand: 2025-12-11
Status: FINAL (Inkl. Async Core, Nomic & 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
1. Projektstruktur (Post-WP10)
Der Code ist modular in app (Logik), scripts (CLI) und config (Steuerung) getrennt.
mindnet/
├── app/
│ ├── core/ # Kernlogik
│ │ ├── ingestion.py # NEU: Async Ingestion Service (WP11)
│ │ ├── chunker.py # Text-Zerlegung
│ │ ├── 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 & Interview Logic (WP06/WP07)
│ │ ├── feedback.py # Feedback (WP04c)
│ │ └── ...
│ ├── services/ # Interne & Externe Dienste
│ │ ├── llm_service.py # Ollama Client (Mit Timeout & Raw-Mode)
│ │ ├── embeddings_client.py# NEU: Async Embeddings (HTTPX)
│ │ ├── feedback_service.py # Logging (JSONL Writer)
│ │ └── discovery.py # NEU: Intelligence Logic (WP11)
│ ├── frontend/ # NEU (WP10)
│ │ └── ui.py # Streamlit Application inkl. Draft-Editor
│ └── main.py # Entrypoint der API
├── config/ # YAML-Konfigurationen (Single Source of Truth)
│ ├── types.yaml # Import-Regeln
│ ├── prompts.yaml # LLM Prompts & Interview Templates (WP06/07)
│ ├── decision_engine.yaml # Router-Strategien & Schemas (WP06/07)
│ └── 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
/chatund Embeddings). - Vault: Ein Ordner mit Markdown-Dateien (z.B.
./mindnet_v2_test_vaultfür Tests).
2.2 Installation
# 1. Repository klonen & Verzeichnis wechseln
git clone <repo> 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
MINDNET_DECISION_CONFIG="./config/decision_engine.yaml"
# Frontend Settings (WP10)
MINDNET_API_URL="http://localhost:8002"
MINDNET_API_TIMEOUT=60.0
# 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(). - Async & Semaphore: Das Skript nutzt nun
asynciound eine Semaphore (Limit: 5), um parallele Embeddings zu erzeugen, ohne Ollama zu überlasten. - Idempotenz: Der Importer muss mehrfach laufen können, ohne Duplikate zu erzeugen. Wir nutzen deterministische IDs (UUIDv5).
- Debugging: Nutze
--dry-runoderscripts/payload_dryrun.py.
3.2 Der Hybrid Router (app.routers.chat)
Hier liegt die Logik für Intent Detection (WP06) und Interview-Modus (WP07).
- Logic:
_classify_intentprüft zuerst Keywords (Fast Path) und fällt aufllm_service.generate_raw_responsezurück (Slow Path), wenn konfiguriert. - One-Shot: Wenn Intent
INTERVIEWerkannt wird, wird kein Retrieval ausgeführt. Stattdessen wird ein Draft generiert. - Erweiterung: Um neue Intents hinzuzufügen, editiere nur die YAML, nicht den Python-Code (Late Binding).
3.3 Der Retriever (app.core.retriever)
Hier passiert das Scoring.
- Hybrid Search: Der Chat-Endpoint erzwingt
mode="hybrid". - Strategic Retrieval: In
chat.pywird 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. - Draft Editor: Enthält einen YAML-Sanitizer (
normalize_meta_and_body), der sicherstellt, dass LLM-Halluzinationen im Frontmatter nicht das File zerstören. - Logik: Ruft
/chatund/feedbackund/ingest/analyzeEndpoints der API auf.
3.5 Embedding Service (app.services.embeddings_client)
Neu in v2.4:
- Nutzt
httpx.AsyncClientfür non-blocking Calls an Ollama. - Unterstützt dediziertes Embedding-Modell (
nomic-embed-text) getrennt vom Chat-Modell. - Enthält Legacy-Funktion
embed_textfür synchrone Skripte.
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: short # Risiken sind oft kurze Statements
retriever_weight: 0.90 # Sehr wichtig, fast so hoch wie Decisions
edge_defaults: ["blocks"] # Automatische Kante zu verlinkten Projekten
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/decision_engine.yaml)
Füge das Feld in die Liste ein.
project:
fields: ["Titel", "Ziel", "Budget"] # <--- Budget neu
2. Keine Code-Änderung nötig
Der One-Shot Extractor (Prompt Template) liest diese Liste dynamisch und weist das LLM an, das Budget zu extrahieren oder [TODO] zu setzen.
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