mindnet/docs/mindnet_functional_architecture.md
Lars 0bb7b34259
All checks were successful
Deploy mindnet to llm-node / deploy (push) Successful in 4s
docs/mindnet_functional_architecture.md aktualisiert
2025-11-17 18:46:39 +01:00

292 lines
15 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 Fachliche Architektur (Stand: 2025-11-17)
> Dieses Dokument beschreibt **was** Mindnet fachlich tut und **warum** mit Fokus auf die Erzeugung und Nutzung von **Edges** (Kanten) zwischen Notizen/Chunks. Die technische Umsetzung (Module, Flags, Schemas) wird nur dort angerissen, wo es zum Verständnis nötig ist und im technischen Dokument detailliert.
---
## 0) Zielbild & Grundprinzip
Mindnet wandelt Obsidian-Markdown-Notizen in einen **Graph 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*. :contentReference[oaicite:0]{index=0}
---
## 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. :contentReference[oaicite:1]{index=1}
### 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*.
> **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. :contentReference[oaicite:2]{index=2}
---
## 2) Edges fachliche Typen & Bedeutung
Edges kodieren Beziehungen. Sie sind **gerichtet** und werden in `mindnet_edges` gespeichert.
### 2.1 Struktur-Kanten
- **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. :contentReference[oaicite:3]{index=3}
### 2.2 Inhalts-Kanten (explizit)
- **references (chunk-scope)**: aus dem Textfenster des Chunks extrahierte Links.
Standardquelle: **Wikilinks** `[[…]]` einschließlich Varianten `[[id#anchor]]`, `[[id|label]]`.
→ Mindnet reduziert robust auf die Ziel-ID (Titel/ID-Normalisierung). :contentReference[oaicite:4]{index=4}
- **Explizite Inline-Relationen**: im Fließtext notierte Relationen, z. B.:
rel: similar_to [[Vector DB Basics]]
→ werden als Relation **similar_to** mit hoher Confidence materialisiert; *rule_id* `inline:rel`.
(Diese Form ist besonders kompakt in Obsidian editierbar.)
- **Callout-Edges** (optional):
> [!edge] related_to: [[Vector DB Basics]] [[Embeddings 101]]
→ erzeugt mehrere **related_to**-Kanten aus einer Zeile; *rule_id* `callout:edge`.
(Für kuratierte, sichtbare Linklisten am Notizende.)
> Alle expliziten Quellen (Wikilink, Inline-Rel, Callout) sind **gleichwertige Primärbelege** und werden als *provenance=explicit* geführt. Wo zutreffend, tragen Edges *rule_id* wie `explicit:wikilink`, `inline:rel`, `callout:edge`. :contentReference[oaicite:5]{index=5}
### 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}` (z. B. `edge_defaults:project:depends_on`). :contentReference[oaicite:6]{index=6}
---
## 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) oder `"note"` (optional für Backlinks/Note-Scope)
- `source_id`, `target_id` Quell-/Ziel-Knoten (Chunk- oder Note-ID)
- `note_id` **Owner-Note** (die Note, aus der die Kante stammt; dient der schnellen Löschung/Filterung)
Erweiterte/abgeleitete Felder (V2-Superset):
- `provenance` `"explicit"` (Wikilink/Inline/Callout) oder `"rule"` (Typ-Defaults)
- `rule_id` maschinenlesbare Regelquelle, z. B.
- `explicit:wikilink`, `inline:rel`, `callout:edge`
- `edge_defaults:{note_type}:{relation}`
- `confidence` 0.01.0; Heuristik, z. B. `1.0` für Wikilinks/Backlinks, `0.95` für `inline:rel`, `0.7` für Typ-Defaults.
**Dedup-Schlüssel** (fachlich): Gleichlautende `(source_id, target_id, kind, scope, rule_id)` werden nicht mehrfach geschrieben. :contentReference[oaicite:7]{index=7}
---
## 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** (z. B. `retriever_weight`) werden respektiert; am Ende schreibt der Importer die **effektiven** Werte zuverlässig in Note- und Chunk-Payload. :contentReference[oaicite:8]{index=8}
### 4.2 Beispiel (auslieferungsnah)
version: 1.0
types:
concept:
chunk_profile: medium
edge_defaults: ["references", "related_to"]
retriever_weight: 0.35
project:
chunk_profile: long
edge_defaults: ["references", "depends_on"]
retriever_weight: 0.97
profile:
chunk_profile: long
edge_defaults: ["references", "depends_on"]
retriever_weight: 0.66
**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. :contentReference[oaicite:9]{index=9}
---
## 5) Wie entstehen Edges aus Markdown?
### 5.1 Quelle „Wikilinks“ (Primärfall)
- Parser extrahiert alle `[[…]]` (Label/Anker werden auf die Ziel-ID reduziert).
- Pro Fund entsteht **eine** `references`-Kante (Chunk-Scope).
- Zusätzlich: Typ-Defaults (z. B. `depends_on`, `related_to`) pro Ziel. :contentReference[oaicite:10]{index=10}
### 5.2 Quelle „Inline-Relation“ (Optional, kompakt)
- Im Fließtext markierte Relation, z. B.:
rel: similar_to [[Vector DB Basics]]
- Erzeugt `similar_to`-Kanten; *rule_id* `inline:rel`; `confidence≈0.95`.
- Geeignet für sparsame, gut lesbare Referenzierung. (Erfassung in der Chunk-Window-Analyse.) :contentReference[oaicite:11]{index=11}
### 5.3 Quelle „Callout-Edges“ (Optional, kuratiert)
- Klar sichtbare, redaktionell gepflegte Liste am Ende einer Note:
> [!edge] related_to: [[Vector DB Basics]] [[Embeddings 101]]
- Erzeugt je Ziel eine `related_to`-Kante; *rule_id* `callout:edge`.
- Eignet sich für „Leselisten“ und „Siehe auch“. (Zählung als *callout_total* in Reports, wo vorhanden.) :contentReference[oaicite:12]{index=12}
### 5.4 Struktur-Kanten
- `belongs_to` pro Chunk
- `next/prev` aus Nachbarbezug (aus Chunk-Sequenz/Neighbors) :contentReference[oaicite:13]{index=13}
> **Hinweis zu Note-Scope:** Optional können zusätzlich Note-weite *references/backlinks* aus der Gesamtheit aller Chunk-Funde abgeleitet werden (Konfig-Flag/ENV). Das ist für globale Graph-Analysen nützlich, aber im Retrieval seltener erforderlich. :contentReference[oaicite:14]{index=14}
---
## 6) Confidence & Provenance wozu?
Der Retriever kann Edges gewichten:
- **provenance**: *explicit* > *rule*
- **confidence**: numerische Feinsteuerung (z. B. Inline-Relation etwas höher, Defaults etwas niedriger)
- **retriever_weight (Note/Chunk)**: skaliert die Relevanz des gesamten Knotens
Eine typische Gewichtung (konfigurierbar) ist:
explicit: 1.0, rule: 0.8, default_resolved: 0.6, default: 0.2
Damit bevorzugt der Graph **kuratiertes Wissen** (explizit notierte Links) vor „erweiterten“ Default-Ableitungen. :contentReference[oaicite:15]{index=15}
---
## 7) 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 (z. B. Query-Zeit-Expansion), um Redundanz im Vault zu vermeiden. :contentReference[oaicite:16]{index=16}
---
## 8) Frontmatter-Eigenschaften Rolle & Empfehlung
Frontmatter-Eigenschaften (Properties) bleiben **minimiert**:
- **type** steuert Typ-Defaults via Registry (Pflicht für differenziertes Verhalten).
- **retriever_weight** *(optional)* kann typbasierte Defaults überschreiben.
- **chunk_profile** *(optional)* kann typbasierte Defaults überschreiben.
- **links** *(optional, Bestandskompatibilität)* wenn vorhanden (z. B. `depends_on: …`), können sie als explizite Kanten materialisiert werden; die Pflege in freiem Text (Inline/Callout) ist jedoch **benutzerfreundlicher** und weniger fehleranfällig.
Empfehlung: **Links primär über Text (Wikilink/Inline/Callout) pflegen**, nicht als Properties. Die Registry regelt Standards; Properties dienen nur gezielten Ausnahmen. :contentReference[oaicite:17]{index=17}
---
## 9) 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.
- Es gibt Abkürzungen für „fehlertolerante Rebuilds“: *Existenz-Checks* statt Full-Scan. :contentReference[oaicite:18]{index=18}
---
## 10) Beispiel Von Markdown zu Kanten
**Markdown (Auszug)**
# Relations Showcase
rel: similar_to [[Vector DB Basics]]
[[Embeddings 101]]
> [!edge] related_to: [[Vector DB Basics]] [[Embeddings 101]]
**Ergebnis (fachlich)**
- `references(Chunk→Vector DB Basics)` + `references(Chunk→Embeddings 101)`
- `similar_to(Chunk→Vector DB Basics)` mit `rule_id=inline:rel`, `confidence≈0.95`
- `related_to(Chunk→Vector DB Basics)` und `related_to(Chunk→Embeddings 101)`
via Callout; `rule_id=callout:edge`
- Zusätzliche **Typ-Defaults** je Quell-Typ, z. B. `edge_defaults:concept:related_to` → weitere `related_to`-Kanten
*Strukturkanten* (`belongs_to`, `next/prev`) fallen wie üblich an. (Die tatsächlichen Zähllogiken erscheinen im Import-Report/Smoke-Tests.) :contentReference[oaicite:19]{index=19}
---
## 11) Abfrage-Implikationen (fachlich)
Retriever und Query-Layer berücksichtigen:
1) **Knoten-Gewicht** (`retriever_weight`) aus Typ/Property (Note & Chunk).
2) **Edge-Provenance/Confidence** explizit > regelbasiert; höhere Confidence bevorzugt.
3) **Edge-Topologie** z. B. 1-Hop-Nachbarschaft, Sequenzpfade (`next/prev`), Backlinks (optional).
4) **Policy-Filter** Privacy, Tags, Created usw. via Payload-Indizes.
Die Abfrage kann so z. B. Ergebnisse bevorzugen, die **explizit** in einem *Projekt* als `depends_on` genannt sind und nur nachrangig solche, die „typbedingt“ (`edge_defaults`) ähnlich/abhängig sind. :contentReference[oaicite:20]{index=20}
---
## 12) Qualitäts- und Testkriterien (fachlich)
- **Keine Duplikate** gleicher `(src, relation, dst)` in der Collectionsicht (Dedup).
- **Explizite Links** werden vollständig materialisiert (*explicit_total*).
- **Typ-Defaults** ergänzen, aber überdecken nicht Counts bleiben plausibel (*defaults_total*).
- **Inline/Callout** werden separat quantifiziert (*inline_total*, *callout_total*), damit Redaktionen ihre Pflegewirkung beobachten können. :contentReference[oaicite:21]{index=21}
---
## 13) Praxisempfehlungen für den Vault
1) **Wikilinks** überall, wo eine inhaltliche Nennung stattfindet.
2) Für **gezielte Relationen** (Ähnlichkeit/Abhängigkeit) kurze **Inline-Rel**-Zeilen; z. B.:
rel: similar_to [[X]]
rel: related_to [[Y]] [[Z]]
3) Am Notizende **Callout-Edges** für kuratierte Überblicksblöcke:
> [!edge] related_to: [[X]] [[Y]]
4) **Properties** schlank halten: mindestens `type`, optional `retriever_weight`/`chunk_profile`.
5) **types.yaml** pflegen (zentrale Governance): *Welche Typen gibt es? Welche Default-Relationen sind fachlich sinnvoll?*
6) **Regelmäßige Smoke-Tests/Reports** prüfen die Kanten-Counts und Provenance-Verteilung. :contentReference[oaicite:22]{index=22}
---
## 14) Referenzen (Projektdateien & Leitlinien)
- Import-Pipeline & Registry-Auflösung (Importer, Flags, Idempotenz): `scripts/import_markdown.py`. :contentReference[oaicite:23]{index=23}
- Robuste Kantenbildung (Wikilinks, Struktur, optionale Note-Scope): `app/core/derive_edges.py` (v1.4+). :contentReference[oaicite:24]{index=24}
- V2-Edge-Superset (Provenance, rule_id, Confidence, Typ-Defaults): `app/core/edges.py` (v2.0+). :contentReference[oaicite:25]{index=25}
- Typ-Registry laden/auflösen (Fallbacks, Effektivwerte): Import-Helper / *Type-Registry*-Hilfsfunktionen. :contentReference[oaicite:26]{index=26}
- Test-/Playbook-Leitplanken (Policies, KPIs, Roadmap): *Implementation Playbook*. :contentReference[oaicite:27]{index=27}
---
## 15) Anhang Mini-Beispiel einer Projekt-Note (verkürzt)
---
id: 20251110-ki-trainerassistent-projekt-56d2aa
title: KI Trainerassistent (Projekt)
type: project
retriever_weight: 1.0 # optional Override
chunk_profile: default # optional Override
---
# KI Trainerassistent (Projekt)
Wir nutzen [[Qdrant Vektordatenbank]] und [[Ollama LLM]] …
rel: depends_on [[Qdrant Vektordatenbank]]
rel: related_to [[Ollama LLM]]
> [!edge] depends_on: [[Qdrant Vektordatenbank]]
> [!edge] related_to: [[Ollama LLM]]
*Erwartung*:
- `references` (Wikilinks) auf **beide** Ziele
- `depends_on` & `related_to` via **Inline** und **Callout** (provenance=`explicit`, rule_id `inline:rel`/`callout:edge`)
- Zusätzlich **Typ-Defaults** aus `types.yaml` für `project` (z. B. weitere `depends_on`) provenance=`rule`, `rule_id=edge_defaults:project:depends_on`. :contentReference[oaicite:28]{index=28}
---