my_voice_assistant_v3_jamulix/BEDIENUNGSANLEITUNG.md
Dieter Schlüter 531b57e08d feat: Langzeit-Erinnerungen (#3b) und WebSocket-Streaming-Chat (#4, erster Increment)
#3b Langzeit-Erinnerungen:
- Store: memories-Tabelle + add/get/delete_memory (pro Nutzer)
- API: GET/POST/DELETE /api/me/memories
- chat.py injiziert Nutzer-Erinnerungen als System-Kontext ins LLM (sessionunabhaengig)
- ?debug zeigt memories_len

#4 Echtzeit (erster Increment):
- WS /ws/chat: dauerhafter Kanal, Event-Folge ack -> semantic -> audio (binaer) -> done
- Auth (Token-Query), Session-Gedaechtnis und Erinnerungen wie bei POST /api/chat
- Fehler als error-Event (422/403/502)

- Tests: 38 gruen (Erinnerungs-CRUD/Injektion, WebSocket-Streaming/Auth)
- Doku aktualisiert (README, BEDIENUNGSANLEITUNG, Architektur)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 04:26:55 +02:00

9.4 KiB

Bedienungsanleitung — Voice Assistant Gateway

Diese Anleitung führt Schritt für Schritt durch Installation, Start, Konfiguration und Fehlerbehebung. Technische Hintergründe stehen im Architektur-Dokument, eine kompakte Übersicht im README.


1. Voraussetzungen

  • Python 3.11 oder neuer (python3 --version)
  • Ein OpenRouter-API-Key — nur nötig, wenn ein Profil entfernte KI nutzt (hybrid, cloud). Für rein lokalen Betrieb (local-dev) nicht erforderlich.
  • Optional: Docker, falls im Container betrieben.

2. Installation

cd voice-assistant-scaffold
python3 -m venv .venv
source .venv/bin/activate
pip install -U pip
pip install -e .[test]

Danach die zentrale Konfigurationsdatei anlegen:

cp config/voice-assistant.example.toml config/voice-assistant.toml

3. API-Key hinterlegen (für Cloud/Hybrid)

Der Schlüssel wird aus der Umgebung gelesen und gehört nicht in eine Datei. Dauerhaft am besten in ~/.bashrc:

echo 'export OPENROUTER_API_KEY=sk-or-v1-DEIN_KEY' >> ~/.bashrc
chmod 600 ~/.bashrc
source ~/.bashrc

Prüfen, ob er ankommt:

echo ${OPENROUTER_API_KEY:0:8}    # zeigt nur den Anfang

Sicherheit: Den Key niemals in .env oder config/*.toml schreiben. Wird ein Key versehentlich öffentlich, im OpenRouter-Dashboard löschen (= widerrufen) und neu erzeugen.


4. Betriebsart (Profil) wählen

Profile bestimmen, welche KI-Module genutzt werden:

Profil Bedeutung Key nötig?
local-dev alles lokal (eigene KI/Hardware) nein
hybrid STT/TTS über Cloud, Haupt-LLM lokal ja
cloud alles über OpenRouter (Standardbetrieb) ja

Profil einmalig für einen Start:

VA_PROFILE=cloud make run

Profil dauerhaft — in .env eintragen:

VA_PROFILE=cloud

Hinweis: Stehen in .env noch DEFAULT_STT_PROVIDER / DEFAULT_LLM_PROVIDER / DEFAULT_TTS_PROVIDER, überschreiben diese das Profil. Für profilbasiertes Umschalten sollten sie auskommentiert sein.


5. Starten und Stoppen

make run

Standard-Adresse: http://localhost:8080 (Port änderbar, siehe Abschnitt 8). Beenden mit Strg + C.

Schnelltest in einem zweiten Terminal:

curl http://localhost:8080/health
# {"status":"ok"}

curl http://localhost:8080/api/config
# zeigt aktives Profil und die aufgelöste Standard-Route

6. Tägliche Bedienung — typische Aufgaben

a) Text sprechen lassen (/api/speak)

curl -X POST http://localhost:8080/api/speak \
  -H 'Content-Type: application/json' \
  -d '{"text":"Guten Morgen, wie geht es Ihnen?"}' \
  --output antwort.pcm

b) Chatten (Text rein, gesprochene Antwort raus) (/api/chat)

Nur den Trace als JSON ansehen (ohne Audio):

curl -X POST "http://localhost:8080/api/chat?debug=true" \
  -H 'Content-Type: application/json' \
  -d '{"text":"Wie wird das Wetter morgen?"}'

Komfortabler mit dem mitgelieferten Client (spielt die Antwort ab):

python chat_client.py "Erzähl mir einen guten Morgen-Spruch"

chat_client.py erwartet den Dienst auf Port 8003 — bei Bedarf im Skript GATEWAY_URL anpassen oder den Dienst mit PORT=8003 make run starten.

Fortlaufendes Gespräch (Gedächtnis): Wird eine session_id mitgegeben, merkt sich der Assistent den Verlauf und bezieht ihn in die nächste Antwort ein:

curl -X POST "http://localhost:8080/api/chat?session_id=oma-anna&debug=true" \
  -H 'Content-Type: application/json' -d '{"text":"Ich heiße Anna."}'
curl -X POST "http://localhost:8080/api/chat?session_id=oma-anna&debug=true" \
  -H 'Content-Type: application/json' -d '{"text":"Wie war noch mein Name?"}'

Ohne session_id ist jeder Aufruf eigenständig (kein Gedächtnis). Wie viele zurückliegende Nachrichten einfließen, steuert HISTORY_MAX_MESSAGES (Standard 10).

c) Audio transkribieren (/api/transcribe)

curl -X POST http://localhost:8080/api/transcribe \
  -F "file=@aufnahme.wav" -F "language=de"

d) Gerät oder Provider einmalig umstellen (pro Aufruf)

curl -X POST http://localhost:8080/api/speak \
  -H 'Content-Type: application/json' \
  -d '{"text":"Test","tts_provider":"piper","output_endpoint":"loopback"}'

e) Präferenzen für eine Session festlegen

# einmal setzen
curl -X POST http://localhost:8080/api/sessions/oma-anna/route \
  -H 'Content-Type: application/json' \
  -d '{"llm_provider":"openrouter","language":"de"}'

# danach mit dieser Session nutzen
curl -X POST "http://localhost:8080/api/chat?session_id=oma-anna&debug=true" \
  -H 'Content-Type: application/json' -d '{"text":"Hallo!"}'

7. Verfügbare Geräte und Bausteine ansehen

curl http://localhost:8080/api/devices    # Audio-Endpunkte mit Fähigkeiten
curl http://localhost:8080/api/config     # Profil, Route, Provider, Endpunkte

8. Port ändern

PORT=8003 make run                      # einmalig
sed -i 's/^PORT=.*/PORT=8003/' .env     # dauerhaft

9. Mit Docker betreiben

export OPENROUTER_API_KEY=sk-or-v1-...
docker compose up --build

Der Key wird aus der Shell in den Container durchgereicht; fehlt er, bricht der Start mit klarer Meldung ab.


10. Authentifizierung & Mehrbenutzer

Im Produktivbetrieb ist AUTH_ENABLED=true (Standard). Dann brauchen chat/speak/transcribe/sessions/me ein Bearer-Token pro Nutzer. Nutzer und Sessions werden in einer SQLite-Datei gespeichert (DB_PATH, Standard data/voice-assistant.db).

Schritt 1 — Admin-Schlüssel setzen (nur über die Umgebung):

export ADMIN_API_KEY=ein-langes-geheimnis

Schritt 2 — Nutzer anlegen (Token erscheint nur einmal, sicher notieren):

curl -X POST http://localhost:8080/api/admin/users \
  -H "X-Admin-Key: $ADMIN_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"display_name":"Oma Anna"}'

Schritt 3 — mit Token nutzen:

TOKEN=<das-token-von-oben>
curl http://localhost:8080/api/me -H "Authorization: Bearer $TOKEN"

curl -X POST http://localhost:8080/api/speak \
  -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"text":"Guten Morgen!"}'

Dauerhafte Vorlieben eines Nutzers (Gerät/Provider/Sprache) setzen:

curl -X PUT http://localhost:8080/api/me/prefs \
  -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"language":"de","llm_provider":"openrouter"}'

Diese Vorlieben gelten automatisch für alle Aufrufe dieses Nutzers (Ebene zwischen Profil und Session). Eine fremde Session zu nutzen, wird mit 403 abgelehnt.

Langzeit-Erinnerungen (dauerhafte Fakten/Vorlieben, gelten über alle Gespräche):

# anlegen
curl -X POST http://localhost:8080/api/me/memories \
  -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' -d '{"content":"Mag morgens Kamillentee."}'
# auflisten / löschen
curl http://localhost:8080/api/me/memories -H "Authorization: Bearer $TOKEN"
curl -X DELETE http://localhost:8080/api/me/memories/1 -H "Authorization: Bearer $TOKEN"

Diese Erinnerungen gibt der Assistent bei jedem Chat als Kontext mit — auch ohne session_id.

Echtzeit-Chat über WebSocket (/ws/chat): dauerhafter Kanal, pro Nachricht {"text": "..."}; Antwort kommt als Event-Folge (ack, semantic, Audio, done). Token per Query (?token=…), Gedächtnis per ?session_id=….

Für lokale Entwicklung ist in der mitgelieferten .env AUTH_ENABLED=false gesetzt — dann ist kein Token nötig (anonymer Nutzer).


11. Fehlerbehebung

Symptom Ursache Lösung
OPENROUTER_API_KEY is empty Key nicht in der Umgebung export OPENROUTER_API_KEY=…, neues Terminal / source ~/.bashrc
HTTP 401 „Bearer token required/Invalid token" Auth an, Token fehlt/falsch gültiges Token im Header Authorization: Bearer …, oder AUTH_ENABLED=false für dev
HTTP 401 bei /api/admin/users falscher/fehlender Admin-Key X-Admin-Key mit ADMIN_API_KEY abgleichen
HTTP 403 bei ?session_id=… Session gehört anderem Nutzer eigene session_id verwenden
HTTP 503 bei /api/admin/users ADMIN_API_KEY nicht gesetzt Admin-Key in der Umgebung setzen
HTTP 422 „Unbekannter …-Provider/Endpunkt" Tippfehler in *_provider / *_endpoint gültige Werte via GET /api/config prüfen
VA_PROFILE wirkt nicht DEFAULT_*_PROVIDER in .env überschreibt es diese Zeilen in .env auskommentieren
LLM-Timeout / Connection refused (lokal) lokaler LLM-Server (Port 11434) läuft nicht LLM-Server starten oder Profil cloud wählen
Address already in use Port belegt anderen PORT setzen (Abschnitt 8)
chat_client.py bekommt keine Antwort Client nutzt Port 8003 Dienst mit PORT=8003 starten oder GATEWAY_URL anpassen
Profil greift nicht / Standardwerte config/voice-assistant.toml fehlt Datei aus *.example.toml kopieren (Abschnitt 2)

Logs erscheinen im Terminal, in dem make run läuft. Für mehr Details LOG_LEVEL=debug in .env setzen.


12. Tests ausführen

make test

Alle Tests sollten grün sein. Schlägt etwas fehl, gibt die Ausgabe den genauen Testnamen und die Ursache an.