mindnet/docs/03_Technical_References/03_tech_chat_backend.md

13 KiB

doc_type audience scope status version context
technical_reference developer, architect backend, chat, llm_service, traffic_control, resilience, agentic_rag, moe active 3.0.0 Technische Implementierung des FastAPI-Routers, des hybriden LLMService (v3.5.2), WP-25 Agentic Multi-Stream RAG, WP-25a Mixture of Experts (MoE) 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 Mixture of Experts (MoE) Architektur (WP-25a)

Seit WP-25a nutzt MindNet eine profilbasierte Experten-Steuerung statt einer globalen Provider-Konfiguration. Jede Systemaufgabe wird einem dedizierten Profil zugewiesen:

Profil-Registry (llm_profiles.yaml):

  • synthesis_pro: Hochwertige Synthese für Chat-Antworten
  • tech_expert: Fachspezialist für Code & Technik
  • compression_fast: Schnelle Kompression & Routing
  • ingest_validator: Deterministische Validierung (Temperature 0.0)
  • identity_safe: Lokaler Anker (Ollama/Phi-3) für maximale Privacy

Rekursive Fallback-Kaskade: Der LLMService (v3.5.2) implementiert eine automatische Fallback-Logik:

  1. Versucht primäres Profil (z.B. synthesis_pro)
  2. Bei Fehler → fallback_profile (z.B. synthesis_backup)
  3. Bei weiterem Fehler → nächster Fallback (z.B. identity_safe)
  4. Schutz gegen Zirkel-Referenzen via visited_profiles-Tracking

Integration:

  • Intent-Routing: Nutzt router_profile (z.B. compression_fast)
  • Stream-Kompression: Nutzt compression_profile pro Stream
  • Synthese: Nutzt llm_profile aus Strategie-Konfiguration
  • Ingestion: Nutzt ingest_validator für binäre Validierungen

1.3 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.4 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.5 Pre-Synthesis Kompression (WP-25a)

Wissens-Streams, die den Schwellenwert (compression_threshold) überschreiten, werden asynchron verdichtet, bevor sie die Synthese erreichen:

Kompression-Logik:

  • Schwellenwert: Konfigurierbar pro Stream (z.B. 2500 Zeichen für Values Stream)
  • Profil: Nutzt compression_profile (z.B. compression_fast für schnelle Zusammenfassung)
  • Parallelisierung: Mehrere Streams können gleichzeitig komprimiert werden
  • Fehlerbehandlung: Kompressions-Fehler blockieren nicht die Synthese (Original-Content wird verwendet)

Vorteile:

  • Reduziert Token-Verbrauch bei langen Streams
  • Beschleunigt Synthese durch kürzere Kontexte
  • Erhält Relevanz durch intelligente Zusammenfassung

1.6 Wissens-Synthese (WP-25/25a)

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 (Profil-gesteuert):

  • FACT_WHAT/FACT_WHEN: Nutzt synthesis_pro - Kombiniert Fakten, Biographie und Technik.
  • DECISION: Nutzt synthesis_pro - Wägt Fakten gegen Werte ab, evaluiert Risiken.
  • EMPATHY: Nutzt synthesis_pro - Fokus auf Biographie und Werte.
  • CODING: Nutzt tech_expert - Spezialisiertes Modell für Code & Technik.

Profil-Auflösung: Jede Strategie kann ein individuelles llm_profile definieren. Fehlt diese Angabe, wird synthesis_pro als Standard verwendet.

1.7 RAG Flow (Technisch - WP-25a)

Wenn der Intent nicht INTERVIEW ist, wird folgender Flow ausgeführt:

  1. Intent Detection: Hybrid Router klassifiziert die Anfrage via router_profile (z.B. compression_fast).
  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. Pre-Synthesis Kompression (WP-25a):
    • Streams über compression_threshold werden via compression_profile verdichtet.
    • Parallelisierung über asyncio.gather() für mehrere Streams gleichzeitig.
  4. Wissens-Synthese:
    • Strategie-spezifisches llm_profile (z.B. tech_expert für CODING) steuert die finale Antwortgenerierung.
    • Fallback-Kaskade bei Fehlern (automatisch via LLMService).
  5. Context Formatting:
    • Stream-Ergebnisse werden in formatierte Kontext-Strings umgewandelt.
    • Ollama Context-Throttling: Kontext wird auf MAX_OLLAMA_CHARS begrenzt (Standard: 10.000).
  6. Synthese:
    • DecisionEngine._generate_final_answer() kombiniert alle Streams.
    • Template-basierte Prompt-Konstruktion mit Stream-Variablen.
  7. 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.