# 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.0–1.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} ---