--- doc_type: technical_reference audience: developer, devops scope: backend, ingestion, smart_edges, edge_registry, modularization status: active version: 2.9.0 context: "Detaillierte technische Beschreibung der Import-Pipeline, Two-Pass-Workflow (WP-15b) und modularer Datenbank-Architektur (WP-14). Integriert Mistral-safe Parsing und Deep Fallback." --- # Ingestion Pipeline & Smart Processing **Quellen:** `pipeline_playbook.md`, `ingestion_processor.py`, `ingestion_db.py`, `ingestion_validation.py`, `registry.py`, `edge_registry.py` Die Ingestion transformiert Markdown in den Graphen. Entrypoint: `scripts/import_markdown.py` (CLI) oder `routers/ingest.py` (API). Seit v2.9 nutzt dieser Prozess ein hocheffizientes **Two-Pass-Verfahren**, um globale Kontext-Informationen für die semantische Validierung bereitzustellen, ohne die Idempotenz oder die Change-Detection zu verletzen. ## 1. Der Import-Prozess (16-Schritte-Workflow) Der Prozess ist **asynchron**, **idempotent** und wird nun in zwei logische Durchläufe (Passes) unterteilt, um die semantische Genauigkeit zu maximieren. ### Phase 1: Pre-Scan & Context (Pass 1) 1. **Trigger & Async Dispatch:** * **API (`/save`):** Nimmt Request entgegen, validiert und startet Background-Task ("Fire & Forget"). Antwortet sofort mit `202/Queued`. * **CLI:** Iteriert über Dateien und nutzt `asyncio.Semaphore` zur Drosselung. 2. **Markdown lesen:** Rekursives Scannen des Vaults zur Erstellung des Dateiinventars. 3. **Frontmatter Check & Hard Skip (WP-22):** * Extraktion von `status` und `type`. * **Hard Skip Rule:** Wenn `status` in `['system', 'template', 'archive', 'hidden']` ist, wird die Datei für das Deep-Processing übersprungen, ihre Metadaten werden jedoch für den Kontext-Cache erfasst. * Validierung der Pflichtfelder (`id`, `title`) für alle anderen Dateien. 4. **Edge Registry Initialisierung (WP-22):** * Laden der Singleton-Instanz der `EdgeRegistry`. * Validierung der Vokabular-Datei unter `MINDNET_VOCAB_PATH`. 5. **Config Resolution (WP-14):** * Bestimmung von `chunking_profile` und `retriever_weight` via zentraler `TypeRegistry`. * **Priorität:** 1. Frontmatter (Override) -> 2. `types.yaml` (Type) -> 3. Global Default. 6. **LocalBatchCache & Summary Generation (WP-15b):** * Erstellung von Kurz-Zusammenfassungen für jede Note. * Speicherung im `batch_cache` als Referenzrahmen für die spätere Kantenvalidierung. ### Phase 2: Semantic Processing & Persistence (Pass 2) 7. **Note-Payload & Multi-Hash (WP-15b):** * Erstellen des JSON-Objekts inklusive `status`. * **Multi-Hash Calculation:** Berechnet Hashtabellen für `body` (nur Text) und `full` (Text + Metadaten) zur präzisen Änderungskontrolle. 8. **Change Detection:** * Vergleich des aktuellen Hashes mit den Daten in Qdrant (Collection `{prefix}_notes`). * Strategie wählbar via ENV `MINDNET_CHANGE_DETECTION_MODE` (`full` oder `body`). Unveränderte Dateien werden hier final übersprungen. 9. **Purge Old Artifacts (WP-14):** * Bei Änderungen löscht `purge_artifacts()` via `app.core.ingestion.ingestion_db` alle alten Chunks und Edges der Note. * Die Namensauflösung erfolgt nun über das modularisierte `database`-Paket. 10. **Chunking anwenden:** Zerlegung des Textes basierend auf dem ermittelten Profil (siehe Kap. 3). 11. **Smart Edge Allocation & Semantic Validation (WP-15b):** * Der `SemanticAnalyzer` schlägt Kanten-Kandidaten vor. * **Validierung:** Jeder Kandidat wird durch das LLM semantisch gegen das Ziel im **LocalBatchCache** geprüft. * **Traffic Control:** Nutzung der neutralen `clean_llm_text` Funktion zur Bereinigung von Steuerzeichen (, [OUT]). * **Deep Fallback (v2.11.14):** Erkennt "Silent Refusals". Liefert die Cloud keine verwertbaren Kanten, wird ein lokaler Fallback via Ollama erzwungen. 12. **Inline-Kanten finden:** Parsing von `[[rel:...]]` und Callouts. 13. **Alias-Auflösung & Kanonisierung (WP-22):** * Jede Kante wird via `EdgeRegistry` normalisiert (z.B. `basiert_auf` -> `based_on`). * Unbekannte Typen werden in `unknown_edges.jsonl` protokolliert. 14. **Default- & Strukturkanten:** Anwendung der `edge_defaults` und Erzeugung von Systemkanten (`belongs_to`, `next`, `prev`). 15. **Embedding (Async):** Generierung der Vektoren via `nomic-embed-text` (768 Dimensionen). 16. **Database Sync (WP-14):** Batch-Upsert aller Points in die Collections `{prefix}_chunks` und `{prefix}_edges` über die zentrale Infrastruktur. --- ## 2. Betrieb & CLI Befehle ### 2.1 API-Endpunkt: `/ingest/save` (Background Tasks) Seit WP-14 nutzt der `/ingest/save` Endpunkt **Background Tasks** für non-blocking Ingestion: **Workflow:** 1. **Request:** Frontend sendet Markdown an `/ingest/save` 2. **Sofortige Antwort:** API antwortet mit `status: "queued"` und `note_id: "pending"` 3. **Datei-Persistenz:** Markdown wird sofort auf Festplatte geschrieben 4. **Background Task:** Ingestion läuft asynchron im Hintergrund - Chunking - Embedding-Generierung - Smart Edge Allocation (WP-15) - Hybrid-Cloud-Analyse (WP-20) 5. **Vorteil:** Keine Timeouts bei großen Dateien oder langsamen LLM-Calls **Hinweis:** Die tatsächliche `note_id` steht erst nach dem Parsing fest. Das Frontend sollte den `file_path` für Tracking nutzen. ### 2.2 CLI-Betrieb (Inkrementell) Erkennt Änderungen via Multi-Hash. ```bash export QDRANT_URL="http://localhost:6333" export COLLECTION_PREFIX="mindnet" export MINDNET_CHANGE_DETECTION_MODE="full" # Nutzt das Venv der Produktionsumgebung /home/llmadmin/mindnet/.venv/bin/python3 -m scripts.import_markdown \ --vault ./vault \ --prefix "$COLLECTION_PREFIX" \ --apply \ --purge-before-upsert \ --sync-deletes ``` > **[!WARNING] Purge-Before-Upsert** > Das Flag `--purge-before-upsert` nutzt nun `ingestion_db.purge_artifacts`. Es ist kritisch, um "Geister-Chunks" (verwaiste Daten nach Textlöschung) konsistent aus den spezialisierten Collections zu entfernen. ### 2.2 Full Rebuild (Clean Slate) Notwendig bei Änderungen an `types.yaml`, der Registry oder Modell-Wechsel. ```bash # --force ignoriert alle Hashes und erzwingt den vollständigen Two-Pass Workflow python3 -m scripts.import_markdown --vault ./vault --prefix "mindnet" --apply --force ``` --- ## 3. Chunking & Payload Das Chunking ist profilbasiert und bezieht seine Konfiguration dynamisch aus der `TypeRegistry`. ### 3.1 Profile und Strategien | Profil | Strategie | Parameter | Einsatzgebiet | | :--- | :--- | :--- | :--- | | `sliding_short` | `sliding_window` | Max: 350, Target: 200 | Kurze Logs, Chats. | | `sliding_standard` | `sliding_window` | Max: 650, Target: 450 | Standard-Wissen. | | `sliding_smart_edges`| `sliding_window` | Max: 600, Target: 400 | Fließtexte (Projekte). | | `structured_smart_edges` | `by_heading` | `strict: false` | Strukturierte Texte. | ### 3.2 Die `by_heading` Logik (v2.9 Hybrid) Die Strategie `by_heading` zerlegt Texte anhand ihrer Struktur (Überschriften). Sie unterstützt ein "Safety Net" gegen zu große Chunks. * **Split Level:** Definiert die Tiefe (z.B. `2` = H1 & H2 triggern Split). * **Modus "Strict" (`strict_heading_split: true`):** * Jede Überschrift (`<= split_level`) erzwingt einen neuen Chunk. * *Merge-Check:* Wenn der vorherige Chunk leer war (nur Überschriften), wird gemergt. * *Safety Net:* Wird ein Abschnitt zu lang (> `max` Token), wird auch ohne Überschrift getrennt. * **Modus "Soft" (`strict_heading_split: false`):** * **Hierarchie-Check:** Überschriften *oberhalb* des Split-Levels erzwingen **immer** einen Split. * **Füll-Logik:** Überschriften *auf* dem Split-Level lösen nur dann einen neuen Chunk aus, wenn der aktuelle Chunk die `target`-Größe erreicht hat. * *Safety Net:* Auch hier greift das `max` Token Limit. --- ## 4. Edge-Erzeugung & Prioritäten (Provenance) Kanten werden nach Vertrauenswürdigkeit (`provenance`) priorisiert. Die höhere Prio gewinnt. | Prio | Quelle | Rule ID / Provenance | Confidence | Erläuterung | | :--- | :--- | :--- | :--- | :--- | | **1** | Wikilink | `explicit:wikilink` | **1.00** | Harte menschliche Setzung. | | **2** | Inline | `inline:rel` | **0.95** | Typisierte menschliche Kante. | | **3** | Callout | `callout:edge` | **0.90** | Explizite Meta-Information. | | **4** | Semantic AI | `semantic_ai` | **0.90** | KI-validiert gegen LocalBatchCache. | | **5** | Type Default | `edge_defaults` | **0.70** | Heuristik aus der Registry. | | **6** | Struktur | `structure` | **1.00** | System-interne Verkettung (`belongs_to`). | --- ## 5. Quality Gates & Monitoring **1. Registry Review (WP-14):** Prüfung der `data/logs/unknown_edges.jsonl`. Die zentrale Auflösung via `registry.py` verhindert Inkonsistenzen zwischen Import und Retrieval. **2. Mistral-safe Parsing:** Automatisierte Bereinigung von LLM-Antworten in `ingestion_validation.py`. Stellt sicher, dass semantische Entscheidungen ("YES"/"NO") nicht durch technische Header verfälscht werden. **3. Purge Integrity:** Validierung, dass vor jedem Upsert alle assoziierten Artefakte in den Collections `{prefix}_chunks` und `{prefix}_edges` gelöscht wurden, um Daten-Duplikate zu vermeiden.