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 ## 4. Profil (Betriebsart) wählen
| Profil | Bedeutung | Key nötig? | Das Gateway kennt drei Betriebsprofile. Jedes Profil legt fest, welche der drei
|-------------|-----------------------------------------|------------| Pipeline-Stufen **STT** (Sprache → Text), **LLM** (Antwort generieren) und **TTS**
| `local-dev` | alles lokal (eigene KI) | nein | (Text → Sprache) lokal oder in der Cloud laufen.
| `hybrid` | STT/TTS Cloud, Haupt-LLM lokal | ja |
| `cloud` | alles über OpenRouter (Standard) | ja |
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 ## 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 # 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) ## A1. Sprech-Loop: sprechen → hören → erneut sprechen (empfohlen)
Der mitgelieferte Helfer nimmt vom Mikrofon auf, schickt die Aufnahme an das Gateway 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 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 > `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`. > 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 ## API-Überblick
| Methode & Pfad | Zweck | | Methode & Pfad | Zweck |