docs: Betriebsprofile, Ollama, Web-UI und Startup-Hinweise dokumentieren

- README: Ollama als LLM-Backend (Alternative zu llama.cpp) mit .env-Snippet
- README: Warnung dass Gateway ohne LLM-Server startet, Fehler erst beim ersten Request
- BEDIENUNGSANLEITUNG: Abschnitt 4 zu vollstaendiger Profilbeschreibung ausgebaut
  (cloud / hybrid / local-dev je mit Hardware, Software, Kosten, Latenz, Qualitaet,
  Einrichtungsbefehlen und Vergleichstabelle)
- BEDIENUNGSANLEITUNG: neues Kapitel A0 Web-Interface (Oberflaeche, Ablaeufe,
  Fehlertabelle)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Dieter Schlüter 2026-06-18 16:30:46 +02:00
commit 5e6d708038
2 changed files with 261 additions and 6 deletions

View file

@ -60,13 +60,164 @@ echo ${OPENROUTER_API_KEY:0:8} # zeigt nur den Anfang zur Kontrolle
## 4. Profil (Betriebsart) wählen
| Profil | Bedeutung | Key nötig? |
|-------------|-----------------------------------------|------------|
| `local-dev` | alles lokal (eigene KI) | nein |
| `hybrid` | STT/TTS Cloud, Haupt-LLM lokal | ja |
| `cloud` | alles über OpenRouter (Standard) | ja |
Das Gateway kennt drei Betriebsprofile. Jedes Profil legt fest, welche der drei
Pipeline-Stufen **STT** (Sprache → Text), **LLM** (Antwort generieren) und **TTS**
(Text → Sprache) lokal oder in der Cloud laufen.
Dauerhaft in `.env`: `VA_PROFILE=cloud` — oder einmalig: `VA_PROFILE=cloud make run`.
Umschalten — dauerhaft in `.env`:
```bash
VA_PROFILE=cloud # Standard
VA_PROFILE=hybrid
VA_PROFILE=local-dev
```
Oder einmalig für einen Start: `VA_PROFILE=cloud make run`.
---
### Profil `cloud` — alles über OpenRouter (Empfehlung für den Einstieg)
| Stufe | Läuft auf | Standard-Modell |
|-------|-----------|-----------------|
| STT | OpenRouter (remote) | `openai/whisper-large-v3` |
| LLM | OpenRouter (remote) | `openai/gpt-4.1-mini` |
| TTS | OpenRouter (remote) | `openai/gpt-4o-mini-tts` |
**Was muss laufen?** Nur das Gateway (`make run`). Sonst nichts.
**Hardware:** Beliebiger Rechner mit Internetzugang — keine GPU nötig.
**Software:** Nur das Gateway (`pip install -e .[test]`).
**API-Key:** `OPENROUTER_API_KEY` erforderlich.
**Kosten:** ca. 12 ¢ pro Sprech-Runde (STT + TTS sind die Kostentreiber; LLM ist
nahezu kostenlos). Grob ~2040 ¢ pro 10-Minuten-Gespräch. Genaue Zahlen:
OpenRouter-Dashboard → Activity/Usage.
**Antwortgeschwindigkeit:** ~4 s Round-Trip (STT ~1,2 s + LLM ~0,7 s + TTS ~1,9 s,
gemessen gegen OpenRouter). Streaming (`audio_stream=true`) lässt die erste Silbe
früher kommen — subjektiv schneller.
**Beste Modell-Kombination (bewährt, inkl. Plattdeutsch):**
```bash
OPENROUTER_STT_MODEL=openai/whisper-large-v3
OPENROUTER_LLM_MODEL=google/gemini-3.1-flash-lite
OPENROUTER_TTS_MODEL=google/gemini-3.1-flash-tts-preview
OPENROUTER_TTS_VOICE=Zephyr
```
---
### Profil `hybrid` — STT/TTS Cloud, LLM lokal
| Stufe | Läuft auf | Provider |
|-------|-----------|----------|
| STT | OpenRouter (remote) | `openrouter` |
| LLM | eigener Rechner | `local-openai-compatible` (llama.cpp oder Ollama) |
| TTS | OpenRouter (remote) | `openrouter` |
**Was muss laufen?** Gateway + lokaler LLM-Server.
**Hardware:** NVIDIA-GPU empfohlen (für llama.cpp-Modelle mit >7B Parametern praktisch
Pflicht); für Ollama mit kleinen Modellen auch ohne GPU möglich (langsamer).
**Software:**
- llama.cpp: `make llm-up` (Docker, GPU) — erst warten bis `make llm-status` „HTTP OK" zeigt
- Ollama: `ollama serve` + `ollama pull <modell>` (kein Docker nötig)
**API-Key:** `OPENROUTER_API_KEY` erforderlich (für STT + TTS).
**Kosten:** ~0,51,5 ¢/Runde (nur TTS remote — STT ist zwar auch remote, aber billig).
Ersparnis gegenüber `cloud` nur ~1015 %; der echte Vorteil ist **Datenschutz**
(Spracheingabe + KI-Verarbeitung verlassen den Rechner nicht).
**Antwortgeschwindigkeit:** STT und TTS wie `cloud`. LLM-Latenz hängt vom lokalen Modell
und GPU ab — mit `LOCAL_LLM_DISABLE_REASONING=true` und einem Sprach-System-Prompt sind
~0,7 s (Qwen3-35B auf RTX 3090) erreichbar.
**Einrichten (llama.cpp):**
```bash
make llm-up # Docker-Container starten (GPU 1, Port 8001)
make llm-status # warten bis "HTTP OK"
VA_PROFILE=hybrid make run
```
**Einrichten (Ollama):**
```bash
# in .env:
LOCAL_LLM_BASE_URL=http://127.0.0.1:11434/v1
LOCAL_LLM_API_KEY=ollama
LOCAL_LLM_MODEL=qwen3:30b-a3b # oder anderes Modell aus 'ollama list'
VA_PROFILE=hybrid make run
```
---
### Profil `local-dev` — alles lokal (kein API-Key, maximaler Datenschutz)
| Stufe | Läuft auf | Provider |
|-------|-----------|----------|
| STT | eigener Rechner | `faster-whisper` |
| LLM | eigener Rechner | `local-openai-compatible` (llama.cpp oder Ollama) |
| TTS | eigener Rechner | `piper` |
**Was muss laufen?** Gateway + lokaler LLM-Server. STT und TTS laufen im Gateway-Prozess.
**Hardware:**
- NVIDIA-GPU für llama.cpp (35B-Modell braucht ~20 GB VRAM)
- Für Ollama mit kleinen Modellen (7B) geht auch CPU, aber langsam
- Kein Internetzugang nötig (vollständig offline betreibbar)
**Software:**
```bash
pip install -e .[local] # faster-whisper + piper-tts installieren
# Piper-Stimmmodell bereitstellen (einmalig):
# .onnx + .onnx.json nach ~/.local/share/piper/voices/ kopieren
# llama.cpp:
make llm-up && make llm-status # warten auf "HTTP OK"
# oder Ollama:
ollama serve && ollama pull qwen3:30b-a3b
```
**API-Key:** keiner nötig.
**Kosten:** keine API-Kosten — nur Strom (GPU-Betrieb).
**Antwortgeschwindigkeit:** STT (`faster-whisper base` auf CPU) ~13 s; LLM wie bei
`hybrid`; TTS (`piper`, in-process) ~0,30,5 s für einen Satz. Gesamtlatenz
vergleichbar mit `cloud`, aber abhängig von der GPU-Auslastung. Erster Turn nach
Server-Start ist wärmer als früher (Modelle werden beim Start vorgeladen).
**Sprach­qualität:** piper klingt synthetischer als Cloud-TTS (Gemini/Zephyr).
Whisper `base` ist schnell, aber schwächer bei Dialekt als `large-v3`. Für
bessere Qualität: `FASTER_WHISPER_MODEL=large-v3` + `FASTER_WHISPER_DEVICE=cuda`.
**Einrichten:**
```bash
make llm-up # erst warten bis make llm-status "HTTP OK" zeigt
VA_PROFILE=local-dev make run
```
> **Achtung:** Das Gateway startet auch ohne laufenden LLM-Server fehlerfrei hoch.
> Der Fehler „All connection attempts failed" erscheint erst beim ersten Request.
> Deshalb immer erst `make llm-up` vollständig abwarten.
---
### Vergleich auf einen Blick
| | `cloud` | `hybrid` | `local-dev` |
|---|---------|----------|-------------|
| **STT** | remote | remote | lokal |
| **LLM** | remote | **lokal** | **lokal** |
| **TTS** | remote | remote | **lokal** |
| **API-Key nötig** | ja | ja | nein |
| **GPU nötig** | nein | empfohlen | empfohlen |
| **Internetverbindung** | ja | ja | nein |
| **Kosten/Runde** | ~12 ¢ | ~0,51,5 ¢ | ~0 (nur Strom) |
| **Round-Trip** | ~4 s | ~35 s | ~36 s |
| **Sprachqualität TTS** | hoch | hoch | mittel (piper) |
| **Datenschutz** | gering | hoch | maximal |
| **Empfohlen für** | Einstieg, Senioren | Datenschutz + gutes TTS | Offline, kein API-Key |
## 5. Starten und Stoppen
@ -92,6 +243,73 @@ Port ändern: `PORT=8005 make run` (einmalig) bzw. `PORT=` in `.env` (dauerhaft)
# Teil A — Mit dem Assistenten sprechen
## A0. Web-Interface im Browser (einfachster Einstieg)
Das Gateway liefert unter `/` eine fertige Web-Oberfläche aus — kein zusätzliches
Programm nötig, nur ein Browser.
### Aufrufen
```
http://localhost:8003/ ← am Server selbst (Mikrofon funktioniert)
http://<server-lan-ip>:8003/ ← aus dem LAN (nur Text-Chat; Mikrofon braucht HTTPS)
```
> Mikrofon im Browser geht nur über `localhost` oder HTTPS. Für Sprache von einem
> anderen Gerät im Heimnetz: HTTPS-Zugang einrichten (siehe README → „Remote von
> unterwegs").
### Oberfläche auf einen Blick
```
┌─────────────────────────────────────────────────────┐
│ Voice Assistant [☀️/🌙] Angemeldet als … │
├─────────────────────────────────────────────────────┤
│ │
│ (Nachrichtenverlauf) │
│ │
├───────────────────────────────────┬─────────────────┤
│ Texteingabe … [Senden] │ [🎤] [Stimme ▾] │
└───────────────────────────────────┴─────────────────┘
```
| Element | Bedeutung |
|---------|-----------|
| **Texteingabe + Senden** | Nachricht tippen, Enter oder „Senden" drücken |
| **🎤 Mikrofon-Button** | einmal tippen → Aufnahme startet (Button wird rot); erneut tippen → Aufnahme stoppt, Sprache wird verarbeitet |
| **Stimme ▾** | TTS-Anbieter wählen: leer = Server-Default (piper), `chatterbox` = neuronale Stimme, `openrouter` = Cloud-TTS |
| **☀️ / 🌙** | Tag-/Nacht-Modus umschalten (folgt sonst automatisch dem System) |
| **Angemeldet als …** | SSO-Identität; „Gast" wenn AUTH deaktiviert oder kein SSO-Cookie vorhanden |
### Typischer Ablauf (Text)
1. Seite aufrufen → Statuszeile ist leer, Eingabefeld aktiv.
2. Text eintippen (z. B. „Wie wird das Wetter morgen?") → **Enter** oder **Senden**.
3. Eigene Nachricht erscheint als blaue Blase rechts; Assistent antwortet (grau links),
Antwort wird gleichzeitig **vorgelesen**.
4. Nächste Frage eintippen — der Gesprächsverlauf bleibt erhalten (solange die
Seite offen ist).
### Typischer Ablauf (Sprache)
1. **🎤** antippen → Button wird rot, Statuszeile zeigt „Aufnahme …".
2. Sprechen.
3. **🎤** erneut antippen → Aufnahme stoppt; Statuszeile wechselt zu
„verarbeite Sprache …" → „denkt …".
4. Transkription erscheint als blaue Blase, Antwort als graue Blase — und wird
vorgelesen.
### Fehlermeldungen im Chat verstehen
| Meldung | Ursache | Abhilfe |
|---------|---------|---------|
| „Verbindungsfehler" | WebSocket-Verbindung konnte nicht aufgebaut werden | Seite neu laden; Gateway-Prozess prüfen (`make run`) |
| „Fehler: All connection attempts failed" | Konfigurierter LLM-/STT-/TTS-Dienst nicht erreichbar | Abhängigen Dienst starten (z. B. `make llm-up`) |
| „Mikrofon-Zugriff fehlgeschlagen" | Browser hat Mikrofon nicht freigegeben | Browser-Einstellungen → Mikrofon erlauben; oder HTTPS nutzen |
| „Aufnahme nicht unterstützt" | Sehr alter Browser / iOS < 14.3 | Browser / iOS aktualisieren |
---
## A1. Sprech-Loop: sprechen → hören → erneut sprechen (empfohlen)
Der mitgelieferte Helfer nimmt vom Mikrofon auf, schickt die Aufnahme an das Gateway

View file

@ -183,9 +183,46 @@ make llm-up # 35B-Modell laden; mit make llm-status auf "HTTP OK" warte
make run # Gateway nutzt jetzt das lokale, unzensierte Modell als zentrale KI
```
> **Wichtig:** Gateway und LLM-Server starten **unabhängig** voneinander — `make run`
> läuft auch ohne laufenden LLM-Container hoch, ohne Fehlermeldung. Der Fehler
> „All connection attempts failed" erscheint erst beim **ersten Request**. Daher immer
> zuerst `make llm-up` vollständig abwarten (Status „HTTP OK"), dann `make run`.
> `VA_PROFILE` ist in `.env` dauerhaft setzbar (aktuell `local-dev`) oder pro Lauf
> voranstellbar (`VA_PROFILE=hybrid make run`). Prüfen: `curl http://localhost:8080/api/config`.
## Ollama als LLM-Backend (Alternative)
Wer statt des llama.cpp-Docker-Containers lieber **Ollama** nutzt, braucht keinen
eigenen Start-Skript: Ollama verwaltet den Server-Prozess selbst und bietet eine
**OpenAI-kompatible API** — der Provider `local-openai-compatible` verbindet sich
direkt damit.
**Voraussetzung:** Ollama ist installiert (`ollama --version`) und das gewünschte
Modell bereits heruntergeladen (`ollama pull qwen3:30b-a3b`).
Drei Zeilen in `.env` anpassen (der Rest bleibt unverändert):
```bash
LOCAL_LLM_BASE_URL=http://127.0.0.1:11434/v1
LOCAL_LLM_API_KEY=ollama # Ollama erwartet einen beliebigen Wert
LOCAL_LLM_MODEL=qwen3:30b-a3b # exakter Name aus 'ollama list'
```
Danach Gateway starten — kein `make llm-up` nötig, Ollama läuft im Hintergrund:
```bash
VA_PROFILE=local-dev make run # oder hybrid, wenn STT/TTS Cloud bleiben sollen
```
**Hinweise:**
- `LOCAL_LLM_DISABLE_REASONING=true` (Standard) schickt `chat_template_kwargs:
{enable_thinking: false}` — Ollama ignoriert dieses Feld; die Denkphase muss
im Modell-Alias selbst abgeschaltet werden (`qwen3:30b-a3b` statt
`qwen3:30b-a3b:thinking`) oder über den System-Prompt.
- `ollama list` zeigt alle lokal vorhandenen Modelle mit exaktem Namen.
- Verfügbare Modelle: `https://ollama.com/library` (Suche nach `qwen3`, `llama`, …).
## API-Überblick
| Methode & Pfad | Zweck |