mindnet/docs/mindnet_functional_architecture.md
2025-12-08 16:14:52 +01:00

294 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.2 Fachliche Architektur
**Datei:** `docs/mindnet_functional_architecture_v2.2.md`
**Stand:** 2025-12-08
**Status:** **FINAL** (Integrierter Stand WP01WP05)
> Dieses Dokument beschreibt **was** Mindnet fachlich tut und **warum** mit Fokus auf die Erzeugung und Nutzung von **Edges** (Kanten), die Logik des Retrievers und den neuen **RAG-Chat** (Persönlichkeit). Die technische Umsetzung wird im technischen Dokument detailliert.
---
## 0) Zielbild & Grundprinzip
Mindnet wandelt Obsidian-Markdown-Notizen in einen **dynamischen Graphen aus Punkten und Kanten** um.
Die drei zentralen Artefakt-Sammlungen lauten:
- `mindnet_notes` genau **eine** Note pro Markdown-Datei (Metadaten & Hashes)
- `mindnet_chunks` semantische Teilstücke einer Note (Fenster/„Chunks“)
- `mindnet_edges` gerichtete Beziehungen zwischen Knoten (Chunks/Notes)
Die Import-Pipeline erzeugt diese Artefakte **deterministisch** und **idempotent** (erneute Läufe überschreiben konsistent statt zu duplizieren). Die Import-Schritte sind: *parse → chunk → edge → upsert*.
---
## 1) Notizen & Chunks (fachliche Perspektive)
### 1.1 Notiz (Note)
- Repräsentiert eine fachliche Einheit (z. B. *„Vector DB Basics“*, *„KI-Projekt“*).
- Trägt Eigenschaften (Titel, Typ, Zeitstempel, optionale Policies).
- **Typ** (*type*) steuert u. a. Chunk-Profil und Default-Relationen (siehe §4).
- **retriever_weight** und **chunk_profile** werden systematisch an Note **und** Chunks gespiegelt, damit der Retriever beides nutzen kann.
### 1.2 Chunk
- Ausschnitt/Textfenster aus der Note, als eigenständiger Such-Anker.
- Jeder Chunk gehört **genau einer** Note.
- Chunks bilden eine Sequenz (1…N) das ermöglicht *next/prev*.
- **Neu in v2.2:** Alle Kanten entstehen ausschließlich zwischen Chunks (Scope="chunk"), nie zwischen Notes direkt. Notes dienen nur noch als Metadatencontainer.
> **Wichtig:** Chunking-Profile (short/medium/long) kommen aus `types.yaml` (per Note-Typ), können aber lokal überschrieben werden. Die effektiven Werte werden bei der Payload-Erzeugung bestimmt.
---
## 2) Edges fachliche Typen & Bedeutung
Edges kodieren Beziehungen. Sie sind **gerichtet** und werden in `mindnet_edges` gespeichert. Die Erzeugung folgt einer strengen Priorität: **Inline > Callout > Defaults > Struktur**.
### 2.1 Struktur-Kanten (Das Skelett)
- **belongs_to**: *Chunk → Note* (Zuordnung)
- **next / prev**: Kettenbeziehungen zwischen aufeinanderfolgenden Chunks derselben Note.
→ ermöglichen „lineares Weiterlesen“ oder Kontextpfade in Antworten.
Diese Kanten entstehen immer, unabhängig von Inhalten.
### 2.2 Inhalts-Kanten (explizit)
Hier unterscheidet v2.2 präzise zwischen verschiedenen Quellen der Evidenz:
1. **Explizite Inline-Relationen (Höchste Priorität):**
Im Fließtext notierte, semantisch qualifizierte Relationen.
* Syntax: `[[rel:depends_on Embeddings 101]]`
* Fachliche Aussage: "Hängt ab von", "Ähnlich zu".
* *rule_id*: `inline:rel`
* *confidence*: ~0.95
2. **Callout-Edges (Kuratierte Listen):**
Redaktionell gepflegte Listen am Ende einer Notiz (z.B. "Siehe auch").
* Syntax: `> [!edge] related_to: [[Vector DB Basics]]`
* *rule_id*: `callout:edge`
* *confidence*: ~0.90
3. **Wikilinks (Standard-Referenzen):**
Der klassische Obsidian-Link.
* Syntax: `[[Vector DB Basics]]`
* Typ: `references`
* *rule_id*: `explicit:wikilink`
* *confidence*: 1.0
> Alle expliziten Quellen (Wikilink, Inline-Rel, Callout) sind **Primärbelege**.
### 2.3 Typ-basierte Default-Kanten (Regelbasiert)
Jede Note hat einen *Typ* (z. B. `concept`, `project`, `profile`). In `config/types.yaml` definieren wir pro Typ **edge_defaults**, z. B.:
- `concept`: `["references","related_to"]`
- `project`: `["references","depends_on"]`
Regel: **Für jede gefundene explizite Referenz** (s. o.) werden **zusätzliche** Edges nach diesen Defaults erzeugt.
Beispiel: Ein *project* mit `edge_defaults=["depends_on"]` erzeugt zu *jedem* explizit referenzierten Ziel **zusätzlich** eine `depends_on`-Kante.
Diese Kanten tragen *provenance=rule* und eine **rule_id** der Form `edge_defaults:{note_type}:{relation}` sowie eine geringere Confidence (~0.7).
---
## 3) Edge-Payload Felder & Semantik
Jede Kante hat mindestens:
- `kind` Beziehungsart *(belongs_to, next, prev, references, related_to, depends_on, similar_to, …)*
- `scope` `"chunk"` (Standard in v2.2)
- `source_id`, `target_id` Quell-/Ziel-Knoten (Chunk-IDs oder Note-Titel bei unresolved Targets)
- `note_id` **Owner-Note** (die Note, aus der die Kante stammt)
Erweiterte/abgeleitete Felder (WP03 Superset):
- `provenance` `"explicit"` (Wikilink/Inline/Callout) oder `"rule"` (Typ-Defaults)
- `rule_id` maschinenlesbare Regelquelle (z.B. `inline:rel`, `edge_defaults:project:depends_on`)
- `confidence` 0.01.0; Heuristik zur Gewichtung im Scoring.
**Dedup-Schlüssel** (fachlich): Gleichlautende `(source_id, target_id, kind, scope, rule_id)` werden nicht mehrfach geschrieben.
---
## 4) Typ-Registry (`config/types.yaml`)
### 4.1 Zweck
- Steuert **Chunking-Profile** (`short|medium|long`) **pro Typ**
- Liefert **retriever_weight** (Note-/Chunk-Gewichtung im Ranking) **pro Typ**
- Definiert **edge_defaults** je Typ (s. o.)
Der Importer lädt die Registry aus `MINDNET_TYPES_FILE` oder nutzt Fallbacks. **Frontmatter-Overrides** für Profile werden in v2.2 weitgehend ignoriert zugunsten einer zentralen Governance in der YAML-Datei.
### 4.2 Beispiel (auslieferungsnah)
version: 1.0
types:
concept:
chunk_profile: medium
edge_defaults: ["references", "related_to"]
retriever_weight: 0.60
project:
chunk_profile: long
edge_defaults: ["references", "depends_on"]
retriever_weight: 0.97
**Auflösung im Importer**
- `effective_chunk_profile(note_type, registry)``"short|medium|long"|None`
- `effective_retriever_weight(note_type, registry)``float|None`
- Ergebnis wird in `note_payload` **und** `chunk_payloads` gespiegelt.
---
## 5) Der Retriever (Funktionaler Layer)
Der Retriever ist in v2.2 der zentrale Zugangspunkt. Er realisiert die **Hybride Suche**.
### 5.1 Scoring-Modell
Die Relevanz eines Treffers ergibt sich nicht mehr nur aus Textähnlichkeit, sondern aus einer gewichteten Formel:
total_score =
semantic_weight * semantic_score
+ edge_weight * edge_bonus
+ centrality_weight * centrality_bonus
+ type_weight * retriever_weight
* **semantic_score:** Vektorähnlichkeit (Qdrant).
* **retriever_weight:** Wichtigkeit des Typs (z.B. Projekte > Quellen).
* **edge_bonus:** Belohnung für Chunks, die im Kontext der Anfrage stark vernetzt sind (Summe der Confidence eingehender relevanter Kanten).
* **centrality_bonus:** Belohnung für Knoten, die zentrale Hubs im lokalen Graphen darstellen.
### 5.2 Erklärbarkeit (Explainability) WP04b
Der Retriever ist keine Blackbox mehr. Er liefert auf Wunsch (`explain=True`) eine strukturierte Begründung (`Explanation`-Objekt).
**Die "Warum"-Logik:**
1. **Semantik:** Prüfung der Cosine-Similarity ("Sehr hohe textuelle Übereinstimmung").
2. **Typ:** Prüfung des `retriever_weight` ("Bevorzugt, da Entscheidung").
3. **Graph (Kontext):**
* **Hub (Outgoing):** Worauf verweist dieser Treffer? ("Verweist auf Qdrant").
* **Authority (Incoming):** Wer verweist auf diesen Treffer? ("Wird referenziert von Projekt Alpha").
Die API gibt diese Analysen als menschenlesbare Sätze (`reasons`) und als Datenstruktur (`score_breakdown`) zurück.
---
## 6) Der RAG-Chat & Persönlichkeit (WP05)
Seit WP-05 kann Mindnet nicht nur suchen, sondern als **KI-Zwilling** antworten.
### 6.1 Context Intelligence (Der "Enriched Context")
Kleine Sprachmodelle (SLMs wie Phi-3) scheitern oft an komplexen Zusammenhängen. Mindnet löst dies durch **explizite Metadaten-Injection** in den Prompt.
Dem LLM wird nicht nur der Text eines Chunks gezeigt, sondern auch sein Typ und Score:
* *"Hier ist eine Notiz vom Typ `[DECISION]`. Sie erklärt, warum wir etwas tun."*
* *"Hier ist eine Notiz vom Typ `[PROJECT]`. Sie erklärt, was wir tun."*
Dadurch kann das System Fragen wie *"Warum nutzen wir X?"* korrekt beantworten, indem es die Begründung aus der Decision-Notiz zieht, selbst wenn die Frage auf das Projekt abzielte.
### 6.2 Persönlichkeit (Late Binding)
Die "Persönlichkeit" von Mindnet (Stil, Werte, Tonfall) ist **nicht** im Python-Code verankert, sondern in `config/prompts.yaml`.
* **System Prompt:** Definiert die Rolle ("Ich bin dein digitales Gedächtnis...").
* **Werte:** Pragmatismus, Transparenz (kein Halluzinieren), Vernetztes Denken.
* **Flexibilität:** Die Persönlichkeit kann jederzeit angepasst werden (z.B. "Sei kritischer"), ohne das System neu zu starten.
---
## 7) Feedback & Lernen WP04c
Das System verfügt nun über ein **Kurzzeitgedächtnis für Interaktionen**, das die Basis für zukünftiges Lernen bildet.
### 7.1 Der Feedback-Loop
1. **Suche (Situation):**
Wenn ein Nutzer eine Anfrage stellt, loggt Mindnet die "Situation":
* Den Query-Text.
* Die Top-K Ergebnisse.
* Den exakten `score_breakdown` zu diesem Zeitpunkt.
* Eine eindeutige `query_id` wird generiert.
2. **Bewertung (Label):**
Der Nutzer (oder ein Agent) bewertet einen spezifischen Treffer (`node_id`) positiv oder negativ (Score 1-5).
Dieses Feedback wird unter Referenzierung der `query_id` gespeichert.
3. **Lernen (Perspektive WP08):**
Durch die Verknüpfung von Situation und Bewertung entstehen Trainingsdaten. Mindnet kann später analysieren: *"Nutzer bevorzugen Treffer mit hohem Edge-Bonus, auch wenn der Text weniger passt."* -> Konsequenz: `edge_weight` erhöhen.
---
## 8) Confidence & Provenance wozu?
Der Retriever kann Edges gewichten:
- **provenance**: *explicit* > *rule*
- **confidence**: numerische Feinsteuerung
- **retriever_weight (Note/Chunk)**: skaliert die Relevanz des gesamten Knotens
Eine typische Gewichtung (konfigurierbar in `retriever.yaml`) ist:
`explicit: 1.0`, `rule: 0.8`. Damit bevorzugt der Graph **kuratiertes Wissen** (explizit notierte Links) vor „erweiterten“ Default-Ableitungen.
---
## 9) Semantik ausgewählter `kind`-Werte
- `references` „Nutzt/erwähnt“; neutral, aber stützend für Kontext.
- `related_to` Ähnlichkeit/Verwandtschaft (symmetrisch interpretierbar).
- `similar_to` noch engere Ähnlichkeit; oft aus Inline-Rel (bewusst gesetzt).
- `depends_on` fachliche Abhängigkeit (z. B. „Projekt X hängt von Y ab“).
- `belongs_to`, `next`, `prev` Struktur.
> Symmetrische Relationen (z. B. `related_to`, `similar_to`) können **explizit** nur einseitig notiert sein, aber im Retriever beidseitig interpretiert werden.
---
## 10) Frontmatter-Eigenschaften Rolle & Empfehlung
Frontmatter-Eigenschaften (Properties) bleiben **minimiert**:
- **type** steuert Typ-Defaults via Registry (Pflicht für differenziertes Verhalten).
- **tags** für klassische Filterung.
- **retriever_weight / chunk_profile** Sollten **nicht** manuell gesetzt werden (Best Practice: `types.yaml` nutzen).
- **links** Veraltet. Bitte Links primär über Text (Wikilink/Inline/Callout) pflegen.
---
## 11) Lösch-/Update-Garantien (Idempotenz)
- Jede Note hat einen stabilen **note_id** (Frontmatter/Hash).
- Vor einem Upsert können *alte Chunks/Edges einer Note* gefiltert gelöscht werden (`note_id`-Filter) das hält Collections sauber bei Re-Imports.
- Die Import-Skripte unterstützen Modi wie `--purge-before-upsert` und `--sync-deletes`, um den Graph sauber zu halten.
---
## 12) Beispiel Von Markdown zu Kanten (v2.2)
**Markdown (Auszug)**
# Relations Showcase
Wir nutzen [[rel:depends_on Qdrant Vektordatenbank]] für die Suche.
Siehe auch: [[Embeddings 101]]
> [!edge] related_to: [[Vector DB Basics]]
**Ergebnis (fachlich)**
1. `depends_on(Chunk→Qdrant)` mit `rule_id=inline:rel`, `confidence≈0.95`.
2. `references(Chunk→Embeddings 101)` mit `rule_id=explicit:wikilink`, `confidence=1.0`.
3. `related_to(Chunk→Vector DB Basics)` via Callout; `rule_id=callout:edge`, `confidence≈0.90`.
4. **Typ-Defaults:** Falls die Note vom Typ `project` ist, entstehen zusätzlich `depends_on`-Kanten zu den Zielen aus (2) und (3).
---
## 13) Referenzen (Projektdateien & Leitlinien)
- Import-Pipeline & Registry-Auflösung: `scripts/import_markdown.py`.
- Kantenbildung (V2-Logic): `app/core/derive_edges.py`.
- Typ-Registry: `config/types.yaml` & `TYPE_REGISTRY_MANUAL.md`.
- Retriever-Scoring & Explanation: `app/core/retriever.py`.
- Persönlichkeit & Chat: `config/prompts.yaml` & `app/routers/chat.py`.
- Logging Service: `app/services/feedback_service.py`.
---
## 14) Workpackage Status (v2.2.1)
Aktueller Implementierungsstand der Module.
| WP | Titel | Status | Anmerkung |
| :--- | :--- | :--- | :--- |
| **WP01** | Knowledge Design | 🟢 Live | Typen, Frontmatter definiert. |
| **WP02** | Chunking Strategy | 🟢 Live | Profilbasiertes Chunking aktiv. |
| **WP03** | Edge Logic / Import | 🟢 Live | Neue Importer-Pipeline mit Provenance. |
| **WP04a**| Retriever Scoring | 🟢 Live | Hybrider Score (Semantik + Graph). |
| **WP04b**| Explanation Layer | 🟢 Live | API liefert Reasons & Breakdown. |
| **WP04c**| Feedback Loop | 🟢 Live | Logging (JSONL) & Traceability aktiv. |
| **WP05** | Persönlichkeit / Chat | 🟢 Live | RAG-Integration mit Context Enrichment. |
| **WP06** | Decision Engine | 🟡 Geplant | Nächster Schritt. |
| **WP08** | Self-Tuning | 🔴 Geplant | Auto-Adjustment der Gewichte. |