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

15 KiB
Raw Blame History

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?

  • 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 BasicsEmbeddings 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}