Dokumentation

This commit is contained in:
Lars 2025-12-16 18:46:11 +01:00
parent edbd8f0ca8
commit 25ec3880bb
6 changed files with 105 additions and 59 deletions

View File

@ -31,7 +31,8 @@ context: "Definitionen zentraler Begriffe und Entitäten im Mindnet-System."
* **Active Intelligence:** Feature im Web-Editor, das während des Schreibens automatisch Links vorschlägt.
* **Smart Edge Allocation (WP15):** Ein KI-Verfahren, das prüft, ob ein Link in einer Notiz für einen spezifischen Textabschnitt relevant ist, statt ihn blind allen Chunks zuzuordnen.
* **Strict Heading Split:** Chunking-Strategie, bei der Überschriften (z.B. H2) als harte Grenzen dienen. Verhindert das Vermischen von Themen (z.B. zwei unterschiedliche Rollen in einem Chunk).
* **Strict Heading Split:** Chunking-Strategie, bei der Überschriften (z.B. H2) als harte Grenzen dienen. Verhindert das Vermischen von Themen (z.B. zwei unterschiedliche Rollen in einem Chunk). Besitzt ein "Safety Net" für zu lange Abschnitte.
* **Soft Heading Split:** Chunking-Strategie, die Überschriften respektiert, aber kleine Abschnitte zusammenfasst, um Vektor-Kontext zu füllen ("Fuller Chunks").
* **Healing Parser:** UI-Funktion, die fehlerhaften Output des LLMs (z.B. defektes YAML) automatisch repariert.
* **Explanation Layer:** Die Schicht, die dem Nutzer erklärt, *warum* ein Suchergebnis gefunden wurde (z.B. "Weil Projekt X davon abhängt").
* **Provenance:** Die Herkunft einer Kante.

View File

@ -3,7 +3,7 @@ doc_type: user_manual
audience: user, author
scope: vault, markdown, schema
status: active
version: 2.6
version: 2.7.0
context: "Regelwerk für das Erstellen von Notizen im Vault. Die 'Source of Truth' für Autoren."
---
@ -46,11 +46,12 @@ tags: [ki, entwicklung] # Taxonomie
---
```
**Optionale Felder:**
**Optionale Felder & Overrides (Advanced):**
* `aliases`: [Alpha Projekt] Wichtig für "Active Intelligence" (Exact Match).
* `visibility`: internal (default) / public.
> **Wichtig:** Felder wie `retriever_weight` oder `chunk_profile` werden zentral über `types.yaml` gesteuert und müssen nicht mehr manuell gesetzt werden (Virtual Schema Layer).
* **NEU:** Du kannst die KI-Steuerung manuell überschreiben, wenn dir der Standard für den Typ nicht passt:
* `chunking_profile`: Zwingt den Chunker in einen Modus (z.B. `structured_smart_edges_strict`).
* `retriever_weight`: Setzt die Wichtigkeit manuell hoch/runter (z.B. `1.5` für extrem wichtig).
---
@ -136,11 +137,9 @@ Ich habe gelernt: Das ist oft das Zeichen kurz vor dem Durchbruch.
---
## 6. Best Practices & Beispiele (Klassik)
## 6. Best Practices & Beispiele
Hier sind vollständige Vorlagen für häufige Typen.
### 6.1 Beispiel: Projekt-Notiz
### 6.1 Beispiel: Projekt-Notiz (Standard)
Projekte profitieren von `depends_on`, um Abhängigkeiten zu klären.
```markdown
@ -159,11 +158,11 @@ Wir bauen ein persönliches Wissensnetz.
Wir nutzen [[rel:depends_on Qdrant]] für die Vektorsuche und [[rel:depends_on FastAPI]] für das Backend.
## Architektur
Das Konzept basiert auf [[RAG Architecture]]. (Automatisch 'depends_on' durch Typ-Default, falls konfiguriert).
Das Konzept basiert auf [[RAG Architecture]].
```
### 6.2 Beispiel: Entscheidung (Decision Record)
Entscheidungen sind hoch gewichtet (`retriever_weight: 1.0`).
### 6.2 Beispiel: Advanced Tuning (Manuelles Override)
Hier zwingen wir das System, eine Entscheidung extrem kleinteilig (`strict`) zu zerlegen und in der Suche maximal zu priorisieren.
```markdown
---
@ -172,6 +171,9 @@ title: ADR: Wahl von Qdrant
type: decision
status: final
tags: [architektur, db]
# OVERRIDES: Wir wollen diese Notiz extrem wichtig machen und strikt trennen
chunking_profile: structured_smart_edges_strict
retriever_weight: 1.5
---
# Entscheidung: Qdrant
@ -180,13 +182,11 @@ Wir haben uns für Qdrant entschieden.
## Alternativen
Wir haben auch [[rel:similar_to Pinecone]] und [[rel:similar_to Weaviate]] betrachtet.
## Begründung
Qdrant erlaubt lokalen Betrieb und [[rel:solves Payload Filtering Requirements]].
```
---
## 7. Langfristige Stabilität
## 7. Virtual Schema Layer
Wir nutzen das Prinzip des **Virtual Schema Layers**. Wir kodieren keine Logik (wie `chunk_size`) in die Notizen. Das wird zentral in der `types.yaml` verwaltet. Das bedeutet für dich: Du kannst dich rein auf den Inhalt konzentrieren. Wenn wir die Chunking-Strategie ändern, müssen wir nicht 1000 Markdown-Dateien anfassen.
Grundsätzlich gilt das Prinzip des **Virtual Schema Layers**. Die Logik (wie `chunk_size`) wird zentral in der `types.yaml` verwaltet.
**Aber:** Als Power-User hast du über die oben genannten Overrides (`chunking_profile`) jederzeit die Möglichkeit, aus diesem Standard auszubrechen, wenn eine spezifische Notiz eine Sonderbehandlung benötigt.

View File

@ -3,7 +3,7 @@ doc_type: technical_reference
audience: developer, admin
scope: configuration, env
status: active
version: 2.6.0
version: 2.7.0
context: "Referenztabellen für Umgebungsvariablen und YAML-Konfigurationen."
---
@ -32,8 +32,7 @@ Diese Variablen steuern die Infrastruktur, Timeouts und Feature-Flags.
| `MINDNET_API_TIMEOUT` | `300.0` | Frontend Timeout (Erhöht für Smart Edge Wartezeiten). |
| `MINDNET_LLM_BACKGROUND_LIMIT`| `2` | **Traffic Control (Neu):** Max. parallele Import-Tasks (Semaphore). |
| `MINDNET_VAULT_ROOT` | `./vault` | Pfad für Write-Back Operationen (Drafts). |
| `MINDNET_HASH_COMPARE` | `Body` | Import-Strategie: `Body`, `Frontmatter` oder `Full`. |
| `MINDNET_HASH_SOURCE` | `parsed` | Hash-Quelle: `parsed`, `raw` oder `file`. |
| `MINDNET_CHANGE_DETECTION_MODE` | `full` | **Change Detection (Neu):** `full` (Text + Meta) oder `body` (nur Text). |
---
@ -41,9 +40,17 @@ Diese Variablen steuern die Infrastruktur, Timeouts und Feature-Flags.
Steuert das Import-Verhalten, Chunking und die Kanten-Logik pro Typ.
**Referenztabelle (Stand v2.6):**
### 2.1 Konfigurations-Hierarchie (Override-Logik)
Seit Version 2.7.0 gilt für `chunking_profile` und `retriever_weight` folgende Priorität:
| Typ (`type`) | Chunk Profile | Retriever Weight | Smart Edges? | Beschreibung |
1. **Frontmatter (Höchste Prio):** Ein Wert direkt in der Markdown-Datei überschreibt alles.
* *Beispiel:* `chunking_profile: structured_smart_edges_strict` im Header einer Notiz erzwingt diesen Splitter, egal welcher Typ eingestellt ist.
2. **Type Config:** Der Standardwert für den `type` (z.B. `concept`) aus `types.yaml`.
3. **Global Default:** Fallback aus `defaults` in `types.yaml`.
### 2.2 Typ-Referenztabelle
| Typ (`type`) | Chunk Profile (Standard) | Retriever Weight | Smart Edges? | Beschreibung |
| :--- | :--- | :--- | :--- | :--- |
| **concept** | `sliding_smart_edges` | 0.60 | Ja | Abstrakte Begriffe. |
| **project** | `sliding_smart_edges` | 0.97 | Ja | Aktive Vorhaben. |
@ -58,7 +65,9 @@ Steuert das Import-Verhalten, Chunking und die Kanten-Logik pro Typ.
| **goal** | `sliding_smart_edges` | 0.95 | Nein | Strategische Ziele. |
| **belief** | `sliding_short` | 0.90 | Nein | Glaubenssätze. |
| **profile** | `structured_smart_edges_strict` | 0.70 | Nein | Rollenprofile. Strict Split. |
| **principle** | `structured_smart_edges_strict_L3`| 0.95 | Nein | Prinzipien. Tiefer Split (H3). |
| **principle** | `structured_smart_edges_strict_L3`| 0.95 | Nein | Prinzipien. Tiefer Split (H3) für Mikro-Prinzipien. |
| **task** | `sliding_short` | 0.80 | Nein | Aufgaben. |
| **glossary** | `sliding_short` | 0.40 | Nein | Begriffsdefinitionen. |
| **default** | `sliding_standard` | 1.00 | Nein | Fallback. |
*Hinweis: `Smart Edges?` entspricht dem YAML-Key `enable_smart_edge_allocation: true`.*

View File

@ -3,7 +3,7 @@ doc_type: technical_reference
audience: developer, architect
scope: database, qdrant, schema
status: active
version: 2.6
version: 2.7.0
context: "Exakte Definition der Datenmodelle (Payloads) in Qdrant und Index-Anforderungen."
---
@ -31,13 +31,20 @@ Repräsentiert die Metadaten einer Markdown-Datei (1:1 Beziehung).
"note_id": "string (keyword)", // UUIDv5 (deterministisch) oder Slug
"title": "string (text)", // Titel aus Frontmatter
"type": "string (keyword)", // Logischer Typ (z.B. 'project', 'concept')
"retriever_weight": "float", // Numerische Wichtigkeit (0.0-1.0), aus types.yaml
"chunk_profile": "string", // Genutztes Profil (z.B. 'sliding_smart_edges')
"retriever_weight": "float", // Effektive Wichtigkeit (Frontmatter > Type > Default)
"chunk_profile": "string", // Effektives Profil (Frontmatter > Type > Default)
"edge_defaults": ["string"], // Liste der aktiven Default-Kanten
"tags": ["string"], // Liste von Tags aus Frontmatter
"aliases": ["string"], // Synonyme für Discovery (WP-11)
"created": "string (iso-date)", // Erstellungsdatum
"updated": "integer", // Timestamp (File Modification Time)
"fulltext": "string (no-index)" // Gesamter Text (nur für Recovery/Export)
"fulltext": "string (no-index)", // Gesamter Text (nur für Recovery/Export)
// NEU in v2.7: Multi-Hash für flexible Change Detection
"hashes": {
"body:parsed:canonical": "string", // Hash nur über den Text-Body
"full:parsed:canonical": "string" // Hash über Text + Metadaten (Tags, Title, Config)
}
}
```
@ -68,10 +75,12 @@ Die atomare Sucheinheit. Enthält den Vektor.
"text": "string (text)", // Reintext für Anzeige (ohne Overlap)
"window": "string (text)", // Text + Overlap (Basis für Embedding)
"ord": "integer", // Laufende Nummer (1..N) für Sortierung
"retriever_weight": "float", // Kopie aus Note (für Query-Speed)
"chunk_profile": "string", // Vererbt von Note
"retriever_weight": "float", // Geerbt von Note (für schnelles Re-Ranking)
"chunk_profile": "string", // Geerbt von Note (für Debugging/Filtering)
"neighbors_prev": ["string"], // ID des Vorgängers (Linked List)
"neighbors_next": ["string"] // ID des Nachfolgers
"neighbors_next": ["string"], // ID des Nachfolgers
"section": "string", // Pfad/Überschrift, zu der der Chunk gehört
"source_path": "string" // Relativer Pfad zur Datei
}
```
@ -99,7 +108,7 @@ Gerichtete Kanten zwischen Knoten. Stark erweitert in v2.6 für Provenienz-Track
"note_id": "string (keyword)", // Owner Note ID (Ursprung der Kante)
// Provenance & Quality (WP03/WP15)
"provenance": "keyword", // 'explicit', 'rule', 'smart' (NEU)
"provenance": "keyword", // 'explicit', 'rule', 'smart', 'structure'
"rule_id": "string (keyword)", // Traceability: 'inline:rel', 'explicit:wikilink', 'smart:llm'
"confidence": "float" // Vertrauenswürdigkeit (0.0 - 1.0)
}

View File

@ -3,7 +3,7 @@ doc_type: technical_reference
audience: developer, frontend_architect
scope: architecture, graph_viz, state_management
status: active
version: 2.6
version: 2.7.0
context: "Technische Dokumentation des modularen Streamlit-Frontends, der Graph-Engines und des Editors."
---
@ -28,7 +28,7 @@ Seit Version 2.6 ist das Frontend (`app/frontend/`) kein Monolith mehr, sondern
| `ui_utils.py` | **Helper.** Markdown-Parsing (`parse_markdown_draft`) und String-Normalisierung. |
| `ui_graph_service.py`| **Data Logic.** Holt Daten aus Qdrant und bereitet Nodes/Edges auf (unabhängig von der Vis-Library). |
| `ui_graph_cytoscape.py`| **View: Graph.** Implementierung mit `st-cytoscape` (COSE Layout). |
| `ui_editor.py` | **View: Editor.** Logik für Drafts und manuelles Editieren. |
| `ui_editor.py` | **View: Editor.** Logik für Drafts, manuelles Editieren und **Async Feedback**. |
### 1.2 Konfiguration (`ui_config.py`)
@ -117,7 +117,19 @@ Der `switch_to_editor_callback` in `ui_callbacks.py` implementiert folgende Kask
})
st.session_state["sidebar_mode_selection"] = "📝 Manueller Editor"
Dies garantiert, dass der Editor immer den **echten, aktuellen Stand** der Markdown-Datei anzeigt.
### 3.3 Async Save Pattern (Neu in v2.7 / WP-14)
Um Timeouts bei der Smart-Edge-Berechnung zu vermeiden, nutzt der Editor ein **"Fire & Forget"** Muster.
1. **Request:** UI sendet Markdown an `/ingest/save`.
2. **Backend:**
* Validiert Request.
* Speichert Datei auf Disk (Persistenz garantiert).
* Startet `BackgroundTasks` für LLM-Analyse und Embedding.
* Returniert sofort `status: queued`.
3. **UI Feedback:**
* Editor zeigt "Erfolgreich eingereiht".
* User muss nicht warten.
* (ToDo: WebSocket Notification bei Abschluss).
---

View File

@ -3,7 +3,7 @@ doc_type: technical_reference
audience: developer, devops
scope: backend, ingestion, smart_edges
status: active
version: 2.6.0
version: 2.7.0
context: "Detaillierte technische Beschreibung der Import-Pipeline, Chunking-Strategien und CLI-Befehle."
---
@ -11,28 +11,37 @@ context: "Detaillierte technische Beschreibung der Import-Pipeline, Chunking-Str
**Quellen:** `pipeline_playbook.md`, `Handbuch.md`
Die Ingestion transformiert Markdown in den Graphen. Entrypoint: `scripts/import_markdown.py`.
Die Ingestion transformiert Markdown in den Graphen. Entrypoint: `scripts/import_markdown.py` (CLI) oder `routers/ingest.py` (API).
## 1. Der Import-Prozess (13-Schritte-Workflow)
## 1. Der Import-Prozess (14-Schritte-Workflow)
Der Prozess ist **asynchron** und **idempotent**.
1. **Markdown lesen:** Rekursives Scannen des Vaults.
2. **Frontmatter extrahieren:** Validierung von Pflichtfeldern (`id`, `type`, `title`).
3. **Typauflösung:** Bestimmung des `type` via `types.yaml`.
4. **Note-Payload generieren:** Erstellen des JSON-Objekts für `mindnet_notes`.
5. **Chunking anwenden:** Zerlegung des Textes basierend auf dem `chunk_profile` (siehe Kap. 3).
6. **Smart Edge Allocation (WP15):**
1. **Trigger & Async Dispatch:**
* **API (`/save`):** Nimmt Request entgegen, validiert und startet Background-Task ("Fire & Forget"). Antwortet sofort mit `202/Queued`.
* **CLI:** Iteriert über Dateien und nutzt `asyncio.Semaphore` zur Drosselung.
2. **Markdown lesen:** Rekursives Scannen des Vaults.
3. **Frontmatter extrahieren:** Validierung von Pflichtfeldern (`id`, `type`, `title`).
4. **Config Resolution:**
* Bestimmung von `chunking_profile` und `retriever_weight`.
* **Priorität:** 1. Frontmatter (Override) -> 2. `types.yaml` (Type) -> 3. Default.
5. **Note-Payload generieren:**
* Erstellen des JSON-Objekts für `mindnet_notes`.
* **Multi-Hash Calculation:** Berechnet Hashtabellen für `body` (nur Text) und `full` (Text + Metadaten).
6. **Change Detection:**
* Vergleich des Hashes mit Qdrant.
* Strategie wählbar via ENV `MINDNET_CHANGE_DETECTION_MODE` (`full` oder `body`).
7. **Chunking anwenden:** Zerlegung des Textes basierend auf dem ermittelten Profil (siehe Kap. 3).
8. **Smart Edge Allocation (WP15):**
* Wenn `enable_smart_edge_allocation: true`: Der `SemanticAnalyzer` sendet Chunks an das LLM.
* **Traffic Control:** Request nutzt `priority="background"`. Semaphore (Limit via `.env`) drosselt die Last.
* **Resilienz:** Bei Timeout (Ollama) greift ein Fallback (Broadcasting an alle Chunks).
7. **Inline-Kanten finden:** Parsing von `[[rel:...]]`.
8. **Callout-Kanten finden:** Parsing von `> [!edge]`.
9. **Default-Edges erzeugen:** Anwendung der `edge_defaults` aus Registry.
10. **Strukturkanten erzeugen:** `belongs_to`, `next`, `prev`.
11. **Embedding (Async):** Generierung via `nomic-embed-text` (768 Dim).
12. **Strict Mode:** Abbruch bei leeren Embeddings oder Dimension 0.
13. **Diagnose:** Integritäts-Check nach dem Lauf.
9. **Inline-Kanten finden:** Parsing von `[[rel:...]]`.
10. **Callout-Kanten finden:** Parsing von `> [!edge]`.
11. **Default-Edges erzeugen:** Anwendung der `edge_defaults` aus Registry.
12. **Strukturkanten erzeugen:** `belongs_to`, `next`, `prev`.
13. **Embedding (Async):** Generierung via `nomic-embed-text` (768 Dim).
14. **Diagnose:** Integritäts-Check nach dem Lauf.
---
@ -44,6 +53,8 @@ Für regelmäßige Updates (Cronjob). Erkennt Änderungen via Hash.
```bash
export QDRANT_URL="http://localhost:6333"
export COLLECTION_PREFIX="mindnet"
# Steuert, wann eine Datei als "geändert" gilt
export MINDNET_CHANGE_DETECTION_MODE="full"
# Nutzt das Venv der Produktionsumgebung
/home/llmadmin/mindnet/.venv/bin/python3 -m scripts.import_markdown \
@ -68,6 +79,7 @@ ollama pull nomic-embed-text
python3 -m scripts.reset_qdrant --mode wipe --prefix "mindnet" --yes
# 2. Vollständiger Import (Force)
# --force ignoriert alle Hashes und schreibt alles neu
python3 -m scripts.import_markdown --vault ./vault --prefix "mindnet" --apply --force
```
@ -75,7 +87,7 @@ python3 -m scripts.import_markdown --vault ./vault --prefix "mindnet" --apply --
## 3. Chunking & Payload
Das Chunking ist profilbasiert und in `types.yaml` konfiguriert. Seit v2.6 unterscheiden wir zwischen **Sliding Window** und **Heading Split**.
Das Chunking ist profilbasiert und in `types.yaml` konfiguriert.
### 3.1 Profile und Strategien
@ -86,24 +98,27 @@ Das Chunking ist profilbasiert und in `types.yaml` konfiguriert. Seit v2.6 unter
| `sliding_smart_edges`| `sliding_window` | Max: 600, Target: 400 | Fließtexte mit hohem Wert (Projekte, Erfahrungen). |
| `structured_smart_edges` | `by_heading` | `strict: false` (Soft) | Strukturierte Texte, wo kleine Abschnitte gemergt werden dürfen. |
| `structured_smart_edges_strict` | `by_heading` | `strict: true` (Hard) | **Atomare Einheiten**: Entscheidungen, Werte, Profile. |
| `structured_smart_edges_strict_L3`| `by_heading` | `strict: true`, `level: 3` | Tief geschachtelte Prinzipien (Tier 2/MP1 Logik). |
### 3.2 Die `by_heading` Logik (Neu in v2.6)
### 3.2 Die `by_heading` Logik (v2.9 Hybrid)
Die Strategie `by_heading` zerlegt Texte anhand ihrer Struktur (Überschriften).
Die Strategie `by_heading` zerlegt Texte anhand ihrer Struktur (Überschriften). Sie unterstützt seit v2.9 ein "Safety Net" gegen zu große Chunks.
* **Split Level:** Definiert die Tiefe (z.B. `2` = H1 & H2 triggern Split).
* **Modus "Strict" (`strict_heading_split: true`):**
* Jede Überschrift (`<= split_level`) erzwingt einen neuen Chunk.
* *Ausnahme:* Wenn der vorherige Chunk leer war (nur Überschriften), wird gemergt (Context-Aware Merge).
* *Safety:* Wird ein Abschnitt zu lang (> `max`), wird trotzdem getrennt (Hybrid-Fallback).
* *Merge-Check:* Wenn der vorherige Chunk leer war (nur Überschriften), wird gemergt (verhindert verwaiste Überschriften).
* *Safety Net:* Wird ein Abschnitt zu lang (> `max` Token), wird auch ohne Überschrift getrennt.
* **Modus "Soft" (`strict_heading_split: false`):**
* Überschriften auf dem Split-Level (z.B. H2) lösen nur dann einen neuen Chunk aus, wenn der aktuelle Chunk die `target`-Größe erreicht hat.
* Überschriften *oberhalb* (z.B. H1) erzwingen immer einen Split (Hierarchie-Reset).
* **Hierarchie-Check:** Überschriften *oberhalb* des Split-Levels (z.B. H1 bei Level 2) erzwingen **immer** einen Split.
* **Füll-Logik:** Überschriften *auf* dem Split-Level (z.B. H2) lösen nur dann einen neuen Chunk aus, wenn der aktuelle Chunk die `target`-Größe erreicht hat.
* *Safety Net:* Auch hier greift das `max` Token Limit.
### 3.3 Payload-Felder (Qdrant)
* `text`: Der reine Inhalt (Anzeige im UI).
* `window`: Inhalt plus Overlap (für Embedding). Bei `by_heading` enthält dies oft den Kontext der Eltern-Überschrift.
* `text`: Der reine Inhalt (Anzeige im UI). Überschriften bleiben erhalten.
* `window`: Inhalt plus Overlap (für Embedding). Bei `by_heading` wird der Kontext (Eltern-Überschrift) oft vorangestellt.
* `chunk_profile`: Das effektiv genutzte Profil (zur Nachverfolgung).
---