--- doc_type: technical_reference audience: developer, architect scope: backend, chat, llm_service, traffic_control, resilience, agentic_rag status: active version: 2.9.3 context: "Technische Implementierung des FastAPI-Routers, des hybriden LLMService (v3.4.2), WP-25 Agentic Multi-Stream RAG und WP-20 Resilienz-Logik." --- # Chat Backend & Agentic Multi-Stream RAG ## 1. Hybrid Router & Intent-basiertes Routing (WP-25) Der zentrale Einstiegspunkt für jede Chatanfrage ist der **Hybrid Router** (`app/routers/chat.py`). Seit WP-25 agiert das System als **Agentic Orchestrator**, der Nutzeranfragen analysiert, in parallele Wissens-Streams aufteilt und diese zu einer kontextreichen, wertebasierten Antwort synthetisiert. ### 1.1 Intent-Erkennung (Hybrid-Modus) Der Router nutzt einen **Hybrid-Modus** mit Keyword-Fast-Path und LLM-Slow-Path: 1. **Keyword Fast-Path (Sofortige Erkennung):** * Prüft `trigger_keywords` aus `decision_engine.yaml` (z.B. "Soll ich", "Wann", "Was ist"). * Wenn Match: Sofortige Intent-Zuordnung ohne LLM-Call. * **Strategien:** FACT_WHAT, FACT_WHEN, DECISION, EMPATHY, CODING, INTERVIEW. 2. **Type Keywords (Interview-Modus):** * Lädt `types.yaml` und prüft `detection_keywords` für Objekt-Erkennung. * Wenn Match und keine Frage: **INTERVIEW Modus** (Datenerfassung). 3. **LLM Slow-Path (Semantische Analyse):** * Wenn unklar: Anfrage an `DecisionEngine._determine_strategy()` zur LLM-basierten Klassifizierung. * Nutzt `intent_router_v1` Prompt aus `prompts.yaml`. ### 1.2 Prompt-Auflösung (Bulletproof Resolution) Um Kompatibilitätsprobleme mit verschachtelten YAML-Prompts zu vermeiden, nutzt der Router die Methode `llm.get_prompt()`. Diese implementiert eine **Provider-Kaskade**: * **Spezifischer Provider:** Das System sucht zuerst nach einem Prompt für den aktiv konfigurierten Provider (z.B. `openrouter`). * **Cloud-Stil Fallback:** Existiert dieser nicht, erfolgt ein Fallback auf das `gemini`-Template. * **Basis-Fallback:** Als letzte Instanz wird das `ollama`-Template geladen. * **String-Garantie:** Die Methode garantiert die Rückgabe eines Strings (selbst bei verschachtelten YAML-Dicts), was 500-Fehler bei String-Operationen wie `.replace()` oder `.format()` verhindert. ### 1.2 Multi-Stream Retrieval (WP-25) Anstelle einer einzelnen Suche führt die `DecisionEngine` nun **parallele Abfragen** in spezialisierten Streams aus: **Stream-Library (definiert in `decision_engine.yaml`):** * **Values Stream:** Extrahiert Identität, Ethik und Prinzipien (`value`, `principle`, `belief`, etc.). * **Facts Stream:** Liefert operative Daten zu Projekten, Tasks und Status (`project`, `decision`, `task`, etc.). * **Biography Stream:** Greift auf persönliche Erfahrungen und Journal-Einträge zu (`experience`, `journal`, `profile`). * **Risk Stream:** Identifiziert Hindernisse und potenzielle Gefahren (`risk`, `obstacle`, `bias`). * **Tech Stream:** Bündelt technisches Wissen, Code und Dokumentation (`concept`, `source`, `glossary`, etc.). **Stream-Konfiguration:** * Jeder Stream nutzt individuelle **Edge-Boosts** (z.B. `guides: 3.0` für Values Stream). * **Filter-Types** sind strikt mit `types.yaml` (v2.7.0) synchronisiert. * **Query-Templates** transformieren die ursprüngliche Anfrage für spezialisierte Suche. **Parallele Ausführung:** * `asyncio.gather()` führt alle aktiven Streams gleichzeitig aus. * **Stream-Tracing:** Jeder Treffer wird mit `stream_origin` markiert für Feedback-Optimierung. * **Fehlerbehandlung:** Einzelne Stream-Fehler blockieren nicht die gesamte Anfrage. ### 1.3 Wissens-Synthese (WP-25) Die Zusammenführung der Daten erfolgt über spezialisierte Templates in der `prompts.yaml`: **Template-Struktur:** * Explizite Variablen für jeden Stream (z.B. `{values_stream}`, `{risk_stream}`). * **Pre-Initialization:** Alle möglichen Stream-Variablen werden vorab initialisiert (verhindert KeyErrors). * **Provider-spezifische Templates:** Separate Versionen für Ollama, Gemini und OpenRouter. **Synthese-Strategien:** * **FACT_WHAT/FACT_WHEN:** Kombiniert Fakten, Biographie und Technik. * **DECISION:** Wägt Fakten gegen Werte ab, evaluiert Risiken. * **EMPATHY:** Fokus auf Biographie und Werte. * **CODING:** Technik und Fakten. ### 1.4 RAG Flow (Technisch) Wenn der Intent nicht `INTERVIEW` ist, wird folgender Flow ausgeführt: 1. **Intent Detection:** Hybrid Router klassifiziert die Anfrage. 2. **Multi-Stream Retrieval:** * Parallele Abfragen in spezialisierten Streams via `DecisionEngine._execute_parallel_streams()`. * Jeder Stream nutzt individuelle Filter, Edge-Boosts und Query-Templates. 3. **Context Formatting:** * Stream-Ergebnisse werden in formatierte Kontext-Strings umgewandelt. * **Ollama Context-Throttling:** Kontext wird auf `MAX_OLLAMA_CHARS` begrenzt (Standard: 10.000). 4. **Synthese:** * `DecisionEngine._generate_final_answer()` kombiniert alle Streams. * Template-basierte Prompt-Konstruktion mit Stream-Variablen. 5. **Response:** * LLM-Antwort wird generiert (provider-spezifisch). * **Sources:** Alle Treffer aus allen Streams werden dedupliziert und zurückgegeben. --- ## 2. LLM Service & Traffic Control (WP-20 / WP-25) Der `LLMService` (`app/services/llm_service.py`, v3.4.2) fungiert als zentraler Hybrid-Client für OpenRouter, Google Gemini und Ollama. Er schützt das System vor Überlastung und verwaltet Quoten. **WP-25 Integration:** * **Lazy Initialization:** `DecisionEngine` wird erst bei Bedarf initialisiert (verhindert Circular Imports). * **Ingest-Stability Patch:** Entfernung des <5-Zeichen Guards ermöglicht YES/NO Validierungen beim Vault-Import. * **Empty Response Guard:** Sicherung gegen leere `choices` Arrays bei OpenRouter (verhindert JSON-Errors). Mit Version 2.8.1 wurde die Architektur der Antwort-Generierung grundlegend gehärtet: A. Fail-Fast Prinzip (No-Retry Chat) Im Gegensatz zur Ingestion-Pipeline nutzt das Chat-Backend für Echtzeit-Anfragen keine internen Retries (max_retries=0). Scheitert ein Provider (Timeout/Fehler), wird sofort die Fallback-Kaskade eingeleitet oder der Deep Fallback zu Ollama getriggert. Dies verhindert die kumulative Wartezeit von mehreren Minuten bei Provider-Störungen. B. Context-Throttling & Memory Guard Drosselung: Vor der Übergabe an Ollama prüft die chat.py, ob der Kontext (RAG-Hits) die Grenze von MAX_OLLAMA_CHARS überschreitet und kürzt diesen ggf.. Modell-Lock: Der LLMService erzwingt im Ollama-Payload den Parameter num_ctx: 8192. Dies stabilisiert den VRAM-Verbrauch und verhindert, dass das Modell versucht, speicherintensive 128k-Kontexte zu reservieren. ### 2.1 Prioritäts-Semaphor Jeder LLM-Request steuert über ein `priority`-Flag den Zugriff auf Hardware- und API-Ressourcen: | Priority | Verwendung | Limitierung | | :--- | :--- | :--- | | **realtime** | Chat-Anfragen, Intent-Routing | Keine (Hardware-Limit) | | **background** | Smart Edge Allocation, Import-Tasks | `MINDNET_LLM_BACKGROUND_LIMIT` | **Funktionsweise:** * Hintergrund-Tasks nutzen ein globales `asyncio.Semaphore`. * Das Limit (Standard: 2) verhindert, dass parallele Import-Vorgänge die API-Quoten oder die lokale CPU erschöpfen. * Chat-Tasks umgehen die Semaphore für minimale Latenz. ### 2.2 Task-Mapping & Model Selection Die Konfiguration ermöglicht eine spezialisierte Modell-Auswahl je nach Anwendungsfall: * **Semantische Extraktion (Turbo):** Nutzt bevorzugt `OPENROUTER_MODEL` (Mistral-7B) für schnelles und präzises JSON-Parsing. * **RAG-Chat:** Nutzt bevorzugt `GEMINI_MODEL` (2.5 flash-lite) für hohe Kapazität und Stabilität mittels erzwungener **v1-API Version**. ### 2.3 Timeout-Konfiguration Deadlocks und "hängende" Importe werden durch differenzierte Timeouts verhindert: * **Cloud-Calls (OpenRouter/Gemini):** Strikte **45 Sekunden** zur Vermeidung von Blockaden bei Provider-Latenz. * **Lokales LLM (Ollama):** Konfigurierbar via `MINDNET_LLM_TIMEOUT` (Default: 300s). --- ## 3. Resilience & Quota Management (WP-20) In v2.8 wurde ein intelligentes Fehler-Handling für Cloud-Provider implementiert: 1. **Rate-Limit Erkennung:** Der Service erkennt HTTP 429 Fehler sowie provider-spezifische Meldungen wie `RESOURCE_EXHAUSTED`. 2. **Intelligenter Backoff:** Statt sofort auf das langsame lokale Modell zu wechseln, pausiert das System für die Dauer von `LLM_RATE_LIMIT_WAIT` (Standard: 60s). 3. **Cloud-Retry:** Nach der Pause erfolgt ein erneuter Versuch (bis zu `LLM_RATE_LIMIT_RETRIES` Mal). 4. **Ollama Fallback:** Erst nach Erschöpfung der Retries schaltet das System auf den lokalen Ollama um, um die Betriebssicherheit zu gewährleisten ("Quoten-Schutz"). 5. **Deep Fallback Support:** Der Service stellt die Infrastruktur für den inhaltsbasierten Fallback (v2.11.14) bereit, falls die Cloud zwar technisch antwortet, aber inhaltlich (z.B. wegen Policy-Filtern oder Silent Refusal) keine validen Daten liefert. --- ## 4. Feedback Traceability & Stream-Tracing (WP-25) Unterstützt das geplante Self-Tuning (WP08) und ermöglicht Stream-spezifische Optimierung. 1. **Query ID:** Generiert bei jedem `/chat` Call eine `UUIDv4`. 2. **Stream-Tracing:** Jeder Treffer enthält `stream_origin` für Zuordnung zum Quell-Stream. 3. **Logging:** Speichert einen Snapshot in `data/logs/query_snapshot.jsonl` (Input + Retrieved Context + Intent). 4. **Feedback:** Der `/feedback` Endpoint verknüpft das User-Rating (1-5) mit der `query_id` und `stream_origin`. ## 5. Lifespan Management (WP-25) Die FastAPI-Anwendung (`app/main.py`, v1.0.0) implementiert **Lifespan-Management** für sauberen Startup und Shutdown: **Startup:** * Integritäts-Check der WP-25 Konfiguration (`decision_engine.yaml`, `prompts.yaml`). * Validierung kritischer Dateien vor dem Start. **Shutdown:** * Ressourcen-Cleanup (LLMService-Connections schließen). * Graceful Shutdown für asynchrone Prozesse. **Globale Fehlerbehandlung:** * Fängt unerwartete Fehler in der Multi-Stream Kette ab. * Strukturierte JSON-Responses bei Engine-Fehlern.