All checks were successful
Deploy mindnet to llm-node / deploy (push) Successful in 3s
246 lines
9.3 KiB
Markdown
246 lines
9.3 KiB
Markdown
# Mindnet v2.2 – Developer Guide
|
||
**Datei:** `docs/mindnet_developer_guide_v2.2.md`
|
||
**Stand:** 2025-12-08
|
||
**Status:** **FINAL** (Inkl. RAG, Edge-Config & AI-Teaching)
|
||
**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.
|
||
|
||
---
|
||
|
||
## 1. Projektstruktur (Aktualisiert)
|
||
|
||
Der Code ist modular in `app` (Logik), `scripts` (CLI) und `config` (Steuerung) getrennt.
|
||
|
||
mindnet/
|
||
├── app/
|
||
│ ├── core/ # Kernlogik
|
||
│ │ ├── 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
|
||
│ │ ├── chat.py # RAG-Chat (WP05)
|
||
│ │ ├── feedback.py # Feedback (WP04c)
|
||
│ │ └── ...
|
||
│ ├── services/ # Interne & Externe Dienste
|
||
│ │ ├── llm_service.py # Ollama Client (WP05)
|
||
│ │ ├── feedback_service.py # Logging (JSONL Writer)
|
||
│ │ └── embeddings_client.py
|
||
│ └── main.py # Entrypoint der API
|
||
├── config/ # YAML-Konfigurationen (Single Source of Truth)
|
||
│ ├── types.yaml # Import-Regeln
|
||
│ ├── prompts.yaml # LLM Prompts & RAG Templates (WP05)
|
||
│ └── 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`).
|
||
* **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
|
||
pip install -r requirements.txt
|
||
|
||
# 4. Ollama Setup (Modell laden)
|
||
# Wir nutzen Phi-3 Mini für schnelle CPU-Inference
|
||
ollama pull phi3:mini
|
||
|
||
### 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"
|
||
MINDNET_TYPES_FILE="./config/types.yaml"
|
||
MINDNET_RETRIEVER_CONFIG="./config/retriever.yaml"
|
||
|
||
# LLM / RAG Settings (WP05)
|
||
MINDNET_LLM_MODEL="phi3:mini"
|
||
MINDNET_OLLAMA_URL="http://127.0.0.1:11434"
|
||
MINDNET_PROMPTS_PATH="./config/prompts.yaml"
|
||
|
||
# Import-Strategie
|
||
MINDNET_HASH_COMPARE="Body"
|
||
MINDNET_HASH_SOURCE="parsed"
|
||
|
||
### 2.4 Dienste starten (Systemd bevorzugt)
|
||
Auf dem Entwicklungsserver (Beelink) nutzen wir Systemd.
|
||
|
||
# Starten / Neustarten
|
||
sudo systemctl restart mindnet-dev
|
||
|
||
# Logs prüfen
|
||
journalctl -u mindnet-dev -f
|
||
|
||
Falls du lokal auf Windows entwickelst:
|
||
|
||
# 1. Qdrant starten
|
||
docker run -p 6333:6333 qdrant/qdrant
|
||
# 2. Ollama starten
|
||
ollama serve
|
||
# 3. API starten
|
||
uvicorn app.main:app --host 0.0.0.0 --port 8002 --env-file .env --reload
|
||
|
||
---
|
||
|
||
## 3. Core-Module & Entwicklung
|
||
|
||
### 3.1 Der Importer (`scripts.import_markdown`)
|
||
Dies ist das komplexeste Modul.
|
||
* **Einstieg:** `scripts/import_markdown.py` -> `main()`.
|
||
* **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`.
|
||
|
||
### 3.2 Edge-Logik (`app.core.derive_edges`)
|
||
Hier wird entschieden, welche Kanten entstehen.
|
||
* **Rule-ID:** Vergib zwingend eine eindeutige `rule_id` (z.B. `custom:my_rule`), damit die Herkunft für die Explanation nachvollziehbar bleibt.
|
||
|
||
### 3.3 Der Retriever & Chat (`app.core.retriever` / `app.routers.chat`)
|
||
Hier passiert das Scoring und die Generation.
|
||
* **Hybrid Search:** Der Chat-Endpoint erzwingt `mode="hybrid"`.
|
||
* **Context Enrichment:** In `_build_enriched_context` (chat.py) werden Metadaten (Typ, Score) in den Prompt injiziert. Achte darauf, dass neue Typen hier ggf. berücksichtigt werden, falls sie spezielle Behandlung brauchen (aktuell generisch gelöst).
|
||
|
||
---
|
||
|
||
## 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 (API) gegen eine echte Qdrant-Instanz und Ollama.
|
||
|
||
# 1. Retriever Test (Hybrid + Explanation)
|
||
python scripts/test_retriever_smoke.py --query "Test" --mode hybrid --top-k 5 --explain
|
||
|
||
# 2. Chat / RAG Test (WP05)
|
||
# Prüft die gesamte Kette: Suche -> Kontext -> LLM -> Antwort
|
||
python tests/test_chat_wp05.py
|
||
|
||
# 3. Feedback Test (WP04c)
|
||
python tests/test_feedback_smoke.py --url http://localhost:8002/query
|
||
|
||
---
|
||
|
||
## 5. Das "Teach-the-AI" Paradigma (Context Intelligence)
|
||
|
||
Mindnet lernt nicht durch Training (Fine-Tuning), sondern durch **Konfiguration**, **Vernetzung** und **Prompting**. Wenn du dem System ein neues Konzept beibringen willst, musst du in der Regel an drei Stellen eingreifen. 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
|
||
|
||
*Ergebnis:* Notizen werden importiert und landen bei Suchen weit oben.
|
||
|
||
**2. Labeling-Ebene (`app/routers/chat.py`)**
|
||
Der Router liest das Feld `type` automatisch aus und injiziert es als `TYP: [RISK]` in den Prompt.
|
||
* *Prüfung:* Keine Code-Änderung nötig, da der Router generisch ist.
|
||
|
||
**3. Kognitive Ebene (`config/prompts.yaml`)**
|
||
Erkläre dem LLM, was `[RISK]` bedeutet. Ergänze den `system_prompt`:
|
||
|
||
system_prompt: |
|
||
...
|
||
REGELN FÜR TYPEN:
|
||
- [RISK]: Warnung! Wenn ein [RISK] im Kontext ist, weise den User darauf hin.
|
||
|
||
### 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)**
|
||
Du musst dem System keinen neuen Edge-Typ "beibringen" (Schema-less). Du nutzt ihn einfach.
|
||
Nutze die Inline-Syntax im Fließtext:
|
||
|
||
Die Entscheidung für Qdrant wurde [[rel:beeinflusst_von Budgetkürzung 2024]].
|
||
Diese Strategie ist eine [[rel:reaktion_auf Marktveränderung]].
|
||
|
||
*Ergebnis:* Der Importer erzeugt Kanten mit `kind="beeinflusst_von"`.
|
||
|
||
**2. Gewichtung (`config/retriever.yaml`)**
|
||
Standardmäßig werden alle expliziten Kanten gleich behandelt (hoher Bonus). Wenn du willst, dass `beeinflusst_von` *wichtiger* ist als `related_to`, konfigurierst du dies hier.
|
||
|
||
scoring:
|
||
edge_weight: 0.7
|
||
# Optional: Spezifische Boosts für Kanten-Typen (Advanced)
|
||
edge_type_weights:
|
||
beeinflusst_von: 1.5 # Sehr starker Einfluss auf das Ranking
|
||
reaktion_auf: 1.2
|
||
related_to: 0.5 # Schwächerer Einfluss
|
||
|
||
*Hinweis:* Wenn `edge_type_weights` nicht definiert ist, gilt der Standard-Algorithmus (Confidence ~0.95 für Inline-Relations).
|
||
|
||
**3. Verständnis beim LLM (`config/prompts.yaml`)**
|
||
Damit der Chatbot versteht, dass "beeinflusst_von" eine Kausalität ist (und nicht nur Ähnlichkeit), kannst du dies im Prompt erklären, falls die Explanation-Daten in den Kontext geladen werden (Roadmap WP-06).
|
||
|
||
### Fazit
|
||
Nur wenn **Daten** (Vault), **Physik** (Config) und **Semantik** (Prompt) zusammenspielen, entsteht ein intelligenter Zwilling.
|
||
* **Vault:** Liefert das Wissen.
|
||
* **Config:** Liefert die Priorität (Weights).
|
||
* **Prompt:** Liefert die Interpretation.
|
||
|
||
---
|
||
|
||
## 6. Nützliche Einzeiler
|
||
|
||
**DB komplett zurücksetzen (Vorsicht!):**
|
||
|
||
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 (Beelink):**
|
||
|
||
journalctl -u mindnet-dev -f |