From be090a43f2fc48e11647994f955bd9acc40c4a23 Mon Sep 17 00:00:00 2001 From: Lars Date: Sun, 9 Nov 2025 19:45:53 +0100 Subject: [PATCH] Dateien nach "docs" hochladen --- docs/knowledge_design.md | 343 ++++++++++++++++++--------------------- 1 file changed, 155 insertions(+), 188 deletions(-) diff --git a/docs/knowledge_design.md b/docs/knowledge_design.md index d0b58d6..615c8d9 100644 --- a/docs/knowledge_design.md +++ b/docs/knowledge_design.md @@ -1,249 +1,216 @@ # mindnet – Knowledge Design -**Version:** 1.4.0 (aktualisiert 2025-10-06) +**Version:** 1.5.0 (aktualisiert 2025-11-09) -## 1. Gesamtziel und Systemverständnis - -**mindnet** ist ein lokales Wissensnetzwerk, das alle meine Notizen, Projekte, Gedanken, Erfahrungen und Pläne als Markdown-Dateien speichert, automatisch importiert, semantisch in **Chunks** zerlegt und als **Graph-Struktur in Qdrant** ablegt. -Es ist die Grundlage für ein agentenfähiges, lokal betriebenes LLM-System, das meine Daten verknüpft, abfragt und erweitert. - -**Zentrale Ziele** -- Vollständige Repräsentation persönlichen Wissens in strukturierter, maschinenlesbarer Form -- Reproduzierbare Verarbeitung: Import → Chunking → Embedding → Edges → Graph -- Verlustfreie Roundtrip-Fähigkeit (Import ⇄ Export) -- Erweiterbarkeit für Agenten, RAG-Retriever und semantische Suche - -**Prinzipien** -- **Deterministisch:** IDs, Hashes und Edges wiederholbar -- **Portabel:** Markdown + YAML -- **Robust:** fehlertoleranter Parser -- **Idempotent:** keine Duplikate bei Re-Import -- **Erweiterbar:** neue Typen und Edge-Arten ohne Migration +> Dieses Dokument beschreibt das Ziel, die Architektur, die Datenmodelle sowie die Regeln und Prozesse für den Aufbau von **mindnet** – einem persönlichen, lokal betriebenen Wissensnetz, das auf Markdown-Quellen, Graph-Beziehungen und Vektor-Suche basiert. Es soll die Persönlichkeit, Werte und Erfahrungen des Besitzers widerspiegeln und künftig Antworten generieren, die diese Perspektive authentisch berücksichtigen. --- -## 2. YAML-Frontmatter-Schema +## 1. Ziel von mindnet -| Feld | Typ | Beschreibung | -|-------|-----|--------------| -| `title` | string | Menschlich lesbarer Titel | -| `id` | string | Eindeutige Note-ID (Slug) | -| `type` | enum | `concept`, `thought`, `experience`, `task`, `project`, `journal`, `person`, `meeting`, `milestone` | -| `status` | enum | `draft`, `active`, `done`, `archived` | -| `created` | date | ISO-Datum | -| `updated` | date | Letzte Änderung | -| `area` | string | Themen- oder Lebensbereich | -| `project` | string | Zugehöriges Projekt | -| `tags` | list | Strukturierte Tags (`area/…`, `topic/…`) | -| `depends_on` | list | IDs anderer Notizen | -| `assigned_to` | list | Beteiligte Personen | -| `embedding_exclude` | bool | Falls `true`, keine Embeddings | -| `hash_mode` | enum | Hash-Modus beim Import (`body`, `frontmatter`, `full`) | -| `priority` | enum/int | 1–5 oder `low` / `med` / `high` | -| `effort_min`, `due` | int/date | Aufwand / Termin | -| `aliases` | list | Alternative IDs | -| `lang` | string | ISO-Sprachcode | -| `source` | string | Herkunft / Referenzquelle | +**1.1 Zweck** +- mindnet dient als persönliches Wissensnetz, das Erfahrungen, Werte, Prinzipien, Ziele und prägenden Ereignisse langfristig strukturiert. +- Es ermöglicht spätere Einsichten in Entscheidungen und Entwicklungen und kann in Zukunft für die Familie (z. B. Kinder) eine nachvollziehbare Quelle sein. -**Pflichtfelder:** `title`, `id`, `type`, `status`, `created` -**Optionale Felder:** alle übrigen +**1.2 Leitidee** +- Statt einer reinen Dokumentablage wird Wissen durch **Knoten (Notes/Chunks)** und **Kanten (Edges)** vernetzt. +- Antworten sollen **persönlich** kontextualisiert werden (Perspektive, Konditionierung, Persönlichkeit). + +**1.3 Langfristigkeit** +- Stabiler, zukunftsfähiger Entwurf; spätere Massenmigrationen sollen vermieden werden. +- Architektur unterstützt schrittweise Erweiterung (neue Quellen, neue Agenten, neue Regeln). --- -## 3. Dateinamen und Ordner +## 2. Zielarchitektur (High Level) -- Format: `YYYY-MM-DD_title.md` oder `slug.md` -- Strukturierte Ordner: - - `10_thoughts/`, `20_concepts/`, `30_projects/`, `40_experiences/`, … -- Alle Pfade relativ; Unterstriche statt Leerzeichen +- **Datenquellen:** Markdown-Vault (Obsidian-kompatibel), perspektivisch weitere Quellen (MediaWiki, PDFs, Web-Exporte, E-Mail-Auszüge). +- **Import-Pipeline:** Parser → Frontmatter/Body → Chunking → Embedding → Qdrant (Notes/Chunks/Edges). +- **Speicher:** Qdrant (Vektoren + Payload + Textindex), Dateien bleiben im Filesystem (Quelle ist Referenz). +- **Graph-Schicht:** Edges explizit modelliert (Typ, Richtung, Evidenz, Confidence); optionale abgeleitete Edges per Batch-Job. +- **Retriever/Composer:** Hybrid-Retrieval (Vektor + Filter + optional Volltext), Komposition zu Antwortkandidaten. +- **Erklärbarkeit:** Begründungspfade (Top-Chunks, Graph-Kette, Provenienz). +- **Schnittstellen:** REST/CLI, n8n-Glue, lokale LLM-Anbindung (Ollama). --- -## 4. Link- und Edge-Design +## 3. Collections in Qdrant -**Verlinkungen** -- Wikilinks: `[[note-id]]` oder `[[Titel|note-id]]` -- Automatische Edges aus Text und Frontmatter - -**Edge-Typen in Qdrant** - -| Typ | Bedeutung | Quelle | Scope | -|------|------------|--------|--------| -| `belongs_to` | Chunk → Note | intern | chunk | -| `prev` / `next` | Reihenfolge | intern | chunk | -| `references` | explizite Wikilinks | Text | chunk | -| `backlink` | Gegenkante zu `references` | abgeleitet | note | -| `depends_on` | YAML-Abhängigkeiten | YAML | note | -| `assigned_to` | YAML-Zuweisung | YAML | note | -| `unresolved` | Ziel fehlt (Stub) | abgeleitet | chunk | - -**Edge-Schlüssel** -- `source_id`, `target_id`, `kind`, `scope`, `note_id` -- Dedup-Schlüssel: Kombination aus `(kind, source_id, target_id, scope)` +- `mindnet_notes` – Note-Metadaten (id, title, type, path, timestamps, tags, …). +- `mindnet_chunks` – inhaltstragende Segmente inkl. Vektoren und Textindex. +- `mindnet_edges` – Beziehungen (src/dst, relation, direction, evidence, confidence, …). +- (optional) `mindnet_people` – strukturierte Personenobjekte (Eigen-/Fremdbezug). --- -## 5. Chunking-Modell +## 4. Identitäten & IDs -**Chunk-Datenstruktur** -| Feld | Beschreibung | -|-------|---------------| -| `note_id` | Zugehörige Note | -| `chunk_index` | Laufende Nummer | -| `text` | Originalabschnitt | -| `window` | Text + Overlap links/rechts | -| `overlap_left` | Länge des linken Overlaps | -| `overlap_right` | Länge des rechten Overlaps | -| `embedding` | 384-dimensionaler Vektor | -| `tokens` | Tokenanzahl (optional) | - -**Chunking-Regeln (aus `chunking_strategy.md`)** -- Trennung nach Absätzen, Überschriften, Listen, Tabellen -- Token-Zielgröße 350–500 (max 600) -- Overlap: 30–40 % für semantische Kohärenz -- Overlap wird in `window` integriert, sodass `text ≠ window` +- **Deterministische IDs** für Notes (z. B. Namespace-basierte UUIDv5) und stabile, ableitbare IDs für Chunks/Edges. +- ID-Stabilität ist Voraussetzung für Idempotenz (Re-Imports ohne Duplikate). --- -## 6. Hash-Strategie und Änderungsverfolgung +## 5. Frontmatter & Typen -**Zweck:** Nur bei realer Inhaltsänderung re-indexieren - -| Umgebungsvariable | Beschreibung | -|--------------------|--------------| -| `MINDNET_HASH_COMPARE` | Vergleichsquelle (`Body`, `Full`, `Frontmatter`) | -| `MINDNET_HASH_SOURCE` | Rohtext vs. geparst (`raw` / `parsed`) | -| `MINDNET_HASH_NORMALIZE` | Normalisierung (`canonical` / `none`) | - -**Basismodi** -- `body` → Nur Textkörper -- `frontmatter` → Nur Metadaten -- `full` → Kombination -- Hash = SHA-256(canonicalized_input) - -Bei Änderung: Re-Import, neue Embeddings, Edges werden aktualisiert. +- Pflichtfelder: `id`, `title`, `type`, `created`, `updated`, `tags`, `source_path`. +- Note-Typen (Auszug): `experience`, `principle`, `value`, `goal`, `role`, `persona`, `plan`, `project`, `journal`, `reference`, `translation`. +- **types.yaml** definiert Regeln/Defaults je Typ und für Relationstypen (siehe Abschnitt 10). --- -## 7. Qdrant-Speicherstruktur +## 6. Chunking-Strategie -| Collection | Inhalt | Primärfelder | Embedding | -|-------------|---------|---------------|------------| -| `mindnet_notes` | Notes mit Fulltext & Hash | `note_id` | optional | -| `mindnet_chunks` | Chunks mit Text, Window, Embedding | `chunk_id`, `note_id` | 384 d | -| `mindnet_edges` | Graphkanten | `edge_id`, `source_id`, `target_id` | — | - -**Upsert-Strategie** -- Idempotente UUIDv5-IDs -- Keine Duplikate durch deterministische Signaturen -- `purge-before-upsert` zur Bereinigung - -**Indizes** -- notes: `note_id`, `hash_signature` -- chunks: `note_id`, `chunk_index` -- edges: `(kind, source_id, target_id, scope)` +- Satz- bis Absatz-Chunks, moderate Überlappung; Meta-Felder verweisen auf Note/Quelle. +- Named Vectors (z. B. `content`, optional `title`, `tags`) ermöglichen hybride Scores. --- -## 8. Fehler-Toleranz und Parser-Robustheit +## 7. Embeddings & Vektoren -- UTF-8 mit Fallback: ersetzt ungültige Bytes (`errors="replace"`) -- Ignoriert Nullbytes, BOM, exotische Zeilenenden -- Erkennt defekte oder leere YAML-Header und überspringt sie -- Logt Problemfälle (`read_markdown failed`, `make_note_payload returned non-dict`) -- Bei Fehlern: Import → warn → continue +- Einheitliche Metrik (cosine), reproduzierbares Embedding-Setup. +- Konsistenz über Zeit durch Versionsfeld (`embedding_model`, `embedding_version`). --- -## 9. Tests & Validierung +## 8. Volltext & Filter -**Integrationstests** -- Roundtrip: Import → Export → Compare (`compare_vaults.py`) -- Chunk-Integrität: `verify_chunks_integrity.py` -- Hash-Audit: `hash_reporter.py` -- Window-Vergleich: `check_chunks_window_vs_text.py` - -**Erwartete Ergebnisse** -- Alle Notes werden erkannt -- `window ≠ text` bei > 60 % der Chunks -- Roundtrip-Vergleich liefert „OK“ -- Edge-Anzahl entspricht Modell (belongs_to = #Chunks, next/prev ≈ #Chunks – 1) +- Textindex auf `mindnet_chunks.body` für exakte Term/Operator-Queries. +- Payload-Filter zur schnellen Einschränkung (tags, types, time-buckets, visibility u. a.). --- -## 10. Export & Roundtrip-Verhalten +## 9. Edges – Beziehungen -- `export_markdown.py` erzeugt identische Markdown-Dateien -- Schreibt YAML + Body in korrekter Reihenfolge -- Roundtrip-Prüfung (`compare_vaults.py`) validiert: - - vollständigen Body - - unveränderte Hash-Signatur - - gleiche Chunkzahl +- **Explizit**: Jede tatsächliche Beziehung wird als Kante gespeichert (kein Workaround). +- Felder u. a.: `src_id`, `dst_id`, `relation`, `direction`, `confidence (0–1)`, `evidence` (Chunk-IDs), `created_at`, `updated_at`. +- **edge_defaults** liefern **Interpretations-Hints** (Gewichte, Symmetrie, Transitivität) und parametrisieren abgeleitete Edges; sie **ersetzen** keine Originalkanten. --- -## 11. Graph-Schicht und WP-04-Integration +## 10. Regeln & Policies (types.yaml) -- Qdrant fungiert als Graph-Backend -- `graph/service.py` (WP-04): stellt API für Mehrhop-Abfragen bereit -- Unterstützt: - - `expand(note_id, hops=2)` - - `resolve_unresolved()` - - `neighbors(kind=…)` -- Grundlage für spätere **Retriever-Funktionen** (LLM / Agenten) +- Per Typ/Relation: + - Default-Eigenschaften (Gewicht, Directedness, Symmetrie, Transitivität). + - Scoring-Hooks für Graph-Kontext im Retriever. + - (später) Privacy-Hooks je Relation (Mindest-Visibility). --- -## 12. Agenten- und LLM-Integration +## 11. Retrieval & Ranking (Komposition) -**Retriever-Pipeline** -1. Suche top-k Chunks (cosine distance) -2. Erweiterung um Edges (`references`, `backlinks`) -3. Kontext-Assembling via `window`-Text -4. Prompt-Generierung - -**Agent-Use-Cases** -- Automatisches Tagging (`type`, `status`) -- Vorschläge für neue Edges -- Auflösen von `unresolved`-Referenzen -- Auto-Import externer Quellen (MediaWiki, PDFs, Webseiten) +- Hybrid: Vektor-Score + Filter + optional BM25/Volltext. +- Zeitgewicht (Decays) und Graph-Kontext werden komponiert (Formel siehe 16.3). +- Konfiguration über `.env`/`config.yaml` (gewichts- und halbwertszeit-basiert). --- -## 13. Erweiterbarkeit +## 12. Erklärbarkeit -- Neue Edge-Typen: `inspired_by`, `relates_to`, `contradicts` -- Neue Note-Typen: `decision`, `resource`, `recommendation` -- Embedding-Engines austauschbar (MiniLM → LaBSE → E5) -- Versionierte Chunking-Strategien (`chunk_config.py`) +- „Warum-Pfad“: Top-Chunks mit Score-Zerlegung (Vektor/Time/Graph), Graph-Kette, Provenienz. +- Mehrschichtige Narrative (Kindheit/Erlebnisse, Werte/Prinzipien, Ziele/Leitbild, Gegenwart). --- -## 14. Qualitätssicherung und Best Practices +## 13. Betrieb & Sicherheit -- Validierung vor Upsert -- Keine Leer-Chunks -- Vollständige Metadaten in Notes -- Tests in `tests/` automatisch ausführbar (`run_e2e_roundtrip.sh`) -- Ergebnis: „Roundtrip OK“ und `verify_chunks_integrity` = OK +- Lokal auf Single-Node starten (Backups via Snapshots). +- Zugriff nur intern/Reverse-Proxy; Festplattenverschlüsselung OS-seitig. +- Migrationspfad zu Qdrant-Distributed (Shards, Replikation) einplanen. --- -## 15. Änderungsverlauf +## 14. Qualität & Monitoring -**v1.4.0 (2025-10-06)** -- Neu: `window` vs `text` Feld in `mindnet_chunks` -- Neu: Hash-Modi (`body`, `frontmatter`, `full`) mit Env-Steuerung -- Neu: Baseline-Modus für Vergleich -- Parser → fehlertolerant (UTF-8 replace) -- Roundtrip-Test vollständig integriert -- Graph-Service und Mehrhop-Abfragen (WP-04-Vorbereitung) -- `purge-before-upsert` und `--note-scope-refs` Parameter ergänzt - -**v1.3.0 (2025-09-09)** -- Hash-Normalisierung und Edge-Scope -- Roundtrip-Tests, Agenten-Integration - -**v1.2.0 (2025-09-02)** -- Grundstruktur des Knowledge-Designs +- Offline-Eval-Sets, Telemetrie (lokal), Drift-Checks, manuelle Reviews. +- Kennzahlen: Hit-Rate, Overlap, Quellen-Alter, Erklärungspfad-Nutzung. --- + +## 15. Offene Punkte + +- Ausdetaillierung `types.yaml` (Relationen, Hooks). +- UI-Oberfläche für Erklärpfade und Provenienz. +- Batch-Jobs für abgeleitete Edges. + +--- + +## 16. Ergänzungen 2025-11-09 (v1.5.0) + +**Kontext:** Basierend auf den neuen Rahmenbedingungen (nur Deutsch; perspektivische externe Abfragen; einheitliche Vertraulichkeit mit Option auf feinere Stufen; Recency-Priorisierung als Default; Regeln später konfigurierbar; zunächst lokale Speicherung mit optionaler Migration; heutige Hardware, später skalierbar; hohe Erklärbarkeit mit mehreren Erklärungsebenen) werden folgende Entscheidungen und Erweiterungen getroffen. Alle bisherigen Inhalte bleiben gültig und werden **nicht** verändert. + +### 16.1 Sprach- und Inhaltsrichtlinie (nur Deutsch) +- `lang: "de"` als verpflichtendes Feld in allen Note-, Chunk- und Edge-Payloads. +- Für spätere Mehrsprachigkeit **nicht** die Collection splitten, sondern ein Feld `lang` + optional `lang_original` behalten; Translation-Artefakte als eigener `type: translation` (verweisend auf `source_id`). + +### 16.2 Vertraulichkeit & Sichtbarkeit +- Heute: einheitliche Stufe `visibility: "internal"`. +- Vorausschauend: reservierte Felder in allen Payloads + - `visibility`: `"public" | "internal" | "restricted"` + - `sensitivity`: Integer 0–3 (0 = unkritisch, 3 = hochsensibel) + - `acl`: Liste erlaubter Rollen/Personen-IDs (App-Layer erzwingt Filter vor Query). +- Access-Control erfolgt **im Applikations-Layer** mittels Qdrant-Payload-Filtern (`must: [ { key: "visibility", match: { any: [...] }}, ... ]`); Qdrant bleibt „dumm“ in Bezug auf ACL. + +### 16.3 Recency-Modell & Ranking (konfigurierbar) +- Default: **Zeitnähe** priorisieren (sanfte Abwertung älterer Inhalte). +- Im Retrieval kombinieren wir: + 1) Vektor-Score (cosine) aus Qdrant + 2) Zeitgewicht `time_decay = exp( - ln(2) * age_days / half_life_days )` + 3) Graph-Kontext aus Edges (z. B. Degree, Path-Hops zum Anker „Ich/Persona“) +- Konfigurierbare Gewichte (per `.env` oder `config.yaml`): + ```text + FINAL_SCORE = w_vec * norm(vec_score) + + w_time * time_decay + + w_graph * graph_context_score + # Vorschlag: w_vec=0.70, w_time=0.20, w_graph=0.10; half_life_days=365 + ``` +- Für Fragen, die „zeitlos“ sind, kann `half_life_days = inf` gesetzt werden (kein Decay). + +### 16.4 Erklärbarkeit („Warum diese Antwort?“) +- Jeder Antwort wird ein **Erklärpfad** mitgegeben (optional im UI): + - Top-Chunks (mit Score-Zerlegung w_vec/w_time/w_graph) + - **Kausalpfad** im Graphen: `Note → Edge(relation, confidence) → Note …` + - **Provenienz** (Quelle, Erstellungszeit, letzte Änderung). +- Ein **Multi-Layer-Explanations**-Modul ordnet Beiträge zu: Kindheit/Erlebnisse, Werte & Prinzipien, aktuelle Ziele/Leitbild, Gegenwartskontext. + +### 16.5 Qdrant-Schemata (Ergänzungen, rückwärtskompatibel) +- **Collections** bleiben: `mindnet_notes`, `mindnet_chunks`, `mindnet_edges` (+ `mindnet_people` falls noch nicht vorhanden). +- Gemeinsame Zusatzfelder (alle Payloads): + - `lang: "de"` + - `visibility`/`sensitivity`/`acl` (s. 16.2) + - `created_at` (ISO-8601), `updated_at` (ISO-8601), `age_days` (App-seitig berechnet) +- **Chunks**: + - Named-Vectors (z. B. `"content"`, optional `"title"`, `"tags"` für Hybrid-Scores). + - `text_index` auf `body` für BM25-ähnliche Volltextsuche (Qdrant-Textindex). + - `recency_group`: Jahr-Monat `YYYY-MM` (ermöglicht Pre-Filter für „letzte N Monate“). +- **Edges** (explizit, keine Workarounds): + - Felder: `src_id`, `dst_id`, `relation`, `direction`, `confidence` (0–1), `evidence` (Chunk-IDs), `created_at`, `updated_at`. + - **edge_defaults** bleiben als **Interpretations-Hints**: z. B. `default_weight`, `symmetry`, `transitivity`. Sie ersetzen **nicht** echte Kanten, sondern parametrisieren abgeleitete/zusätzliche Kantenbildung. + - Abgeleitete Edges: optionaler Batch-Job erzeugt *ergänzende* Kanten entlang `types.yaml`-Regeln (z. B. Backlinks, „inspired_by“ aus Zitaten), niemals statt der Originalkanten. + +### 16.6 Regeln & Typen (konfigurierbar) +- `types.yaml` erweitert um: + - Relationstypen mit Default-Eigenschaften (`weight`, `directed`, `symmetric`, `transitive`). + - **Scoring-Hooks**: pro Relation optionaler Einfluss auf `graph_context_score`. + - **Privacy-Hooks**: pro Relation Minimal-Visibility (z. B. Beziehungen zu Personen sind mindestens `internal`). + +### 16.7 Speicher- & Betriebsstrategie (heute lokal, später skalierbar) +- **Heute**: Single-Node Qdrant mit HNSW-Index, Text-Index und Payload-Filtern; regelmäßiges Backup (Snapshots). +- **Morgen**: Migrationspfad in **Qdrant-Distributed** (Shards, ggf. Replikation) bei Bedarf; Parameter-Gleichheit sichern (named-vectors, Metrik, HNSW-Param). +- **Sicherheit**: Zugriff nur über internes Netz/Reverse-Proxy, Auth vor Qdrant; Festplatten-Verschlüsselung auf OS-Ebene (z. B. LUKS). + +### 16.8 Persona-Layer („meine Essenz“) +- Eigenständiger **Persona-Knoten** (z. B. Note `person/lars`), verbunden mit: + - Werten/Prinzipien, Leitbild, prägenden Erlebnissen, Zielen, Rollen. + - Jede Antwort kann gegen diesen Knoten **kontextualisiert** werden (Graph-Pfadnähe). +- Feld `persona_weight` in Chunks/Notes zur Priorisierung persönlicher Relevanz. + +### 16.9 Evaluierung & Qualitätssicherung +- **Offline-Sets** aus echten Fragen (inkl. gewünschter Perspektiven) mit erwarteten Top-Quellen. +- **Telemetrie** (lokal): Query-Arten, Treffer-Overlaps, Zeitgewicht-Effekte, „Warum-Pfad“ genutzt/ignoriert. +- **Drift-Checks**: Anteil sehr alter vs. neuer Quellen in Antworten; manuelle Reviews. + +### 16.10 Offene Punkte / Nächste Schritte +1) `types.yaml` um Relationseigenschaften erweitern (s. 16.6). +2) Retriever-Komposition inkl. Zeitgewicht (s. 16.3) implementieren. +3) Explanations-Pfad inkl. Provenienzoberfläche (s. 16.4) im UI. +4) Feld-Erweiterungen in Import-Pipelines (`lang`, `visibility`, Zeitfelder). +5) Optional: Batch-Job für abgeleitete Edges nach Regeln (ergänzend, nicht ersetzend).