mindnet/docs/03_Technical_References/03_tech_ingestion_pipeline.md

149 lines
8.3 KiB
Markdown
Raw Normal View History

---
doc_type: technical_reference
audience: developer, devops
2025-12-27 22:13:11 +01:00
scope: backend, ingestion, smart_edges, edge_registry, modularization
status: active
2025-12-27 22:13:11 +01:00
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
2025-12-27 22:13:11 +01:00
**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.
2025-12-25 22:21:41 +01:00
## 1. Der Import-Prozess (16-Schritte-Workflow)
2025-12-27 22:13:11 +01:00
Der Prozess ist **asynchron**, **idempotent** und wird nun in zwei logische Durchläufe (Passes) unterteilt, um die semantische Genauigkeit zu maximieren.
2025-12-27 22:13:11 +01:00
### Phase 1: Pre-Scan & Context (Pass 1)
2025-12-16 18:46:11 +01:00
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.
2025-12-27 22:13:11 +01:00
2. **Markdown lesen:** Rekursives Scannen des Vaults zur Erstellung des Dateiinventars.
2025-12-19 09:02:49 +01:00
3. **Frontmatter Check & Hard Skip (WP-22):**
* Extraktion von `status` und `type`.
2025-12-27 22:13:11 +01:00
* **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.
2025-12-19 09:02:49 +01:00
* 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`.
2025-12-27 22:13:11 +01:00
5. **Config Resolution (WP-14):**
* Bestimmung von `chunking_profile` und `retriever_weight` via zentraler `TypeRegistry`.
2025-12-19 09:02:49 +01:00
* **Priorität:** 1. Frontmatter (Override) -> 2. `types.yaml` (Type) -> 3. Global Default.
2025-12-27 22:13:11 +01:00
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 (<s>, [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`).
2025-12-19 09:02:49 +01:00
* Unbekannte Typen werden in `unknown_edges.jsonl` protokolliert.
2025-12-27 22:13:11 +01:00
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.
2025-12-19 09:02:49 +01:00
---
## 2. Betrieb & CLI Befehle
### 2.1 Standard-Betrieb (Inkrementell)
2025-12-27 22:13:11 +01:00
Erkennt Änderungen via Multi-Hash.
```bash
export QDRANT_URL="http://localhost:6333"
export COLLECTION_PREFIX="mindnet"
2025-12-16 18:46:11 +01:00
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**
2025-12-27 22:13:11 +01:00
> 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)
2025-12-27 22:13:11 +01:00
Notwendig bei Änderungen an `types.yaml`, der Registry oder Modell-Wechsel.
```bash
2025-12-27 22:13:11 +01:00
# --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
2025-12-27 22:13:11 +01:00
Das Chunking ist profilbasiert und bezieht seine Konfiguration dynamisch aus der `TypeRegistry`.
2025-12-27 22:13:11 +01:00
### 3.1 Profile und Strategien
2025-12-16 14:48:04 +01:00
| Profil | Strategie | Parameter | Einsatzgebiet |
| :--- | :--- | :--- | :--- |
2025-12-27 22:13:11 +01:00
| `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. |
2025-12-16 14:48:04 +01:00
2025-12-16 18:46:11 +01:00
### 3.2 Die `by_heading` Logik (v2.9 Hybrid)
2025-12-16 14:48:04 +01:00
2025-12-27 22:13:11 +01:00
Die Strategie `by_heading` zerlegt Texte anhand ihrer Struktur (Überschriften). Sie unterstützt ein "Safety Net" gegen zu große Chunks.
2025-12-16 14:48:04 +01:00
* **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.
2025-12-25 22:21:41 +01:00
* *Merge-Check:* Wenn der vorherige Chunk leer war (nur Überschriften), wird gemergt.
2025-12-16 18:46:11 +01:00
* *Safety Net:* Wird ein Abschnitt zu lang (> `max` Token), wird auch ohne Überschrift getrennt.
2025-12-16 14:48:04 +01:00
* **Modus "Soft" (`strict_heading_split: false`):**
2025-12-19 09:02:49 +01:00
* **Hierarchie-Check:** Überschriften *oberhalb* des Split-Levels erzwingen **immer** einen Split.
2025-12-25 22:21:41 +01:00
* **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.
2025-12-16 18:46:11 +01:00
* *Safety Net:* Auch hier greift das `max` Token Limit.
2025-12-16 14:48:04 +01:00
---
2025-12-19 09:02:49 +01:00
## 4. Edge-Erzeugung & Prioritäten (Provenance)
Kanten werden nach Vertrauenswürdigkeit (`provenance`) priorisiert. Die höhere Prio gewinnt.
2025-12-25 19:39:16 +01:00
| Prio | Quelle | Rule ID / Provenance | Confidence | Erläuterung |
2025-12-19 09:02:49 +01:00
| :--- | :--- | :--- | :--- | :--- |
| **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. |
2025-12-27 22:13:11 +01:00
| **4** | Semantic AI | `semantic_ai` | **0.90** | KI-validiert gegen LocalBatchCache. |
2025-12-19 09:02:49 +01:00
| **5** | Type Default | `edge_defaults` | **0.70** | Heuristik aus der Registry. |
2025-12-25 19:39:16 +01:00
| **6** | Struktur | `structure` | **1.00** | System-interne Verkettung (`belongs_to`). |
---
2025-12-19 09:02:49 +01:00
## 5. Quality Gates & Monitoring
2025-12-27 22:13:11 +01:00
**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.
2025-12-27 22:13:11 +01:00
**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.
2025-12-27 22:13:11 +01:00
**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.