# Mindnet v2.6 – Technische Architektur **Datei:** `docs/mindnet_technical_architecture_v2.6.md` **Stand:** 2025-12-12 **Status:** **FINAL** (Integrierter Stand WP01–WP15: Smart Edges & Traffic Control) **Quellen:** `Programmplan_V2.6.md`, `Handbuch.md`, `chunking_strategy.md`, `wp04_retriever_scoring.md`. > **Ziel dieses Dokuments:** > Vollständige Beschreibung der technischen Architektur inkl. Graph-Datenbank, Retrieval-Logik, der **RAG-Komponenten (Decision Engine & Hybrid Router)**, des **Traffic Control Systems** und dem **Frontend (Streamlit)**. ---
📖 Inhaltsverzeichnis (Klicken zum Öffnen) - [Mindnet v2.6 – Technische Architektur](#mindnet-v26--technische-architektur) - [](#) - [1. Systemüberblick](#1-systemüberblick) - [1.1 Architektur-Zielbild](#11-architektur-zielbild) - [1.2 Verzeichnisstruktur \& Komponenten (Post-WP15)](#12-verzeichnisstruktur--komponenten-post-wp15) - [2. Datenmodell \& Collections (Qdrant)](#2-datenmodell--collections-qdrant) - [2.1 Notes Collection (`_notes`)](#21-notes-collection-prefix_notes) - [2.2 Chunks Collection (`_chunks`)](#22-chunks-collection-prefix_chunks) - [2.3 Edges Collection (`_edges`)](#23-edges-collection-prefix_edges) - [3. Konfiguration](#3-konfiguration) - [3.1 Typ-Registry (`config/types.yaml`)](#31-typ-registry-configtypesyaml) - [3.2 Retriever-Config (`config/retriever.yaml`)](#32-retriever-config-configretrieveryaml) - [3.3 Decision Engine (`config/decision_engine.yaml`)](#33-decision-engine-configdecision_engineyaml) - [3.4 Prompts (`config/prompts.yaml`)](#34-prompts-configpromptsyaml) - [3.5 Environment (`.env`)](#35-environment-env) - [4. Import-Pipeline (Markdown → Qdrant)](#4-import-pipeline-markdown--qdrant) - [4.1 Verarbeitungsschritte (Async + Smart)](#41-verarbeitungsschritte-async--smart) - [5. Retriever-Architektur \& Scoring](#5-retriever-architektur--scoring) - [5.1 Betriebsmodi](#51-betriebsmodi) - [5.2 Scoring-Formel (WP04a)](#52-scoring-formel-wp04a) - [5.3 Explanation Layer (WP04b)](#53-explanation-layer-wp04b) - [5.4 Graph-Expansion](#54-graph-expansion) - [6. RAG \& Chat Architektur (WP06 Hybrid Router + WP07 Interview)](#6-rag--chat-architektur-wp06-hybrid-router--wp07-interview) - [6.1 Architektur-Pattern: Intent Router v5](#61-architektur-pattern-intent-router-v5) - [6.2 Traffic Control (Priorisierung)](#62-traffic-control-priorisierung) - [6.3 Schritt 1: Intent Detection (Question vs. Action)](#63-schritt-1-intent-detection-question-vs-action) - [6.4 Schritt 2: Strategy Resolution](#64-schritt-2-strategy-resolution) - [6.5 Schritt 3: Retrieval vs. Extraction](#65-schritt-3-retrieval-vs-extraction) - [6.6 Schritt 4: Generation \& Response](#66-schritt-4-generation--response) - [7. Frontend Architektur (WP10)](#7-frontend-architektur-wp10) - [7.1 Kommunikation](#71-kommunikation) - [7.2 Features \& UI-Logik](#72-features--ui-logik) - [7.3 Draft-Editor \& Healing Parser (Neu in WP10a/v2.5)](#73-draft-editor--healing-parser-neu-in-wp10av25) - [7.4 State Management (Resurrection Pattern)](#74-state-management-resurrection-pattern) - [7.5 Deployment Ports](#75-deployment-ports) - [8. Feedback \& Logging Architektur (WP04c)](#8-feedback--logging-architektur-wp04c) - [8.1 Komponenten](#81-komponenten) - [8.2 Log-Dateien](#82-log-dateien) - [8.3 Traceability](#83-traceability) - [9. Indizes \& Performance](#9-indizes--performance) - [10. Offene Punkte / Known Limitations](#10-offene-punkte--known-limitations)
--- ## 1. Systemüberblick ### 1.1 Architektur-Zielbild Mindnet ist ein **lokales RAG-System (Retrieval Augmented Generation)** mit Web-Interface. 1. **Source:** Markdown-Notizen in einem Vault (Obsidian-kompatibel). 2. **Pipeline:** Ein Python-Importer transformiert diese in **Notes**, **Chunks** und **Edges**. * **Neu in v2.6:** Intelligente Kanten-Zuweisung durch lokale LLMs (**Smart Edge Allocation**). 3. **Storage:** * **Qdrant:** Vektor-Datenbank für Graph und Semantik (Collections: notes, chunks, edges). * **Local Files (JSONL):** Append-Only Logs für Feedback und Search-History (Data Flywheel). 4. **Backend:** Eine FastAPI-Anwendung stellt Endpunkte für **Semantische** und **Hybride Suche** sowie **Feedback** bereit. * **Update v2.6:** Der Core arbeitet nun vollständig **asynchron (AsyncIO)** mit **Traffic Control** (Semaphore zur Lastverteilung). 5. **Frontend:** Streamlit-App (`ui.py`) für Interaktion und Visualisierung inkl. **Draft Editor**, **Active Intelligence** und **Healing Parser**. 6. **Inference:** Lokales LLM (Ollama: Phi-3 Mini) für RAG-Chat und Antwortgenerierung. Embedding via `nomic-embed-text`. Das System arbeitet **deterministisch** (stabile IDs) und ist **konfigurationsgetrieben** (`types.yaml`, `retriever.yaml`, `decision_engine.yaml`, `prompts.yaml`). ### 1.2 Verzeichnisstruktur & Komponenten (Post-WP15) /mindnet/ ├── app/ │ ├── main.py # FastAPI Einstiegspunkt │ ├── core/ │ │ ├── ingestion.py # NEU: Async Ingestion mit Change Detection │ │ ├── qdrant.py # Client-Factory & Connection │ │ ├── qdrant_points.py # Low-Level Point Operations (Upsert/Delete) │ │ ├── note_payload.py # Bau der Note-Objekte │ │ ├── chunk_payload.py # Bau der Chunk-Objekte │ │ ├── chunker.py # Smart Chunker Orchestrator (WP15) │ │ ├── edges.py # Edge-Datenstrukturen │ │ ├── derive_edges.py # Logik der Kantenableitung (WP03) │ │ ├── graph_adapter.py # Subgraph & Reverse-Lookup (WP04b) │ │ └── retriever.py # Scoring, Expansion & Explanation (WP04a/b) │ ├── models/ # Pydantic DTOs │ │ └── dto.py # Zentrale DTO-Definition │ ├── routers/ │ │ ├── query.py # Such-Endpunkt │ │ ├── ingest.py # NEU: API für Save & Analyze (WP11) │ │ ├── chat.py # Hybrid Router v5 & Interview Logic (WP06/07) │ │ ├── feedback.py # Feedback-Endpunkt (WP04c) │ │ └── ... │ ├── services/ │ │ ├── llm_service.py # Ollama Chat Client mit Traffic Control (v2.8.0) │ │ ├── semantic_analyzer.py# NEU: LLM-Filter für Edges (WP15) │ │ ├── embeddings_client.py# NEU: Async Embeddings (HTTPX) │ │ ├── feedback_service.py # Logging (JSONL Writer) │ │ └── discovery.py # NEU: Intelligence Logic (WP11) │ ├── frontend/ # NEU (WP10) │ │ └── ui.py # Streamlit Application inkl. Healing Parser │ └── main.py # Entrypoint der API ├── config/ # YAML-Konfigurationen (Single Source of Truth) │ ├── types.yaml # Import-Regeln & Smart-Edge Config │ ├── prompts.yaml # LLM Prompts & Interview Templates (WP06/07) │ ├── decision_engine.yaml # Router-Strategien (Actions only) │ └── retriever.yaml # Scoring-Regeln & Kantengewichte ├── data/ │ └── logs/ # Lokale Logs (search_history.jsonl, feedback.jsonl) ├── scripts/ # CLI-Tools (Import, Diagnose, Reset) │ ├── import_markdown.py # Haupt-Importer CLI (Async) │ ├── payload_dryrun.py # Diagnose: JSON-Generierung ohne DB │ └── edges_full_check.py # Diagnose: Graph-Integrität ├── tests/ # Pytest Suite & Smoke Scripts └── vault/ # Dein lokaler Markdown-Content (Git-ignored) --- ## 2. Datenmodell & Collections (Qdrant) Das Datenmodell verteilt sich auf drei Collections, definiert durch `COLLECTION_PREFIX` (Standard: `mindnet`). ### 2.1 Notes Collection (`_notes`) Repräsentiert die Metadaten einer Datei. * **Zweck:** Filterung, Metadaten-Haltung, Vererbung von Eigenschaften an Chunks. * **Schema (Payload):** | Feld | Datentyp | Beschreibung | Herkunft | | :--- | :--- | :--- | :--- | | `note_id` | Keyword | Stabile ID (UUIDv5 oder Slug). | Frontmatter | | `title` | Text | Titel der Notiz. | Frontmatter | | `type` | Keyword | Logischer Typ (z.B. `concept`). | `types.yaml` Resolver | | `retriever_weight` | Float | Wichtigkeit im Retrieval. | `types.yaml` | | `chunk_profile` | Keyword | Genutztes Chunking-Profil. | `types.yaml` | | `edge_defaults` | List[Str] | Aktive Default-Relationen. | `types.yaml` | | `tags` | List[Kw] | Tags zur Filterung. | Frontmatter | | `updated` | Integer | Zeitstempel (z.B. YYYYMMDD...). | File Stats | | `fulltext` | Text | Gesamter Inhalt (für Export/Rekonstruktion). | Body | ### 2.2 Chunks Collection (`_chunks`) Die atomaren Sucheinheiten. * **Zweck:** Vektorsuche (Embeddings), Granulares Ergebnis. * **Update v2.4:** Vektor-Dimension ist jetzt **768** (für `nomic-embed-text`). * **Schema (Payload):** | Feld | Datentyp | Beschreibung | | :--- | :--- | :--- | | `chunk_id` | Keyword | Deterministisch: `{note_id}#c{index:02d}`. | | `note_id` | Keyword | Referenz zur Note. | | `type` | Keyword | **Kopie des Note-Typs** (Denormalisiert für Filter). | | `text` | Text | **Reiner Inhalt** (ohne Overlap). Anzeige-Text. | | `window` | Text | **Kontext-Fenster** (mit Overlap). Embedding-Basis. | | `ord` | Integer | Sortierreihenfolge (1..N). | | `retriever_weight` | Float | Vererbt von Note. | | `chunk_profile` | Keyword | Vererbt von Note. | | `neighbors_prev` | List[Str] | ID des Vorgänger-Chunks. | | `neighbors_next` | List[Str] | ID des Nachfolger-Chunks. | ### 2.3 Edges Collection (`_edges`) Gerichtete Kanten. Massiv erweitert in WP03 für Provenienz-Tracking. * **Zweck:** Graph-Traversal, Kontext-Anreicherung. * **Schema (Payload):** | Feld | Datentyp | Beschreibung | Wertebereich (Bsp.) | | :--- | :--- | :--- | :--- | | `edge_id` | Keyword | Hash aus (src, dst, kind). | | | `source_id` | Keyword | ID des Start-Chunks. | | | `target_id` | Keyword | ID des Ziel-Chunks (oder Note-Titel). | | | `note_id` | Keyword | Note, die diese Kante definiert. | | | `kind` | Keyword | Art der Beziehung. | `references`, `depends_on`, `next` | | `scope` | Keyword | Geltungsbereich. | Immer `"chunk"` (v2.2). | | `rule_id` | Keyword | Herkunftsregel. | `explicit:wikilink`, `inline:rel` | | `confidence` | Float | Vertrauenswürdigkeit (0.0-1.0). | 1.0, 0.95, 0.7 | | `provenance` | Keyword | Quelle der Kante (Neu in v2.6). | `explicit`, `rule`, `smart` | --- ## 3. Konfiguration Die Logik ist ausgelagert in YAML-Dateien. ### 3.1 Typ-Registry (`config/types.yaml`) Steuert den Import-Prozess. * **Priorität:** Frontmatter > Pfad > Default. * **Neu in v2.6:** * `enable_smart_edge_allocation`: (Bool) Aktiviert den LLM-Filter für diesen Typ. * `detection_keywords`: (List) Keywords für den Hybrid Router ("Objekterkennung"). * **Inhalt (Beispiel):** types: concept: chunk_profile: sliding_standard edge_defaults: ["references", "related_to"] retriever_weight: 0.60 experience: chunk_profile: sliding_smart_edges enable_smart_edge_allocation: true detection_keywords: ["erfahrung", "erlebt"] ### 3.2 Retriever-Config (`config/retriever.yaml`) Steuert das Scoring zur Laufzeit (WP04a). * **Inhalt (Beispiel):** scoring: semantic_weight: 1.0 edge_weight: 0.7 centrality_weight: 0.5 ### 3.3 Decision Engine (`config/decision_engine.yaml`) **Neu in WP06/07:** Steuert den Intent-Router. * Definiert Strategien (`DECISION`, `INTERVIEW`, etc.). * **Update v2.6:** Enthält nur noch **Handlungs-Keywords** (Verben wie "neu", "erstellen"). Objektnamen ("Projekt") werden nun über `types.yaml` aufgelöst. * Definiert LLM-Router-Settings (`llm_fallback_enabled`). ### 3.4 Prompts (`config/prompts.yaml`) Steuert die LLM-Persönlichkeit und Templates. * Enthält Templates für alle Strategien inkl. `interview_template` und neu `router_prompt`. ### 3.5 Environment (`.env`) Erweiterung für LLM-Steuerung und Embedding-Modell: MINDNET_LLM_MODEL=phi3:mini MINDNET_EMBEDDING_MODEL=nomic-embed-text # NEU in v2.3.10 MINDNET_OLLAMA_URL=http://127.0.0.1:11434 MINDNET_LLM_TIMEOUT=300.0 # Neu: Erhöht für CPU-Inference Cold-Starts MINDNET_API_TIMEOUT=300.0 # Neu: Timeout für Frontend-API (Smart Edges brauchen Zeit) MINDNET_DECISION_CONFIG="config/decision_engine.yaml" MINDNET_VAULT_ROOT="./vault" # Neu: Pfad für Write-Back MINDNET_LLM_BACKGROUND_LIMIT=2 # Neu: Limit für parallele Hintergrund-Jobs (Traffic Control) --- ## 4. Import-Pipeline (Markdown → Qdrant) Das Skript `scripts/import_markdown.py` orchestriert den Prozess. **Neu in v2.6:** Der Import nutzt `asyncio` und **Traffic Control**, um Ollama nicht zu überlasten. ### 4.1 Verarbeitungsschritte (Async + Smart) 1. **Discovery & Parsing:** Hash-Vergleich zur Erkennung von Änderungen. 2. **Typauflösung:** Bestimmung des `type` via `types.yaml`. 3. **Config Check:** Laden des `chunk_profile` und `enable_smart_edge_allocation`. 4. **Chunking & Smart Edges (WP15):** * Zerlegung des Textes via `chunker.py`. * Wenn Smart Edges aktiv: Der `SemanticAnalyzer` sendet Chunks an das LLM. * **Traffic Control:** Der Request nutzt `priority="background"`. Die Semaphore (Limit: 2) drosselt die Parallelität. 5. **Kantenableitung (Edge Derivation):** * `derive_edges.py` erzeugt Inline-, Callout- und Default-Edges. 6. **Embedding (Async):** * Der `EmbeddingsClient` (`app/services/embeddings_client.py`) sendet Text-Chunks asynchron an Ollama. * Modell: `nomic-embed-text` (768d). 7. **Upsert:** * Schreiben in Qdrant. Nutzung von `--purge-before-upsert`. * **Strict Mode:** Der Prozess bricht ab, wenn Embeddings leer sind oder Dimension `0` haben. --- ## 5. Retriever-Architektur & Scoring Der Retriever (`app/core/retriever.py`) unterstützt zwei Modi. Für den Chat wird **zwingend** der Hybrid-Modus genutzt. ### 5.1 Betriebsmodi * **Semantic:** Reine Vektorsuche (768d). * **Hybrid:** Vektorsuche + Graph-Expansion (Tiefe N) + Re-Ranking. ### 5.2 Scoring-Formel (WP04a) Die Relevanzberechnung ist nun eine gewichtete Summe: $$ TotalScore = (W_{sem} \cdot S_{sem} \cdot \max(W_{type}, 0)) + (W_{edge} \cdot B_{edge}) + (W_{cent} \cdot B_{cent}) $$ * **Komponenten:** * $S_{sem}$: Semantic Score (Cosine Similarity). * $W_{type}$: `retriever_weight` (aus Note/Chunk Payload). * $B_{edge}$: Edge-Bonus (Summe der Konfidenzen eingehender relevanter Kanten). * $B_{cent}$: Centrality-Bonus (im lokalen Subgraphen). * **Gewichte ($W$):** Stammen aus `retriever.yaml`. ### 5.3 Explanation Layer (WP04b) Der Retriever ist keine Blackbox mehr. Er liefert auf Wunsch (`explain=True`) eine strukturierte Begründung (`Explanation`-Objekt). **Die "Warum"-Logik:** 1. **Semantik:** Prüfung der Cosine-Similarity ("Sehr hohe textuelle Übereinstimmung"). 2. **Typ:** Prüfung des `retriever_weight` ("Bevorzugt, da Entscheidung"). 3. **Graph (Kontext):** * **Hub (Outgoing):** Worauf verweist dieser Treffer? ("Verweist auf Qdrant"). * **Authority (Incoming):** Wer verweist auf diesen Treffer? ("Wird referenziert von Projekt Alpha"). Die API gibt diese Analysen als menschenlesbare Sätze (`reasons`) und als Datenstruktur (`score_breakdown`) zurück. ### 5.4 Graph-Expansion Der Hybrid-Modus lädt dynamisch die Nachbarschaft der Top-K Vektor-Treffer ("Seeds") über `graph_adapter.expand`. Dies baut einen temporären `NetworkX`-artigen Graphen im Speicher (Klasse `Subgraph`), auf dem Boni berechnet werden. --- ## 6. RAG & Chat Architektur (WP06 Hybrid Router + WP07 Interview) Der Flow für eine Chat-Anfrage (`/chat`) wurde in WP06 auf eine **Configuration-Driven Architecture** umgestellt und in WP15 (v2.6) verfeinert. ### 6.1 Architektur-Pattern: Intent Router v5 Die Behandlung einer Anfrage ist nicht mehr hartkodiert, sondern wird dynamisch zur Laufzeit entschieden. * **Input:** User Message. * **Config:** `decision_engine.yaml` (Strategien) + `types.yaml` (Objekte). * **Komponenten:** * **Traffic Control:** `LLMService` priorisiert Chat-Anfragen. * **Question Detection:** Unterscheidung Frage vs. Befehl. ### 6.2 Traffic Control (Priorisierung) Der `LLMService` implementiert zwei Spuren basierend auf `app/services/llm_service.py` (v2.8.0): * **Realtime (Chat):** `priority="realtime"`. Umgeht die Semaphore. Antwortet sofort. * **Background (Import/Analyse):** `priority="background"`. Wartet in der Semaphore (`asyncio.Semaphore`), die lazy mit `MINDNET_LLM_BACKGROUND_LIMIT` initialisiert wird. ### 6.3 Schritt 1: Intent Detection (Question vs. Action) Der Router ermittelt die Absicht (`Intent`) des Nutzers. 1. **Frage-Check:** Wenn der Input ein `?` enthält oder mit W-Wörtern beginnt, wird der **RAG-Modus** erzwungen (oder LLM-Entscheidung). Interviews werden hier unterdrückt. 2. **Keyword Scan (Fast Path):** * Prüfung auf `trigger_keywords` (Handlung) in `decision_engine.yaml`. * Prüfung auf `detection_keywords` (Objekt) in `types.yaml`. * Treffer -> **INTERVIEW Modus** (Erfassen). 3. **LLM Fallback (Slow Path):** * Greift, wenn keine Keywords passen. Sendet Query an LLM Router. ### 6.4 Schritt 2: Strategy Resolution Basierend auf dem Intent lädt der Router die Parameter: * **Bei RAG (FACT/DECISION):** `inject_types` für Strategic Retrieval. * **Bei INTERVIEW (WP07):** `schemas` (Pflichtfelder) basierend auf der erkannten Ziel-Entität (`_detect_target_type`). ### 6.5 Schritt 3: Retrieval vs. Extraction Der Router verzweigt hier: **A) RAG Modus (FACT, DECISION, EMPATHY):** 1. **Primary Retrieval:** Hybride Suche nach der User-Query. 2. **Strategic Retrieval (Conditional):** Wenn `inject_types` definiert sind, erfolgt eine zweite Suche, die explizit auf diese Typen filtert. 3. **Merge:** Ergebnisse werden dedupliziert zusammengeführt. **B) Interview Modus (INTERVIEW):** 1. **Kein Retrieval:** Der Kontext ist der Chat-Verlauf (oder initial die Query). 2. **Schema Injection:** Das Schema für den erkannten Typ (z.B. "Project") wird geladen. 3. **Prompt Assembly:** Der `interview_template` Prompt wird mit der Schema-Definition ("Ziel", "Status") gefüllt. ### 6.6 Schritt 4: Generation & Response * **Templating:** Das LLM erhält den Prompt basierend auf dem gewählten Template. * **Execution:** Der `LLMService` führt den Call mit `priority="realtime"` aus. * **Response:** Rückgabe enthält Antworttext (im Interview-Modus: Markdown Codeblock), Quellenliste und den erkannten `intent`. --- ## 7. Frontend Architektur (WP10) Das Frontend ist eine **Streamlit-Anwendung** (`app/frontend/ui.py`), die als separater Prozess läuft und via HTTP mit dem Backend kommuniziert. ### 7.1 Kommunikation * **Backend-URL:** Konfiguriert via `MINDNET_API_URL` (Default: `http://localhost:8002`). * **Endpoints:** * `/chat` (Interaktion) * `/feedback` (Bewertungen) * `/ingest/analyze` (Active Intelligence / Link-Vorschläge) * `/ingest/save` (Persistence / Speichern im Vault) * **Resilienz:** Das Frontend nutzt `MINDNET_API_TIMEOUT` (300s), um auf langsame Backend-Prozesse (Smart Edges) zu warten. ### 7.2 Features & UI-Logik * **State Management:** Session-State speichert Chat-Verlauf und `query_id`. * **Visualisierung:** * **Intent Badges:** Zeigt Router-Entscheidung (`DECISION`, `INTERVIEW`, etc.). * **Source Expanders:** Zeigt verwendete Chunks inkl. Score und "Why"-Explanation. * **Sidebar:** Zeigt Suchhistorie (Log-basiert) und Konfiguration. ### 7.3 Draft-Editor & Healing Parser (Neu in WP10a/v2.5) Wenn der Intent `INTERVIEW` ist, rendert die UI statt einer Textblase den **Draft-Editor**. 1. **Parsing:** Die Funktion `parse_markdown_draft` extrahiert den Codeblock aus der LLM-Antwort. * **Healing:** Erkennt und repariert defekte YAML-Frontmatter (z.B. fehlendes schließendes `---`), falls das LLM unter Last Fehler macht. 2. **Sanitization (`normalize_meta_and_body`):** * Prüft den YAML-Frontmatter auf unerlaubte Felder (Halluzinationen des LLMs). * Verschiebt ungültige Felder (z.B. "Situation") in den Body der Notiz. 3. **Editor Widget:** `st.text_area` erlaubt das Bearbeiten des Inhalts vor dem Speichern. 4. **Save Action:** Speichert über `/ingest/save` atomar in Vault und DB. Erzeugt intelligente Dateinamen via `slugify`. ### 7.4 State Management (Resurrection Pattern) Um Datenverlust bei Tab-Wechseln (Chat <-> Editor) zu verhindern, nutzt `ui.py` ein Persistenz-Muster: * Daten liegen in `st.session_state[data_key]`. * Widgets liegen in `st.session_state[widget_key]`. * Callbacks (`on_change`) synchronisieren Widget -> Data. * Beim Neu-Rendern wird Widget-State aus Data-State wiederhergestellt. ### 7.5 Deployment Ports Zur sauberen Trennung von Prod und Dev laufen Frontend und Backend auf dedizierten Ports: | Umgebung | Backend (FastAPI) | Frontend (Streamlit) | | :--- | :--- | :--- | | **Production** | 8001 | 8501 | | **Development** | 8002 | 8502 | --- ## 8. Feedback & Logging Architektur (WP04c) Mindnet implementiert ein "Data Flywheel" zur späteren Optimierung (Self-Tuning). ### 8.1 Komponenten * **Feedback Service (`app/services/feedback_service.py`):** Kapselt die Schreibzugriffe. * **Storage:** Lokales Dateisystem (`data/logs/`), Format JSONL (Line-delimited JSON). ### 8.2 Log-Dateien 1. **`search_history.jsonl`**: * Speichert jede Anfrage an `/query` und `/chat`. * Enthält: `query_id`, `query_text`, `timestamp`, `hits` (inkl. `score_breakdown` Snapshots). * Zweck: Trainingsdaten ("Was hat das System gesehen?"). 2. **`feedback.jsonl`**: * Speichert User-Reaktionen an `/feedback`. * Enthält: `query_id`, `node_id`, `score` (1-5), `comment`. * **Granularität:** Kann sich auf `generated_answer` (Global) oder eine spezifische `node_id` (Quelle) beziehen. * Zweck: Labels ("War es gut?"). ### 8.3 Traceability Die `query_id` (UUIDv4) wird im `/query` Response generiert und muss vom Client beim `/feedback` Aufruf mitgesendet werden. Dies ermöglicht den Join zwischen Snapshot und Bewertung. --- ## 9. Indizes & Performance Damit Qdrant performant bleibt, sind Payload-Indizes essenziell. **Erforderliche Indizes:** * **Notes:** `note_id`, `type`, `tags`. * **Chunks:** `note_id`, `chunk_id`, `type`. * **Edges:** `source_id`, `target_id`, `kind`, `scope`, `note_id`. Validierung erfolgt über `tests/ensure_indexes_and_show.py`. --- ## 10. Offene Punkte / Known Limitations 1. **Multi-Target Inline-Relations:** * `rel: similar_to [[A]] [[B]]` wird aktuell parser-seitig nicht unterstützt. * Workaround: Zwei separate Inline-Links `[[rel:similar_to A]] [[rel:similar_to B]]`. 2. **Unresolved Targets:** * Kanten zu Notizen, die noch nicht existieren, werden mit `target_id="Titel"` angelegt. * Heilung durch `scripts/resolve_unresolved_references.py` möglich. 3. **Hardware-Last bei Smart Import:** * Der "Smart Edge" Import ist rechenintensiv. Trotz Traffic Control kann die Antwortzeit im Chat leicht steigen, wenn die GPU am VRAM-Limit arbeitet.