diff --git a/docs/plan-local-llm-router.md b/docs/plan-local-llm-router.md new file mode 100644 index 0000000..487d2b5 --- /dev/null +++ b/docs/plan-local-llm-router.md @@ -0,0 +1,92 @@ +# Plan B — Lokaler LLM-Router (Gamebox) neben Claude + +**Ziel:** „Gemini-Feeling" für den Alltag, ohne die Claude-Max-Subscription +aufzugeben. Ein schnelles lokales LLM beantwortet die einfachen ~80 % der Turns +in <1 s; nur die schweren 20 % (Tiefe, Code, Tools, Pentest, langer Kontext) +gehen an Claude. Claude bleibt das Tiefen-Hirn. + +## Warum das der einzige realistische Weg zu „live" ist + +Gemessen (10.07.2026): CLI-Round-trip über den Claude-Max-Proxy hat einen +**harten Boden von ~3,5 s** (Subprozess-Start pro Turn). Streaming-API würde das +brechen, kostet aber API-Geld → verliert die Max-Subscription. Ein lokales +LLM für die einfachen Turns umgeht den 3,5-s-Boden komplett und ist **gratis** +(läuft auf vorhandener Gamebox-GPU). Echtes Speech-to-Speech-Duplex (Gemini +Live nativ) ist mit einem Text-Modell als Hirn prinzipiell nicht drin. + +## Modell & Serving (entschieden) + +- **Modell:** Qwen3 8B, GGUF **Q4_K_M** (~6 GB). Bestes Tool-Calling der 7/8B- + Klasse, solides Deutsch, Apache-2.0. Alt.: Mistral Small 3 7B (schneller, + weniger Tool-Calling). +- **Serving:** **llama.cpp `llama-server`** im Docker-Container auf der Gamebox + (kein Ollama nötig — nativer OpenAI-kompatibler `/v1/chat/completions`). +- **VRAM-Budget:** 12-GB-Karte, Whisper-small (~1–2 GB) + F5-TTS (~1–2 GB) → + ~8–9 GB frei → passt. (FLUX ist auf 12 GB eh raus.) + +## Anbindung: über den RVS, wie TTS/STT (kein IP-Pflegen) + +Die Gamebox ist ein anderer Host als das Brain. Statt direktem HTTP (IP/Port/ +Firewall) läuft das LLM **über den RVS-Token-Room**, exakt wie Whisper/F5-TTS: + +- llama.cpp hört nur auf localhost der Gamebox. +- Ein **dünner RVS-Adapter** daneben (Vorbild: whisper-/xtts-Bridge) verbindet + sich mit dem RVS-Token, lauscht auf `llm_request`, ruft lokal llama-server, + schickt `llm_response` (korreliert per requestId) zurück. +- `rvs/server.js` `ALLOWED_TYPES` um `llm_request`, `llm_response` und (Phase 2) + `llm_partial` erweitern. +- Das Brain bekommt einen zweiten „Proxy" — nur über RVS statt direktem HTTP. + +## Router-Logik im Brain + +Reihenfolge pro Turn (früh raus = schnell): + +- **Tier 0 — Fast-Path (existiert):** reine Steuerbefehle (Spotify, Licht) → + Skill direkt, **kein LLM**. <1 s. +- **Tier 1 — Lokal (Qwen3):** einfache Konversation, kurze Fakten, Smalltalk, + Bestätigungen. Ziel <1 s. +- **Tier 2 — Claude:** tief/technisch, Code, Tool-Use nötig, Pentest-Projekt, + langer/komplexer Kontext. + +**Routing-Signal (heuristisch zuerst, deterministisch & schnell):** +Nachrichtenlänge, Schlüsselwörter, ob ein Tool nötig scheint, Projekt-Kontext +(Pentest-Projekt → immer Claude), Konversationstiefe. + +**Escalation statt perfekter Vorab-Klassifikation:** Das lokale Modell bekommt +die Anweisung, bei Unsicherheit oder Tool-Bedarf **NICHT zu raten**, sondern zu +eskalieren (z.B. Antwort `<>`). Das Brain routet den Turn dann an +Claude. So sind Fehlklassifikationen billig — lieber einmal lokal→Claude als +eine falsche lokale Antwort. + +## Persona auf BEIDEN Modellen + +Das lokale Modell braucht ARIAs Identität, sonst bricht es aus der Rolle +(gelernt aus dem `--system-prompt`-Debakel). Aber **schlanker**: +- IDENTITY_SEED + Kern-Persona: ja. +- Volles Memory / alle Skill-Schemas / Tool-Block: **nein** (Tier 1 macht keine + Tools). Hält den lokalen Prompt klein → schnell. +- Persona kommt lokal auch als echter System-Prompt (llama.cpp `system`-Rolle). + +## Phasen + +- **B0 — Infra:** llama.cpp-Container + RVS-Adapter auf der Gamebox, + `ALLOWED_TYPES`, `local_llm_chat()` im Brain. Isoliert testen („sag hallo"). +- **B1 — Router:** Heuristik Tier-1/2 + Escalation, schlanke Persona lokal. + Einfache Turns → lokal. Messen: Trefferquote & Latenz. +- **B2 — Streaming/Voice:** `llm_partial` → TTS beginnt beim ersten Satz → + der „live"-Sprung. **Hier den Gong-/Ohr-Re-Arm-Bug mit-fixen** (Barge-In, + sauberes Re-Listen). +- **B3 (optional):** dem lokalen Modell ein paar schnelle, sichere Tools geben. + +## Offene Entscheidungen (für Stefan) + +1. **Modell:** Qwen3 8B (Tool-Calling) — oder doch Mistral Small 3 7B (Speed)? +2. **Routing v1:** rein heuristisch + Escalation (empfohlen) — oder gleich ein + Mini-Classifier? +3. **Tools lokal:** in v1 bewusst KEINE (alles Tool-artige → Claude) — ok? + +## Nicht-Ziele + +- Kein echter Gemini-Live-Duplex-Klon (Text-Modell als Hirn). +- FLUX bleibt optional/später (dickere GPU). Bild-Generierung separat als + pluggbarer Provider (ChatGPT/DALL·E-Alternative) — eigenes Feature, nicht Teil B.