# Voice-Agent Self-hosted Transkriptions- und Protokollsystem für Sprachaufzeichnungen — vollständig lokal, DSGVO-konform. > Vollständiges Lastenheft: siehe [`need.md`](need.md) ## Architektur ``` Benutzer (Browser / Handy-PWA) │ ▼ HTTPS (selbst-signiert, Mikrofon-fähig) ┌──────────────────────────────┐ ┌──────────────────────────────┐ │ LXC-Container (Linux) │ HTTP │ Mac (Apple Silicon) │ │ - FastAPI + HTML/JS UI │ ──────► │ - FastAPI Worker │ │ - SQLite Job-Store + Auth │ │ - lightning-whisper-mlx │ │ - Profile (YAML, ≥17) │ │ - Ollama (Standard 8B) │ │ - Result-/Upload-Verz. │ ◄────── │ - python-docx + reportlab │ │ - Nginx HTTPS-Reverse-Proxy │ │ - Per-Job Log-Ringbuffer │ └──────────────────────────────┘ └──────────────────────────────┘ ``` - **LXC**: keine AI-Verarbeitung — nur Uploads, Job-Tracking, Login, Auslieferung. - **Mac**: Stateless API. Erhält Audio/Text, gibt Transkripte / Zusammenfassungen / Protokolle / DOCX / PDF zurück. ## Funktionsumfang (aktueller Stand) - [x] Audio-Upload (MP3, WAV, M4A, MP4, OGG, FLAC, WEBM — max. 500 MB) - [x] Mobile-First-Layout + PWA mit Mikrofon-Aufnahme (Start / Pause / Stop) - [x] Whisper-Transkription auf dem Mac (MLX, Apple Neural Engine) - [x] Ollama-Zusammenfassung - [x] Strukturiertes Protokoll je Profil - [x] **17 Verarbeitungs-Profile** (Sitzung, Diktat, Pflegedoku, IT-Ticket, Sales-Call, …) - [x] **DOCX- und PDF-Export** - [x] **Benutzer-Verwaltung** (bcrypt, Cookie-Sessions, Per-User-Job-Isolation, Admin-Rolle) - [x] **HTTPS via selbst-signiertem Zertifikat** (Mikrofon-Zugriff am Handy) - [x] **Idempotente Pipeline + Retry** — bei „Server disconnected" automatischer 1× Retry, Transkript wird beim manuellen Erneut-Versuchen weiterverwendet - [x] **Diagnose-Panel pro Job** — Live-Heartbeat während laufender Mac-Calls + Mac-Worker-Log direkt in der UI - [ ] Speaker-Diarization (Prio 2 — siehe `mac-worker/README.md`) --- ## Installation — Schritt für Schritt Voraussetzungen: - **Mac** (Apple Silicon empfohlen, M1/M2/M3/M4) mit min. 16 GB RAM, besser 32 GB. - **Proxmox-Host** (oder beliebiger Linux-Host) für den LXC-Container. - **Netzwerk**: Mac und LXC im selben LAN, der LXC muss den Mac auf Port 8080 erreichen. ### Schritt 1 — LXC-Container provisionieren (Proxmox) Container mit: - Debian 13 (Trixie) oder Ubuntu 24.04 - 2 vCPU, 2 GB RAM, 20 GB Disk reichen - Statische LAN-IP, SSH-Zugang als root ### Schritt 2 — App im LXC installieren Im Container als `root` einloggen, dann **eine** der folgenden Optionen wählen: **Option A — Auto-Install per Curl** (Repo wird selbst geklont): ```bash bash <(curl -sSL https://git.cynfo.net/christian/voice-agent/raw/branch/main/deploy/install.sh) ``` **Option B — Manuell aus geklontem Repo:** ```bash git clone https://git.cynfo.net/christian/voice-agent.git /var/www/voice-agent cd /var/www/voice-agent ./deploy/install.sh ``` Das Skript installiert idempotent: 1. apt-Pakete (`git python3-venv nginx ffmpeg openssl …`) 2. Deploy-User `deploy`, klont/aktualisiert Repo nach `/var/www/voice-agent` 3. Python-venv + Dependencies in `lxc-frontend/.venv` 4. `.env` aus Vorlage anlegen, `SESSION_SECRET` automatisch erzeugen 5. Verzeichnisse `/var/lib/voice-agent/{uploads,results}` + SQLite-DB 6. systemd-Service `voice-agent.service` (autostart, restart-on-failure) 7. Selbst-signiertes TLS-Zertifikat mit SAN (Hostname + IP) 8. Nginx HTTPS-Reverse-Proxy + HTTP→HTTPS Redirect 9. CLI-Wrapper `/usr/local/bin/voice-agent-admin` Erneutes Ausführen aktualisiert auf den neuesten `main` (idempotent, kein Datenverlust — die SQLite-DB liegt unter `/var/lib/voice-agent/`, nicht im App-Verzeichnis). ### Schritt 3 — Mac-Worker einrichten Auf dem Mac (Details in [`mac-worker/README.md`](mac-worker/README.md)): ```bash # Repo holen git clone https://git.cynfo.net/christian/voice-agent.git ~/voice-agent cd ~/voice-agent/mac-worker # Ollama + Modell (einmalig) brew install ollama launchctl setenv OLLAMA_HOST "0.0.0.0:11434" brew services restart ollama ollama pull llama3.1:8b # Worker als LaunchAgent installieren — macht venv + Dependencies + Autostart in einem Rutsch ./deploy/install-launchagent.sh ``` Test vom LXC aus: ```bash curl http://:8080/health # erwartet: {"status":"ok","whisper_engine":"mlx","ollama_reachable":true,...} ``` ### Schritt 4 — LXC mit Mac verbinden Im LXC `MAC_API_URL` auf die Mac-LAN-IP setzen: ```bash sudo nano /var/www/voice-agent/lxc-frontend/.env # MAC_API_URL=http://192.168.x.y:8080 sudo systemctl restart voice-agent ``` ### Schritt 5 — Erst-Anmeldung + Benutzen Browser auf `https:///` — beim allerersten Aufruf legt die UI den initialen Admin an (Username + Passwort wählen). Bestehende Jobs werden diesem Konto zugeordnet. Audio hochladen oder direkt in der UI aufnehmen → fertig. --- ## Update / Neudeployment **LXC** — einfach nochmal: ```bash sudo /var/www/voice-agent/deploy/install.sh ``` **Mac** — ein Befehl macht git-pull + pip-install + Worker-Restart + Health-Check: ```bash ~/voice-agent/mac-worker/deploy/update.sh ``` (Falls `update.sh` aus irgendeinem Grund nicht läuft, ist `./deploy/install-launchagent.sh restart` der manuelle Fallback.) --- ## Benutzer-Verwaltung / Passwort zurücksetzen Auf dem LXC steht nach dem Deploy `voice-agent-admin` als Befehl bereit: ```bash # Passwort zurücksetzen (z. B. Admin-Login vergessen) sudo voice-agent-admin reset admin 'NeuesPasswort123' # User auflisten / anlegen / löschen sudo voice-agent-admin list sudo voice-agent-admin create maria 'StartPasswort123' sudo voice-agent-admin create chefin 'Geheim12345' --admin sudo voice-agent-admin delete maria # Passwort prüfen ohne Browser (Debug) sudo voice-agent-admin verify admin 'NeuesPasswort123' ``` Vollständige Befehlsreferenz: [`lxc-frontend/README.md`](lxc-frontend/README.md#benutzer--und-passwort-verwaltung-per-cli). --- ## Profile Jeder Job läuft mit einem **Verarbeitungs-Profil**, das die Prompts für Summary, Protokoll und das Layout des Exports steuert. Standard ist `meeting`. Das Standard-Profil je User wird im Web-UI im Header gewählt und bleibt gespeichert. Mitgelieferte Profile (alle in `mac-worker/profiles/*.yaml`): | Profil | Zweck | |---|---| | `meeting` | Klassisches Sitzungsprotokoll | | `phone-call` | Telefonat-Notiz mit Beteiligten/Verabredungen | | `memo` | Kurze Sprachnotiz / Diktat | | `interview` | Interview mit Sprecherspuren | | `one-on-one` | 1:1-Gespräch (Mitarbeiter / Kunde) | | `brainstorm` | Ideen-Sammlung mit Cluster-Vorschlägen | | `service-ticket` | IT-Service-Ticket aus Anruf-Mitschnitt | | `incident-report` | Incident-Doku (was, wann, Auswirkung, Status) | | `postmortem` | Post-Mortem mit Lessons-Learned | | `site-survey` | Vor-Ort-Aufnahme (Leitungsverlauf, Hardware, Zustand) | | `sales-call` | Sales-Gespräch mit Pain-Points / Next-Steps | | `schichtuebergabe` | Schichtübergabe Pflege | | `pflegedoku` | Pflegedokumentations-Eintrag | | `sturzbericht` | Sturzbericht (Pflege) | | `visite` | Arzt-Visite | | `angehoerigengespraech` | Angehörigen-Gespräch (Pflege) | | `biografie` | Biografie-Eintrag (Pflege) | Eigene Profile: einfach eine weitere YAML-Datei in `mac-worker/profiles/` ablegen (Beispiel siehe `meeting.yaml`) und Mac-Worker neu starten. --- ## Diagnose / Troubleshooting Wenn ein Job hängt oder fehlschlägt: - **In der UI**: bei FAILED-Jobs und langlaufenden Stages erscheint **„Diagnose ▾"**. Aufklappen zeigt: - aktuelle Stage und wie lange sie schon läuft - letzter Heartbeat (alle 3 s während Mac-Calls) - die letzten 200 Mac-Worker-Log-Zeilen für genau diesen Job - **Auf dem LXC**: - `systemctl status voice-agent` / `journalctl -u voice-agent -f` - `curl -sk https://localhost/api/mac/health` - **Auf dem Mac**: - `~/voice-agent/mac-worker/deploy/install-launchagent.sh status` - `tail -f ~/Library/Logs/voice-agent-worker.{out,err}.log` Wenn der Mac mitten in `summarize` die Verbindung abreissen lässt, retried der LXC einmal automatisch (3 s Backoff) — ein vorgelagerter Preload-Aufruf hat zudem das Ollama-Modell schon ins RAM geladen, damit es nicht in der eigentlichen Generierung neu lädt. --- ## Modelle ### Transkription (Mac, Whisper) | `WHISPER_ENGINE` | `WHISPER_MODEL` | Wann nutzen | |---|---|---| | `mlx` | `large-v3` (Default) | Maximale Qualität, langsamer (~0.3× Realzeit auf M2) | | `mlx` | `distil-large-v3` | ~5× schneller, minimal schlechtere Qualität | | `mlx` | `medium` | Schneller, deutlich schlechter bei Fachbegriffen | | `faster` | `large-v3` | Intel-Mac / Linux / CUDA | | `mock` | – | Tests ohne Modell-Download | Standard ist `mlx` + `large-v3`. Für lange Sitzungen lohnt sich `distil-large-v3`. Alternativen (whisper.cpp + CoreML, WhisperX mit Diarization, Voxtral) sind in [`mac-worker/README.md`](mac-worker/README.md#alternative-transkriptions-engines) dokumentiert. ### Zusammenfassung (Ollama) Standard: `llama3.1:8b` — solide Basisqualität bei deutschen Texten, ~8 GB Speicher. Empfohlene Alternativen je nach Hardware (alle via `ollama pull ` und `OLLAMA_MODEL=` in `.env`): | Modell | Größe | RAM-Bedarf | Stärken | |---|---|---|---| | `llama3.1:8b` (Default) | 8 B | ~8 GB | Schnell, brauchbares Deutsch | | `qwen2.5:14b` | 14 B | ~10 GB | Sehr zuverlässige JSON-Ausgabe, exzellentes Deutsch | | `mistral-small:24b` | 24 B | ~16 GB | Europäisch trainiert, beste Kompromiss-Wahl | | `gemma3:12b` | 12 B | ~10 GB | Stark multilingual, gute Strukturierung | | `gpt-oss:20b` | 20 B | ~14 GB | Sehr gute strukturierte Ausgabe (OpenAI Open-Weight) | | `llama3.3:70b` | 70 B | ~48 GB | Top-Qualität, nur auf Macs mit 64 GB+ | Für deutsche Protokolle mit viel JSON-Struktur ist **`qwen2.5:14b`** oder **`mistral-small:24b`** der beste Sweet-Spot auf einem Mac mit 32 GB. Detaillierte Bewertung siehe [`mac-worker/README.md`](mac-worker/README.md#ollama-modell-wählen). --- ## Verzeichnisstruktur ``` voice-agent/ ├── lxc-frontend/ # FastAPI Web-App (läuft im LXC) │ ├── app/ │ ├── requirements.txt │ └── .env.example ├── mac-worker/ # FastAPI AI-Worker (läuft auf dem Mac) │ ├── app/ │ ├── profiles/ # YAML-Profile (Prompts + Layout) │ ├── deploy/ # install-launchagent.sh, update.sh, plist-Template │ ├── requirements.txt │ └── .env.example ├── deploy/ # systemd / nginx / install.sh (LXC) ├── config/ # Toolkit-Konfiguration (project.env) ├── .claude/ # KI-Agenten Skills ├── need.md # Lastenheft └── README.md ``` ## Sicherheit - Vollständig lokaler Betrieb. Keine Cloud-Calls. - HTTPS mit selbst-signiertem Cert (für Mikrofon-Zugriff am Handy zwingend nötig). - Web-UI ist Cookie-Session-basiert (bcrypt cost 12, signiert mit `SESSION_SECRET`). - Mac-Worker hat **keine** Auth — Betrieb nur im internen Netz. - Uploads / Ergebnisse unter `/var/lib/voice-agent/` — bei Bedarf Backup einplanen. - `.env`-Dateien (LXC + Mac) sind chmod 600, enthalten Session-Secret + ggf. Tokens.