23 KiB
Mindnet – Technische Architektur (V2, Stand: 2025-11-xx)
Ziel dieses Dokuments:
Vollständige, konsolidierte Beschreibung der aktuellen technischen Architektur von Mindnet V2 – insbesondere der Verarbeitung von Markdown-Notizen, des Chunkings, der Kantenableitung (Edges) inkl.rule_id/confidenceund der Speicherung in Qdrant.
Das Dokument bildet den aktuellen Implementierungsstand ab, nicht mehr gültige Annahmen sind bereinigt, neue Konzepte (Typ-Defaults, Inline-Relationen, Edges-Schema) sind integriert.
1. Systemüberblick
1.1 Zielbild
Mindnet ist ein persönliches Wissensnetz. Technisch bedeutet das:
-
Markdown-Notizen in einem Vault (Obsidian-kompatibel) werden
- geparst (Frontmatter + Body),
- in Notes, Chunks und Edges überführt,
- in Qdrant als drei Collections abgelegt:
<prefix>_notes<prefix>_chunks<prefix>_edges.
-
Das System ist so konzipiert, dass es:
- deterministisch arbeitet (IDs, Chunks, Kanten),
- über
types.yamlkonfigurierbar ist, - später von einem LLM-basieren Agenten als Graph-Retriever genutzt werden kann.
1.2 Verzeichnisstruktur (Server)
/home/llmadmin/mindnet/:
- /app
main.py– FastAPI-App / Einstieg- /app/core
qdrant.py– QdrantConfig, Client-Factory, Collection-Managementqdrant_points.py– Upserts / Deletes / Queries auf Punktebenenote_payload.py– Bau von Note-Payloadschunk_payload.py– Bau von Chunk-Payloadschunker.py– Chunking-Logikedges.py– Datenstruktur & Hilfsfunktionen für Edgesderive_edges.py– Ableitung von Edges aus Text und Typen
- /app/models
dto.py– DTOs für API / Services
- /app/routers
qdrant_router.py– API-Layer Richtung Qdrant
- /app/services
llm_ollama.py– Anbindung an Ollama-LLMembeddings_client.py– Embedding-Service (z. B. Ollama / lokaler Dienst)
- /config
types.yaml– Typdefinitionen inkl. Chunk-Profilen und Edge-Defaults
- /scripts
import_markdown.py– Hauptimporter für Vaultreset_qdrant.py– Collections löschen/neu anlegen (inkl. Indizes)setup_mindnet_collections.py– Collection-Setup (historisch / Hilfsskript)- diverse Diagnose- und Testskripte, z. B.
payload_dryrun.pyedges_full_check.py
- /tests
test_edges_smoke.py– einfache Edge-Smoke-Teststest_edges_all.py– umfassendere Checks (Counts, Plausibilität)ensure_indexes_and_show.py,assert_payload_schema.py– Schema/Index-Checks
- /vault
- produktives Vault (Obsidian)
- /mindnet_v2_test_vault
- Test-Vault für V2-Funktionen (Chunking, Edges, Typ-Defaults)
2. Datenmodell & Collections
2.1 Note, Chunk, Edge – Begriffe
-
Note
Entspricht einer Markdown-Datei mit YAML-Frontmatter (id,title,type, …).
In Qdrant als ein Punkt in<prefix>_notes. -
Chunk
Ein Abschnitt einer Note (z. B. Absatz, Überschrifts-Block, Sliding Window).
In Qdrant als Punkt in<prefix>_chunks. -
Edge
Eine gerichtete Kante, die eine Beziehung zwischen:- zwei Chunks,
- Chunk ↔ Note,
- oder (konzeptionell) Note ↔ Note beschreibt.
Gespeichert in<prefix>_edges.
2.2 Qdrant Collections (Stand V2)
Namenskonvention:
Prefix aus ENV (COLLECTION_PREFIX, z. B. mindnet):
mindnet_notesmindnet_chunksmindnet_edges
Die Collections werden über:
```bash
python3 -m scripts.reset_qdrant --mode wipe --prefix "$COLLECTION_PREFIX"
```
vollständig neu angelegt, inkl. Payload-Indizes (Details in 6.1).
2.3 Notes – Payload & Felder
Minimale, indexierte Felder (Auszug, Schema laut diag_payload_indexes):
note_id(keyword) – stabile Note-ID (Frontmatterid)title(text) – Notiz-Titeltype(keyword) – logischer Typ (z. B.concept,project,profile,journal,source)tags(keyword[]) – Tags aus Frontmatterupdated(integer) – Zeitstempel (z. B.YYYYMMDDHHMMSSoder epoch; Implementierungsdetail)
Weitere Felder (nicht alle indexiert, aber im Payload vorhanden):
retriever_weight(float) – wie stark diese Note/Chunks im Retrieval gewichtet werdenchunk_profile(string) – Name des verwendeten Chunk-Profilsedge_defaults(string[]) – Liste von Default-Relationen pro Typ (z. B.["references","related_to"])confidentiality,visibility, weitere Metadaten aus Frontmatter
Diese Felder werden in app/core/note_payload.py aus Frontmatter + types.yaml konstruiert.
2.4 Chunks – Payload & Felder
Indexierte Kernfelder:
note_id(keyword) – Referenz auf die übergeordnete Notechunk_id(keyword) – deterministische Chunk-ID:
"{note_id}#c{index:02d}"(z. B.20251110-ollama-llm-9f0a12#c02)index(integer) – 0-basiert; Position in der Notetype(keyword) – Note-Typ (vom Note geerbt)tags(keyword[]) – Tags (vom Note geerbt)
Weitere wichtige Payload-Felder:
ord(integer) – 1-basiertes Pendant zuindex(für menschliche Lesbarkeit)text(string) – eigentlicher Chunk-Text (ggf. gereinigt/normalisiert)window(string) – Kontext-Fenster (z. B. Chunk ± Nachbarn)retriever_weight(float) – gültiger Wert austypes.yaml(oder Default)chunk_profile(string) – verwendetes Profil, z. B.short,medium,long,by_headingneighbors_prev(string[]) – Liste vonchunk_ids direkter Vorgänger (i. d. R. 0 oder 1 ID)neighbors_next(string[]) – Liste vonchunk_ids direkter Nachfolger
Die Konstruktion erfolgt in app/core/chunk_payload.py auf Basis der Chunks aus chunker.py und der aufgelösten Typ-Defaults.
2.5 Edges – Payload & Felder
Indexierte Felder:
note_id(keyword) – Note, zu der der Quell-Chunk gehörtsource_id(keyword) – i. d. R.chunk_iddes Quell-Chunks (z. B.2025…#c00)target_id(keyword) – Zielobjekt (z. B.:chunk_ideines anderen Chunks- Note-Titel (
"Embeddings 101") bei konzeptionellen Referenzen
kind(keyword) – Kantenart:- Struktur:
belongs_to,next,prev - Explizit:
references - Inline: z. B.
similar_to,depends_on,related_to - Typ-Defaults: ebenfalls z. B.
depends_on,related_to(ausedge_defaults)
- Struktur:
scope(keyword) – aktuell immer"chunk"(Kante wird auf Chunk-Ebene geführt)chunk_id(keyword) –chunk_iddes Quell-Chunks
Weitere Payload-Felder:
rule_id(string) – Herkunftsregel:- Struktur:
structure:belongs_tostructure:nextstructure:prev
- Explizite Wiki-Links:
explicit:wikilink
- Inline-Relationen:
inline:rel
- Typ-Defaults aus
types.yaml:edge_defaults:<type>:<relation>
z. B.edge_defaults:concept:related_to
- Struktur:
confidence(float) – Stärke / Vertrauensgrad:- Struktur-Kanten:
1.0 - Explizite Wiki-Links:
1.0 - Inline-Relationen (
[[rel:… …]]): z. B.0.95 - Typ-Defaults: z. B.
0.7
- Struktur-Kanten:
Edges werden in app/core/derive_edges.py erzeugt und in mindnet_edges gespeichert.
3. Typ-Konfiguration (config/types.yaml)
3.1 Struktur des Files
types.yaml (vereinfachtes Beispiel):
```yaml
version: 1.0
default:
retriever_weight: 1.0
chunk_profile: default
types:
concept:
chunk_profile: medium
edge_defaults: ["references", "related_to"]
retriever_weight: 0.35
task:
chunk_profile: short
edge_defaults: ["depends_on", "belongs_to"]
retriever_weight: 0.8
experience:
chunk_profile: medium
edge_defaults: ["derived_from", "inspired_by"]
retriever_weight: 0.9
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
```
3.2 Typauflösung – Reihenfolge der Prioritäten
Für eine Note mit type und optionalen Frontmatter Feldern retriever_weight, chunk_profile gilt aktuell:
- Typ-spezifische Defaults aus
types.yaml:retriever_weight←types.<type>.retriever_weight(falls vorhanden)chunk_profile←types.<type>.chunk_profile(falls vorhanden)
- Globaler Default
defaultintypes.yaml, falls Typ-Eintrag fehlt. - Frontmatter
retriever_weight/chunk_profilewerden aktuell nicht mehr als Konfigurationsebene verwendet, sondern eher als historische Relikte. (Dies kann zukünftig wieder aktiviert werden, ist aber im aktuellen Stand bewusst abgeschaltet zugunsten klarer, zentraler Konfiguration übertypes.yaml.)
Das Ergebnis dieser Auflösung wird im Payload als:
note_payload["retriever_weight"]note_payload["chunk_profile"]
gesetzt und 1:1 an alle Chunks vererbt.
4. Import-Pipeline (Markdown → Qdrant)
4.1 Runbook
Standard-Import (mit Purge-Before-Upsert):
```bash
export COLLECTION_PREFIX=mindnet
export MINDNET_TYPES_FILE="$(pwd)/config/types.yaml"
python3 -m scripts.import_markdown \
--vault ./mindnet_v2_test_vault \
--apply \
--purge-before-upsert \
--prefix "$COLLECTION_PREFIX"
```
Nur Sync-Deletes (entfernte Dateien in Qdrant aufräumen):
```bash
python3 -m scripts.import_markdown \
--vault ./mindnet_v2_test_vault \
--sync-deletes \
--apply \
--prefix "$COLLECTION_PREFIX"
```
4.2 Verarbeitungsschritte
1. Discovery & Parsing
import_markdown.pytraversiert das Vault‐Verzeichnis.- Für jede
.md:- YAML-Frontmatter extrahieren (id, title, type, created, updated, tags, …).
- Body (Markdown) als String.
2. Typauflösung & Payload-Bau (Note)
- Laden & Auflösen von
types.yaml(über ENVMINDNET_TYPES_FILEoder Default./config/types.yaml). - Bestimmung des effektiven Typs (
typeaus Frontmatter; ggf. Fallback). - Anwendung der Typdefaults:
retriever_weightundchunk_profilewerden austypes.yamlgelesen.
- Konstruktion des Note-Payloads via
make_note_payload(innote_payload.py):- Felder wie
note_id,title,type,tags,updated,retriever_weight,chunk_profile,edge_defaults, …
- Felder wie
3. Chunking
-
Übergabe des Note-Bodies +
chunk_profileanchunker.py. -
chunker.pynutztchunk_config.py, das definierte Profile bereitstellt, z. B.:CHUNK_PROFILES = { "short": {"max_tokens": 128, "overlap": 32}, "medium": {"max_tokens": 256, "overlap": 64}, "long": {"max_tokens": 512, "overlap": 128}, "by_heading": {"strategy": "by_heading", "max_chars": 2000}, "default": {"max_tokens": 256, "overlap": 64}, } -
Ergebnis: Liste geordneter Chunks mit:
chunk_id(note_id#cXX),index(0..N-1),ord(1..N),text,window(inkl. Nachbartexte),neighbors_prev/neighbors_next.
4. Chunk-Payloads
- In
chunk_payload.pywerden für jeden Chunk die Payloads gebaut:- Vererbung von
note_id,type,tags,retriever_weight,chunk_profile. - Setzen von
index,ord,neighbors_prev,neighbors_next. - Persistieren von
textundwindow.
- Vererbung von
5. Kantenableitung (Edges)
derive_edges.pywird mit Note + Chunks + Typinformationen aufgerufen.- Es entstehen mehrere Gruppen von Kanten:
- Struktur-Kanten:
belongs_to: Chunk → Notenext: Chunk[i] → Chunk[i+1]prev: Chunk[i] → Chunk[i-1]
- Explizite Kanten aus Text:
- Wiki-Links:
[[Target Title]]→kind="references",rule_id="explicit:wikilink",confidence=1.0. - Inline-Relationen:
[[rel:depends_on Embeddings 101]]:kind="depends_on"rule_id="inline:rel"confidence≈0.95target_id="Embeddings 101"(Titel, nicht ID – Auflösung erfolgt später im Agenten).
- Wiki-Links:
- Typ-basierte Defaults (
edge_defaults):- Aus
types.yamljetype: Liste von Relations-Kinds, z. B.:concept.edge_defaults = ["references","related_to"]project.edge_defaults = ["references","depends_on"]
- Für jede explizite Referenz Quelle→Ziel (z. B.
references,similar_to) werden zusätzliche Kanten erzeugt, z. B.:edge_defaults:project:depends_onedge_defaults:concept:related_to
confidence≈0.7.
- Aus
- Deduplication:
- Alle Kanten werden in einem Set anhand eines Keys wie
(kind, scope, source_id, target_id, rule_id)
dedupliziert (idempotent).
- Alle Kanten werden in einem Set anhand eines Keys wie
- Struktur-Kanten:
6. Upsert nach Qdrant
- Punkte (Notes, Chunks, Edges) werden via
qdrant_points.pyin die entsprechenden Collections upserted. - Option
--purge-before-upsertsorgt dafür, dass alte Punkte mit denselben IDs entfernt werden, bevor neue geschrieben werden (stabiler Reimport). --sync-deletesentfernt Punkte, deren zugehörige Dateien im Vault nicht mehr existieren.
5. Edges im Detail – Semantik & Regeln
5.1 Struktur-Kanten
Erzeugt für jede Note mit >0 Chunks:
- belongs_to
- pro Chunk genau eine Kante:
source_id = chunk_idtarget_id = note_idoder (konzeptionell) ein Note-Identifikatorkind = "belongs_to"scope = "chunk"rule_id = "structure:belongs_to"confidence = 1.0
- pro Chunk genau eine Kante:
- next / prev
- für Index i (
0..N-2):next:chunk_i → chunk_{i+1}prev:chunk_{i+1} → chunk_ikind = "next"bzw."prev"scope = "chunk"rule_id = "structure:next"/"structure:prev"confidence = 1.0
- für Index i (
Tests (tests.test_edges_smoke / tests.test_edges_all) stellen sicher:
belongs_to==#chunksnext==prev==#chunks - 1- keine Duplikate der Strukturkanten.
5.2 Explizite Wiki-Links ([[Target Title]])
- Parser in
derive_edges.pysucht im Chunk-Text nach Mustern:[[Some Page]](keinrel:Präfix)
- Erzeugt Kanten:
kind = "references"scope = "chunk"source_id = chunk_idtarget_id = "<Titel aus dem Link>"(z. B."Vector DB Basics")rule_id = "explicit:wikilink"confidence = 1.0
Diese Kanten bilden das explizite Referenznetz des Nutzers ab (Obsidian-typische Wikilinks).
5.3 Inline-Relationen ([[rel:… …]])
Aktuell implementiert und funktional ist folgende Form:
-
Format (aktuell unterstützt):
[[rel:depends_on Embeddings 101]] [[rel:similar_to Vector DB Basics]] [[rel:related_to Qdrant Vektordatenbank]] -
Parsing-Strategie:
- Link-Inhalt wird gesplittet:
- Erster Token:
rel:depends_on - Rest: Zielbezeichnung (
Embeddings 101)
- Erster Token:
kindwird aus dem Teildepends_onextrahiert (z. B.similar_to,related_to).target_idwird aus dem Rest (meist ein Titel) abgeleitet.
- Link-Inhalt wird gesplittet:
-
Ergebnis-Kante:
kind = "<Relation aus rel:…>"scope = "chunk"source_id = chunk_idtarget_id = "<Ziel-Titel>"rule_id = "inline:rel"confidence ≈ 0.95
-
Nicht unterstützt (Stand jetzt):
rel: depends_on [[Embeddings 101]] [[Vector DB Basics]]Diese Syntax wird derzeit nicht erkannt.
Multi-Target-Inline-Relationen (rel: similar_to [[A]] [[B]]) sind ein offener Task.
5.4 Typ-basierte Default-Edges (edge_defaults)
Zweck:
- Für bestimmte Typen (vor allem
concept,project,profile) sollen zusätzliche Kanten automatisch ergänzt werden, um das Semantiknetz zu verdichten, ohne dass der Nutzer jede Relation explizit pflegen muss.
Konfiguration:
-
In
types.yamldefiniert, z. B.:types: concept: edge_defaults: ["references", "related_to"] project: edge_defaults: ["references", "depends_on"]
Aktuelle Implementierung:
-
Für jede explizite Referenz (Wiki-Link oder Inline-Relation) von Chunk → Ziel:
kind="references"(Wiki) oder die Inline-Relation (depends_on,similar_to, …)
-
Auf Basis des Note-Typs (
type) wird pro Default-Relation eine zusätzliche Kante erzeugt:Beispiel:
- Note-Typ:
project edge_defaults: ["references","depends_on"]- Explizit:
referencesvonEdge Index→Embeddings 101 - Abgeleitete Kanten:
kind="references",rule_id="edge_defaults:project:references",confidence=0.7kind="depends_on",rule_id="edge_defaults:project:depends_on",confidence=0.7
- Note-Typ:
-
Symmetrische Kanten:
- Für einige Relations-Typen (z. B.
related_to) wird zusätzlich eine spiegelbildliche Kante Ziel → Quelle erzeugt. - Dies erklärt in Tests z. B. Paare wie:
related_to (Source=Ollama LLM, Target=Qdrant Vektordatenbank)related_to (Source=Qdrant Vektordatenbank, Target=Ollama LLM)
- Für einige Relations-Typen (z. B.
-
Deduplication:
- Es wird verhindert, dass mehrfach identische Kanten geschrieben werden.
- Schlüssel:
(kind, scope, source_id, target_id, rule_id).
5.5 rule_id & confidence – Bedeutung
rule_id kodiert Herkunft und Regel, z. B.:
structure:belongs_to,structure:next,structure:prevexplicit:wikilinkinline:reledge_defaults:<type>:<relation>
confidence dient als späterer Gewichtungsfaktor im Retrieval / Ranking:
1.0→ harte Struktur- oder explizite Kante (vom Nutzer direkt gesetzt)0.95→ Inline-Relation (stark, aber nicht so „hart“ wie die reine Referenz)0.7→ Typ-Default-Edges (abgeleitete Hypothesen aus Typwissen)
Ein künftiger LLM-Agent kann daraus z. B.:
- Kanten mit hoher
confidencepriorisieren, - Default-Edges als schwächere Hinweise betrachten,
- Inline-Relationen gezielt als semantische Aussagen über die Beziehung interpretieren.
6. Qdrant-Schema & Indizes
6.1 Erstellung & Indizes
Die Erstellung erfolgt über:
```bash
python3 -m scripts.reset_qdrant --mode wipe --prefix "$COLLECTION_PREFIX"
```
Intern:
qdrant.py/setup_mindnet_collections.py:- Collections anlegen, ggf. mit Vektor-Konfiguration (Single-Vector; Named-Vectors sind vorbereitet aber optional).
ensure_payload_indexes():- Legt für jede Collection die relevanten Payload-Indizes an.
Verifizierbar durch:
```bash
python3 -m tests.ensure_indexes_and_show
```
Beispielauszug (bereits real so gesehen):
-
mindnet_notes
{ "tags": { "data_type": "keyword", "points": 8 }, "note_id":{ "data_type": "keyword", "points": 8 }, "title": { "data_type": "text", "points": 8 }, "updated":{ "data_type": "integer", "points": 0 }, "type": { "data_type": "keyword", "points": 8 } } -
mindnet_chunks
{ "note_id": { "data_type": "keyword", "points": 44 }, "chunk_id":{ "data_type": "keyword", "points": 44 }, "index": { "data_type": "integer", "points": 44 }, "type": { "data_type": "keyword", "points": 44 }, "tags": { "data_type": "keyword", "points": 44 } } -
mindnet_edges
{ "scope": { "data_type": "keyword", "points": 135 }, "kind": { "data_type": "keyword", "points": 135 }, "chunk_id":{ "data_type": "keyword", "points": 135 }, "target_id":{ "data_type": "keyword", "points": 135 }, "note_id": { "data_type": "keyword", "points": 135 }, "source_id":{ "data_type": "keyword", "points": 135 } }
6.2 Schema-Validierung
tests/assert_payload_schema.py prüft:
- ob die Minimalfelder (
note_id,type,title,updated,tagsetc.) vorhanden sind, - berichtet fehlende Felder.
Nach Korrektur der Indexanlage sollte:
ok = truesein, bzw. zumindest alle Kernfelder unterpresentgeführt werden.
(Im aktuellen Stand werden sie als Indizes geführt; Qdrant speichert zusätzliche Felder ohne explizite Schema-Zeile, was technisch unproblematisch ist.)
7. Nutzung im Retrieval (Ausblick)
7.1 Typbewusstes Chunk-Retrieval
Ein typischer Query-Pfad eines LLM-Agents:
-
Query → Embedding
-
Suche in
mindnet_chunksmit Filter, z. B.:f = rest.Filter( must=[ rest.FieldCondition(key="type", match=rest.MatchValue(value="concept")), rest.FieldCondition(key="tags", match=rest.MatchAny(any=["ki","ollama"])) ] ) -
Treffer werden nach:
- Vektor-Score,
retriever_weight,- ggf. Edges (z. B. Projekte mit
depends_on→ Konzepte) gewichtet.
7.2 Graph-orientierte Navigation
Basierend auf mindnet_edges kann der Agent:
- ausgehend von einem relevanten Chunk:
- Struktur-Kanten (
next,prev) zur Kontextvergrößerung nutzen, references/depends_on/related_tointerpretieren,edge_defaultsals semantische Ausdehnung (z. B. vonprojectzu seinenconcept-Bausteinen) nutzen.
- Struktur-Kanten (
Die Bedeutung der Kanten ist dabei durch rule_id und confidence klar nachvollziehbar.
8. Offene Punkte / Known Limitations
-
Multi-Target Inline-Relationen
Syntax wie:```md [[rel:similar_to Vector DB Basics]] [[rel:similar_to Embeddings 101]] ```funktioniert (zwei separate Inline-Links).
Nicht unterstützt (Stand jetzt):```md [[rel:similar_to Vector DB Basics]] [[Embeddings 101]] rel: similar_to [[Vector DB Basics]] [[Embeddings 101]] ```→ Offener Task: Parser erweitern, um mehrere Ziele in einer Inline-Relation zu unterstützen.
-
Callout-Edges (
[!edge])-
Konzeptionell vorgesehen, z. B.:
> [!edge] related_to: [[Vector DB Basics]] -
Im aktuellen Implementierungsstand werden Callouts entweder:
- gar nicht, oder
- nur teilweise verarbeitet (in den aktuellen Test-Runs war
callout_total = 0).
→ Offener Task: Callout-Parser robust implementieren und mit Tests absichern.
-
-
Frontmatter-Overrides für
retriever_weight/chunk_profile- Aktuell nicht wirksam.
- Typdefaults aus
types.yamlsind der Single Source of Truth. - Später können kontrollierte Overrides (z. B. für Sonderfälle) eingeführt werden.
-
Vektor-Konfiguration für Edges
mindnet_edgeswird derzeit ohne Vektoren betrieben (vectors = null).- Später könnte z. B. eine semantische Repräsentation von Kanten eingeführt werden (z. B. Embedding von
(source_chunk_text + relation + target_title)).
9. Zusammenfassung
-
Die Mindnet-V2-Architektur implementiert einen dreistufigen Speicher:
- Notes (
mindnet_notes), - Chunks (
mindnet_chunks), - Edges (
mindnet_edges).
- Notes (
-
types.yamlsteuert:retriever_weightundchunk_profileje Typ (inkl. Default),edge_defaultsje Typ (automatische Relations-Ableitung).
-
Das Chunking ist profilbasiert (short/medium/long/by_heading) und deterministisch.
-
Die Kantenableitung in
derive_edges.pyerzeugt:- strukturelle Kanten (belongs_to / next / prev),
- explizite Kanten aus Wiki-Links (
[[Target]]), - semantische Inline-Relationen (
[[rel:depends_on Target]]), - typbasierte Default-Kanten (z. B.
edge_defaults:project:depends_on).
-
rule_idundconfidencemachen die Herkunft jeder Kante transparent und ermöglichen später eine gewichtete Auswertung durch LLM-basierte Agenten. -
Qdrant-Collections und Payload-Indizes sind konsistent eingerichtet und durch Tests verifiziert.
Dieses Dokument bildet damit das aktuelle technische Gesamtbild von Mindnet V2 ab, inkl. aller relevanten Mechanismen rund um Typen, Chunking, Edges und Qdrant-Schema.