mindnet/docs/developer_guide.md

297 lines
12 KiB
Markdown
Raw Normal View History

2025-12-10 18:55:38 +01:00
# Mindnet v2.4 – Developer Guide
**Datei:** `docs/mindnet_developer_guide_v2.4.md`
2025-12-11 16:58:23 +01:00
**Stand:** 2025-12-11
**Status:** **FINAL** (Inkl. Async Core, Nomic & Frontend State)
2025-12-08 16:14:52 +01:00
**Quellen:** `mindnet_technical_architecture.md`, `Handbuch.md`, `DEV_WORKFLOW.md`.
2025-12-07 12:09:43 +01:00
> **Zielgruppe:** Entwickler:innen.
> **Zweck:** Anleitung zum Aufsetzen der Entwicklungsumgebung, Verständnis der Modulstruktur und Durchführung von Tests.
---
2025-12-10 18:55:38 +01:00
- [Mindnet v2.4 – Developer Guide](#mindnet-v24--developer-guide)
2025-12-10 10:26:44 +01:00
- [1. Projektstruktur (Post-WP10)](#1-projektstruktur-post-wp10)
2025-12-09 17:11:03 +01:00
- [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)
2025-12-10 10:26:44 +01:00
- [2.4 Dienste starten (API \& UI)](#24-dienste-starten-api--ui)
2025-12-09 17:11:03 +01:00
- [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)
2025-12-10 10:26:44 +01:00
- [3.4 Das Frontend (`app.frontend.ui`)](#34-das-frontend-appfrontendui)
2025-12-11 16:58:23 +01:00
- [3.5 Embedding Service (`app.services.embeddings_client`)](#35-embedding-service-appservicesembeddings_client)
2025-12-09 17:11:03 +01:00
- [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)
2025-12-10 18:55:38 +01:00
- [C. Workflow: Interview-Schema anpassen (WP07)](#c-workflow-interview-schema-anpassen-wp07)
2025-12-09 17:11:03 +01:00
- [Fazit](#fazit)
- [6. Nützliche Einzeiler](#6-nützliche-einzeiler)
2025-12-07 12:09:43 +01:00
2025-12-09 17:11:03 +01:00
---
2025-12-10 10:26:44 +01:00
## 1. Projektstruktur (Post-WP10)
2025-12-07 12:09:43 +01:00
Der Code ist modular in `app` (Logik), `scripts` (CLI) und `config` (Steuerung) getrennt.
mindnet/
├── app/
│ ├── core/ # Kernlogik
2025-12-11 16:58:23 +01:00
│ │ ├── ingestion.py # NEU: Async Ingestion Service (WP11)
2025-12-07 12:09:43 +01:00
│ │ ├── chunker.py # Text-Zerlegung
│ │ ├── derive_edges.py # Edge-Erzeugung (WP03 Logik)
2025-12-08 16:14:52 +01:00
│ │ ├── retriever.py # Scoring & Hybrid Search
2025-12-07 12:09:43 +01:00
│ │ ├── qdrant.py # DB-Verbindung
│ │ └── ...
2025-12-08 16:14:52 +01:00
│ ├── models/ # Pydantic DTOs
│ │ └── dto.py # Zentrale DTO-Definition
2025-12-07 12:09:43 +01:00
│ ├── routers/ # FastAPI Endpoints
2025-12-08 16:14:52 +01:00
│ │ ├── query.py # Suche
2025-12-11 16:58:23 +01:00
│ │ ├── ingest.py # NEU: Save/Analyze (WP11)
2025-12-10 18:55:38 +01:00
│ │ ├── chat.py # Hybrid Router & Interview Logic (WP06/WP07)
2025-12-08 16:14:52 +01:00
│ │ ├── feedback.py # Feedback (WP04c)
│ │ └── ...
│ ├── services/ # Interne & Externe Dienste
2025-12-09 17:11:03 +01:00
│ │ ├── llm_service.py # Ollama Client (Mit Timeout & Raw-Mode)
2025-12-11 16:58:23 +01:00
│ │ ├── embeddings_client.py# NEU: Async Embeddings (HTTPX)
2025-12-08 16:14:52 +01:00
│ │ ├── feedback_service.py # Logging (JSONL Writer)
2025-12-11 16:58:23 +01:00
│ │ └── discovery.py # NEU: Intelligence Logic (WP11)
2025-12-10 10:26:44 +01:00
│ ├── frontend/ # NEU (WP10)
2025-12-10 18:55:38 +01:00
│ │ └── ui.py # Streamlit Application inkl. Draft-Editor
2025-12-07 12:09:43 +01:00
│ └── main.py # Entrypoint der API
├── config/ # YAML-Konfigurationen (Single Source of Truth)
│ ├── types.yaml # Import-Regeln
2025-12-10 18:55:38 +01:00
│ ├── prompts.yaml # LLM Prompts & Interview Templates (WP06/07)
│ ├── decision_engine.yaml # Router-Strategien & Schemas (WP06/07)
2025-12-08 17:39:01 +01:00
│ └── retriever.yaml # Scoring-Regeln & Kantengewichte
2025-12-08 16:14:52 +01:00
├── data/
│ └── logs/ # Lokale Logs (search_history.jsonl, feedback.jsonl)
2025-12-07 12:09:43 +01:00
├── scripts/ # CLI-Tools (Import, Diagnose, Reset)
2025-12-08 16:14:52 +01:00
├── tests/ # Pytest Suite & Smoke Scripts
2025-12-07 12:09:43 +01:00
└── vault/ # Dein lokaler Markdown-Content (Git-ignored)
---
## 2. Lokales Setup (Development)
### 2.1 Voraussetzungen
* **Python:** 3.10 oder höher.
* **Docker:** Für Qdrant.
2025-12-11 16:58:23 +01:00
* **Ollama:** Für lokale LLM-Inference (erforderlich für `/chat` und Embeddings).
2025-12-07 12:09:43 +01:00
* **Vault:** Ein Ordner mit Markdown-Dateien (z.B. `./mindnet_v2_test_vault` für Tests).
### 2.2 Installation
2025-12-08 17:33:46 +01:00
2025-12-07 12:09:43 +01:00
# 1. Repository klonen & Verzeichnis wechseln
git clone <repo> mindnet
cd mindnet
# 2. Virtual Environment erstellen
python3 -m venv .venv
source .venv/bin/activate
2025-12-10 10:26:44 +01:00
# 3. Abhängigkeiten installieren (inkl. Streamlit)
2025-12-07 12:09:43 +01:00
pip install -r requirements.txt
2025-12-08 16:14:52 +01:00
2025-12-11 16:58:23 +01:00
# 4. Ollama Setup (Modelle laden)
# Chat-Modell (Phi-3)
2025-12-08 16:14:52 +01:00
ollama pull phi3:mini
2025-12-11 16:58:23 +01:00
# Embedding-Modell (Nomic) - PFLICHT für v2.4!
ollama pull nomic-embed-text
2025-12-07 12:09:43 +01:00
### 2.3 Konfiguration (Environment)
2025-12-10 10:26:44 +01:00
Erstelle eine `.env` Datei im Root-Verzeichnis.
2025-12-07 12:09:43 +01:00
# Qdrant Verbindung
QDRANT_URL="http://localhost:6333"
QDRANT_API_KEY="" # Leer lassen für lokal
2025-12-08 16:14:52 +01:00
# Mindnet Core Settings
2025-12-07 12:09:43 +01:00
COLLECTION_PREFIX="mindnet_dev"
2025-12-11 16:58:23 +01:00
VECTOR_DIM=768 # NEU: 768 für Nomic (vorher 384)
2025-12-07 12:09:43 +01:00
MINDNET_TYPES_FILE="./config/types.yaml"
MINDNET_RETRIEVER_CONFIG="./config/retriever.yaml"
2025-12-11 16:58:23 +01:00
MINDNET_VAULT_ROOT="./vault"
2025-12-07 12:09:43 +01:00
2025-12-10 18:55:38 +01:00
# LLM / RAG Settings (WP06/07)
2025-12-08 16:14:52 +01:00
MINDNET_LLM_MODEL="phi3:mini"
2025-12-11 16:58:23 +01:00
MINDNET_EMBEDDING_MODEL="nomic-embed-text" # NEU
2025-12-08 16:14:52 +01:00
MINDNET_OLLAMA_URL="http://127.0.0.1:11434"
2025-12-09 17:11:03 +01:00
MINDNET_LLM_TIMEOUT=300.0
MINDNET_DECISION_CONFIG="./config/decision_engine.yaml"
2025-12-08 16:14:52 +01:00
2025-12-10 10:26:44 +01:00
# Frontend Settings (WP10)
MINDNET_API_URL="http://localhost:8002"
2025-12-11 16:58:23 +01:00
MINDNET_API_TIMEOUT=60.0
2025-12-10 10:26:44 +01:00
2025-12-08 16:14:52 +01:00
# Import-Strategie
2025-12-07 12:09:43 +01:00
MINDNET_HASH_COMPARE="Body"
MINDNET_HASH_SOURCE="parsed"
2025-12-10 10:26:44 +01:00
### 2.4 Dienste starten (API & UI)
2025-12-08 16:14:52 +01:00
2025-12-10 10:26:44 +01:00
Wir entwickeln mit zwei Services. Du kannst sie manuell in zwei Terminals starten oder die Systemd-Services nutzen (siehe `admin_guide.md`).
2025-12-08 16:14:52 +01:00
2025-12-10 10:26:44 +01:00
**Terminal A: Backend (API)**
2025-12-08 17:33:46 +01:00
2025-12-10 10:26:44 +01:00
# Startet auf Port 8002 (Dev Standard)
2025-12-08 16:14:52 +01:00
uvicorn app.main:app --host 0.0.0.0 --port 8002 --env-file .env --reload
2025-12-07 12:09:43 +01:00
2025-12-10 10:26:44 +01:00
**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
2025-12-07 12:09:43 +01:00
---
## 3. Core-Module & Entwicklung
### 3.1 Der Importer (`scripts.import_markdown`)
Dies ist das komplexeste Modul.
2025-12-11 16:58:23 +01:00
* **Einstieg:** `scripts/import_markdown.py` -> `main_async()`.
* **Async & Semaphore:** Das Skript nutzt nun `asyncio` und eine Semaphore (Limit: 5), um parallele Embeddings zu erzeugen, ohne Ollama zu überlasten.
2025-12-08 16:14:52 +01:00
* **Idempotenz:** Der Importer muss mehrfach laufen können, ohne Duplikate zu erzeugen. Wir nutzen deterministische IDs (UUIDv5).
* **Debugging:** Nutze `--dry-run` oder `scripts/payload_dryrun.py`.
2025-12-07 12:09:43 +01:00
2025-12-09 17:11:03 +01:00
### 3.2 Der Hybrid Router (`app.routers.chat`)
2025-12-10 18:55:38 +01:00
Hier liegt die Logik für Intent Detection (WP06) und Interview-Modus (WP07).
2025-12-09 17:11:03 +01:00
* **Logic:** `_classify_intent` prüft zuerst Keywords (Fast Path) und fällt auf `llm_service.generate_raw_response` zurück (Slow Path), wenn konfiguriert.
2025-12-10 18:55:38 +01:00
* **One-Shot:** Wenn Intent `INTERVIEW` erkannt wird, wird **kein Retrieval** ausgeführt. Stattdessen wird ein Draft generiert.
2025-12-09 17:11:03 +01:00
* **Erweiterung:** Um neue Intents hinzuzufügen, editiere nur die YAML, nicht den Python-Code (Late Binding).
2025-12-07 12:09:43 +01:00
2025-12-09 17:11:03 +01:00
### 3.3 Der Retriever (`app.core.retriever`)
Hier passiert das Scoring.
2025-12-08 16:14:52 +01:00
* **Hybrid Search:** Der Chat-Endpoint erzwingt `mode="hybrid"`.
2025-12-09 17:11:03 +01:00
* **Strategic Retrieval:** In `chat.py` wird der Retriever *zweimal* aufgerufen, wenn ein Intent (z.B. `DECISION`) eine Injection (`value`) erfordert.
2025-12-07 12:09:43 +01:00
2025-12-10 10:26:44 +01:00
### 3.4 Das Frontend (`app.frontend.ui`)
Eine Streamlit-App (WP10).
2025-12-11 16:58:23 +01:00
* **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`.
2025-12-10 18:55:38 +01:00
* **Draft Editor:** Enthält einen YAML-Sanitizer (`normalize_meta_and_body`), der sicherstellt, dass LLM-Halluzinationen im Frontmatter nicht das File zerstören.
2025-12-11 16:58:23 +01:00
* **Logik:** Ruft `/chat` und `/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.
* Unterstützt dediziertes Embedding-Modell (`nomic-embed-text`) getrennt vom Chat-Modell.
* Enthält Legacy-Funktion `embed_text` für synchrone Skripte.
2025-12-10 10:26:44 +01:00
2025-12-07 12:09:43 +01:00
---
## 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).
2025-12-08 17:33:46 +01:00
2025-12-07 12:09:43 +01:00
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.
2025-12-08 16:14:52 +01:00
* **Payload Dryrun:** Prüft JSON-Schema Konformität.
2025-12-08 17:33:46 +01:00
2025-12-07 12:09:43 +01:00
python3 -m scripts.payload_dryrun --vault ./mindnet_v2_test_vault
2025-12-08 16:14:52 +01:00
* **Edge Checks:** Prüft Graph-Invarianten.
2025-12-08 17:33:46 +01:00
2025-12-07 12:09:43 +01:00
python3 -m scripts.edges_full_check
### 4.3 Smoke Tests (E2E)
2025-12-10 10:26:44 +01:00
Prüfen das laufende System gegen eine echte Qdrant-Instanz und Ollama.
2025-12-08 16:14:52 +01:00
2025-12-10 10:26:44 +01:00
# 1. API Test (Decision Engine)
2025-12-09 17:11:03 +01:00
python tests/test_wp06_decision.py -p 8002 -e DECISION -q "Soll ich X tun?"
2025-12-07 12:09:43 +01:00
2025-12-10 10:26:44 +01:00
# 2. UI Test (Manuell)
# Öffne http://localhost:8502
# Stelle eine Frage und prüfe Intent-Badge und Quellen-Anzeige.
2025-12-09 17:11:03 +01:00
2025-12-10 10:26:44 +01:00
# 3. Feedback Test
2025-12-08 16:14:52 +01:00
python tests/test_feedback_smoke.py --url http://localhost:8002/query
2025-12-07 12:09:43 +01:00
2025-12-11 16:58:23 +01:00
# 4. Intelligence Test (WP11)
python debug_analysis.py
2025-12-07 12:09:43 +01:00
---
2025-12-08 17:33:46 +01:00
## 5. Das "Teach-the-AI" Paradigma (Context Intelligence)
2025-12-10 18:55:38 +01:00
Mindnet lernt nicht durch Training (Fine-Tuning), sondern durch **Konfiguration**, **Vernetzung** und **Prompting**. Dies ist der **Core-Workflow** für Erweiterungen.
2025-12-08 17:33:46 +01:00
2025-12-08 17:39:01 +01:00
### A. Workflow: Einen neuen Typ implementieren (z. B. `type: risk`)
2025-12-08 17:33:46 +01:00
2025-12-08 17:39:01 +01:00
**1. Daten-Ebene (`config/types.yaml`)**
Definiere die "Physik" des Typs (Import-Regeln und Basis-Wichtigkeit).
2025-12-07 12:09:43 +01:00
2025-12-08 17:33:46 +01:00
risk:
chunk_profile: short # Risiken sind oft kurze Statements
retriever_weight: 0.90 # Sehr wichtig, fast so hoch wie Decisions
2025-12-08 17:39:01 +01:00
edge_defaults: ["blocks"] # Automatische Kante zu verlinkten Projekten
2025-12-07 12:09:43 +01:00
2025-12-09 17:11:03 +01:00
**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
2025-12-08 17:33:46 +01:00
2025-12-09 17:11:03 +01:00
*Ergebnis:* Wenn der Intent `DECISION` erkannt wird, sucht das System nun auch aktiv nach Risiken.
2025-12-08 17:33:46 +01:00
2025-12-08 17:39:01 +01:00
**3. Kognitive Ebene (`config/prompts.yaml`)**
2025-12-09 17:11:03 +01:00
Erkläre dem LLM im Template, was es damit tun soll.
2025-12-08 17:33:46 +01:00
2025-12-08 17:39:01 +01:00
### 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:
2025-12-10 18:55:38 +01:00
> "Die Entscheidung für Qdrant wurde [[rel:beeinflusst_von Budgetkürzung 2024]]."
2025-12-08 17:39:01 +01:00
**2. Gewichtung (`config/retriever.yaml`)**
2025-12-10 18:55:38 +01:00
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
2025-12-08 17:39:01 +01:00
2025-12-10 18:55:38 +01:00
**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.
2025-12-08 17:33:46 +01:00
### Fazit
2025-12-08 17:39:01 +01:00
* **Vault:** Liefert das Wissen.
2025-12-09 17:11:03 +01:00
* **Config:** Liefert die Strategie (Router & Weights).
2025-12-08 17:39:01 +01:00
* **Prompt:** Liefert die Interpretation.
2025-12-07 12:09:43 +01:00
---
## 6. Nützliche Einzeiler
**DB komplett zurücksetzen (Vorsicht!):**
2025-12-08 17:33:46 +01:00
2025-12-11 16:58:23 +01:00
# --yes überspringt die Bestätigung
2025-12-07 12:09:43 +01:00
python3 -m scripts.reset_qdrant --mode wipe --prefix "mindnet_dev" --yes
**Einen einzelnen File inspizieren (Parser-Sicht):**
2025-12-08 17:33:46 +01:00
2025-12-07 12:09:43 +01:00
python3 tests/inspect_one_note.py --file ./vault/MeinFile.md
2025-12-10 10:26:44 +01:00
**Live-Logs sehen (Systemd):**
2025-12-08 17:33:46 +01:00
2025-12-10 10:26:44 +01:00
# Backend
journalctl -u mindnet-dev -f
# Frontend
journalctl -u mindnet-ui-dev -f