mindnet/docs/developer_guide.md
2025-12-13 06:37:24 +01:00

310 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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