14 KiB
| doc_type | audience | scope | status | version | context |
|---|---|---|---|---|---|
| technical_reference | developer, architect | backend, chat, llm_service, traffic_control, resilience, agentic_rag, moe, lazy_prompts | active | 3.1.1 | Technische Implementierung des FastAPI-Routers, des hybriden LLMService (v3.5.5), WP-25 Agentic Multi-Stream RAG, WP-25a Mixture of Experts (MoE), WP-25b Lazy-Prompt-Orchestration 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 - WP-25b)
Der Router nutzt einen Hybrid-Modus mit Keyword-Fast-Path und LLM-Slow-Path:
- Keyword Fast-Path (Sofortige Erkennung):
- Prüft
trigger_keywordsausdecision_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.
- Prüft
- Type Keywords (Interview-Modus):
- Lädt
types.yamlund prüftdetection_keywordsfür Objekt-Erkennung. - Wenn Match und keine Frage: INTERVIEW Modus (Datenerfassung).
- Lädt
- LLM Slow-Path (Semantische Analyse - WP-25b):
- Wenn unklar: Anfrage an
DecisionEngine._determine_strategy()zur LLM-basierten Klassifizierung. - Lazy-Prompt-Loading: Nutzt
prompt_key="intent_router_v1"mitvariables={"query": query} - Ultra-robustes Parsing: Regex-basierter Intent-Parser bereinigt Modell-Artefakte (z.B.
CODING[/S]→CODING) - Fallback: Bei unklarem Intent →
FACT_WHAT
- Wenn unklar: Anfrage an
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-Antwortentech_expert: Fachspezialist für Code & Technikcompression_fast: Schnelle Kompression & Routingingest_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:
- Versucht primäres Profil (z.B.
synthesis_pro) - Bei Fehler →
fallback_profile(z.B.synthesis_backup) - Bei weiterem Fehler → nächster Fallback (z.B.
identity_safe) - Schutz gegen Zirkel-Referenzen via
visited_profiles-Tracking
Integration:
- Intent-Routing: Nutzt
router_profile(z.B.compression_fast) - Stream-Kompression: Nutzt
compression_profilepro Stream - Synthese: Nutzt
llm_profileaus Strategie-Konfiguration - Ingestion: Nutzt
ingest_validatorfür binäre Validierungen
1.3 Hierarchisches Prompt-Resolution-System (WP-25b)
Seit WP-25b nutzt MindNet eine dreistufige hierarchische Prompt-Auflösung mit Lazy-Loading. Prompts werden erst im Moment des Modellaustauschs geladen, basierend auf dem exakt aktiven Modell.
Hierarchische Auflösung (llm_service.py v3.5.5):
-
Level 1 (Modell-ID): Suche nach exakten Übereinstimmungen für die Modell-ID (z.B.
google/gemini-2.0-flash-exp:free).- Vorteil: Modell-spezifische Optimierungen (z.B. für Gemini 2.0, Llama 3.3, Qwen 2.5)
- Logging:
🎯 [PROMPT-TRACE] Level 1 Match: Model-specific
-
Level 2 (Provider): Fallback auf allgemeine Provider-Anweisungen (z.B.
openrouteroderollama).- Vorteil: Bewährte Standards aus v3.1.2 bleiben erhalten
- Logging:
📡 [PROMPT-TRACE] Level 2 Match: Provider-fallback
-
Level 3 (Default): Globaler Sicherheits-Satz zur Vermeidung von Fehlern bei unbekannten Konfigurationen.
- Fallback-Kette:
default→gemini→ollama→"" - Logging:
⚓ [PROMPT-TRACE] Level 3 Match: Global Default
- Fallback-Kette:
Lazy-Prompt-Orchestration:
- Lazy Loading: Prompts werden erst zur Laufzeit geladen, wenn das aktive Modell bekannt ist
- Parameter:
prompt_keyundvariablesstatt vorformatierter Strings - Vorteil: Maximale Resilienz bei Modell-Fallbacks (Cloud → Local)
- Traceability: Vollständige Transparenz über genutzte Instruktionen via
[PROMPT-TRACE]Logs
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.0fü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_originmarkiert 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_fastfü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:
- Intent Detection: Hybrid Router klassifiziert die Anfrage via
router_profile(z.B.compression_fast). - Multi-Stream Retrieval:
- Parallele Abfragen in spezialisierten Streams via
DecisionEngine._execute_parallel_streams(). - Jeder Stream nutzt individuelle Filter, Edge-Boosts und Query-Templates.
- Parallele Abfragen in spezialisierten Streams via
- Pre-Synthesis Kompression (WP-25a):
- Streams über
compression_thresholdwerden viacompression_profileverdichtet. - Parallelisierung über
asyncio.gather()für mehrere Streams gleichzeitig.
- Streams über
- Wissens-Synthese:
- Strategie-spezifisches
llm_profile(z.B.tech_expertfür CODING) steuert die finale Antwortgenerierung. - Fallback-Kaskade bei Fehlern (automatisch via LLMService).
- Strategie-spezifisches
- Context Formatting:
- Stream-Ergebnisse werden in formatierte Kontext-Strings umgewandelt.
- Ollama Context-Throttling: Kontext wird auf
MAX_OLLAMA_CHARSbegrenzt (Standard: 10.000).
- Synthese:
DecisionEngine._generate_final_answer()kombiniert alle Streams.- Template-basierte Prompt-Konstruktion mit Stream-Variablen.
- 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:
DecisionEnginewird 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
choicesArrays 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:
- Rate-Limit Erkennung: Der Service erkennt HTTP 429 Fehler sowie provider-spezifische Meldungen wie
RESOURCE_EXHAUSTED. - 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). - Cloud-Retry: Nach der Pause erfolgt ein erneuter Versuch (bis zu
LLM_RATE_LIMIT_RETRIESMal). - Ollama Fallback: Erst nach Erschöpfung der Retries schaltet das System auf den lokalen Ollama um, um die Betriebssicherheit zu gewährleisten ("Quoten-Schutz").
- 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.
- Query ID: Generiert bei jedem
/chatCall eineUUIDv4. - Stream-Tracing: Jeder Treffer enthält
stream_originfür Zuordnung zum Quell-Stream. - Logging: Speichert einen Snapshot in
data/logs/query_snapshot.jsonl(Input + Retrieved Context + Intent). - Feedback: Der
/feedbackEndpoint verknüpft das User-Rating (1-5) mit derquery_idundstream_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.