The three bundled episode profiles (business_analysis, solo_expert, tech_discussion) shipped with language=null, which podcast_creator treats as "unspecified" and defaults to English for outline/transcript generation regardless of source language. Set language="de" on all three. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
12 KiB
Bedienungsanleitung — Open Notebook (lokales Deployment)
Diese Anleitung deckt die tägliche Benutzung ab. Installation/Neuaufbau:
siehe README.md. Technische Hintergründe und Architektur:
siehe CLAUDE.md.
Inhalt
- Zugriff
- Notebooks und Quellen
- Chat: die drei Kontext-Modi
- Podcasts erzeugen
- Stimmklonung
- Modelle und Provider verwalten
- Dienste starten/stoppen
- Troubleshooting
1. Zugriff
- Web-Oberfläche:
http://localhost:8502 - REST-API (für Automatisierung/Skripte):
http://localhost:5055, Doku unterhttp://localhost:5055/docs
Beide sind nur von diesem Rechner aus erreichbar (127.0.0.1), nicht aus dem Netzwerk.
2. Notebooks und Quellen
Ein Notebook bündelt Quellen, Notizen, Chats und Podcasts zu einem Thema. Neues Notebook über „+ New Notebook" in der UI anlegen.
Quellen hinzufügen
Unterstützt: hochgeladene Dateien (PDF, EPUB, TXT, DOCX, …), URLs, eingefügter Text.
Wie lang darf eine Datei sein? Es gibt kein hartes Limit für Upload/Verarbeitung — auch
sehr große PDFs/EPUBs werden vollständig extrahiert und in Textabschnitte („Chunks")
zerlegt, die für die Suche eingebettet werden. Eine Längenbegrenzung greift nur, wenn eine
Quelle im „Volltext"-Kontextmodus (siehe Abschnitt 3) oder für eine Transformation
verwendet wird — dort geht der komplette Text in einem Stück an das Sprachmodell. Praktischer
Richtwert bei qwen3.5:27b (98.304 Tokens Kontext, siehe Abschnitt 6): grob 180–350
Buchseiten, abhängig von Textdichte. Wichtig: Die Dateigröße in MB sagt nichts über die
Textmenge aus — ein gescanntes PDF mit vielen Bildern kann riesig sein, aber nach der
Texterkennung kaum Inhalt liefern.
Verarbeitungsstatus prüfen
Nach dem Hochladen läuft die Verarbeitung (Extraktion → Chunking → Embedding) im Hintergrund.
Bei großen Dateien kann das ein bis mehrere Minuten dauern. Status ist in der UI an der Quelle
sichtbar; per API: GET /api/sources/{source_id}/status.
3. Chat: die drei Kontext-Modi
Beim Chatten mit einem Notebook lässt sich pro Quelle einstellen, wie viel davon in den Chat-Kontext einfließt (Buttons/Auswahl in der UI, z. B. als Sammel-Aktion für alle Quellen):
| UI-Option | Bedeutung | Geschwindigkeit |
|---|---|---|
| Alle aus dem Kontext ausschließen | Quelle wird ignoriert | – |
| Alle aufnehmen (nur Erkenntnisse) | Nutzt die generierten „Insights" (Zusammenfassungen) der Quelle | schnell (Sekunden) |
| Alle aufnehmen (vollständiger Inhalt) | Kompletter Text der Quelle geht an das Sprachmodell | langsam bei langen Dokumenten (bis zu einigen Minuten) |
Wichtig: „nur Erkenntnisse" braucht vorher eine Transformation
Der Modus „nur Erkenntnisse" ist nur dann nützlich, wenn für die Quelle bereits eine Zusammenfassung („Insight") erzeugt wurde. Ohne das liefert er praktisch nichts (nur Titel/ Metadaten). Eine Zusammenfassung erzeugen:
- In der UI: bei der Quelle eine Transformation anwenden, z. B. „Simple Summary" (für die meisten Fälle passend) oder „Dense Summary", „Key Insights", „Table of Contents".
- Per API:
curl -X POST http://127.0.0.1:5055/api/sources/{source_id}/insights \ -H "Content-Type: application/json" \ -d '{"transformation_id": "<id aus GET /api/transformations>"}' - Bei langen Dokumenten (z. B. ein ganzes Buch) dauert das einmalig einige Minuten (die gesamte Quelle wird einmal durchs Sprachmodell geschickt) — danach ist „nur Erkenntnisse" aber dauerhaft schnell nutzbar.
Faustregel
- Normale Fragen, Überblick, grobe Zusammenhänge → „nur Erkenntnisse" (nach einmaliger Zusammenfassung)
- Sehr spezifische Detailfrage (z. B. exaktes Zitat aus einem bestimmten Kapitel), die in der Zusammenfassung fehlen könnte → „vollständiger Inhalt", dafür Geduld bei langen Quellen
- Quelle für die aktuelle Frage irrelevant → ausschließen (spart Zeit bei mehreren Quellen)
Für gezielte Detailsuche über viele/lange Quellen gibt es außerdem eine separate Such-/Ask-Funktion, die per Embedding-Ähnlichkeitssuche automatisch nur die relevanten Textstellen findet, statt ganze Dokumente einzubeziehen — meist die schnellste und treffsicherste Option für Detailfragen in langen Werken.
4. Podcasts erzeugen
Open Notebook kann aus Notebook-Inhalten automatisch einen Podcast (Dialog zwischen ein oder mehreren Sprechern) erzeugen — Text via Sprachmodell, Audio via TTS (hier: lokal, Chatterbox).
- Episode-Profil wählen (bestimmt Sprecherzahl/-rollen, Anzahl Segmente, Textmodell):
solo_expert(1 Sprecher),tech_discussion(2 Sprecher),business_analysis(3 Sprecher). - Notebook/Quelle als Grundlage angeben.
- Generierung starten — läuft asynchron (Outline → Transkript → Sprachsynthese pro Segment). Bei mehreren Sprechern und langen Transkripten realistisch mehrere Minuten, da jedes Dialogsegment einzeln per TTS synthetisiert wird.
- Fertige Episode in der UI abspielbar/herunterladbar.
Alle Episode-/Sprecherprofile sind bereits auf lokale Modelle (qwen3.5:27b für Text,
Chatterbox für Sprache) umgestellt — keine zusätzlichen Kosten.
5. Stimmklonung
Die TTS-Wrapper (services/tts_server.py) unterstützt Stimmklonung: Referenz-WAV rein, Stimme
raus. Aktuell hinterlegte Stimmen: default (eigene Stimme), male_thorsten und
female_kerstin (offen lizenzierte, synthetische Piper-Stimmen — bewusst keine ungefragt
geklonten echten Personen, siehe CLAUDE.md).
Eine weitere Stimme hinzufügen
- Referenz-Aufnahme besorgen: 10–30 Sekunden, eine Person, saubere Aufnahme, WAV-Format. Rechtlich sauber ist entweder eine eigene Aufnahme, eine Aufnahme mit ausdrücklicher Zustimmung der Person, oder eine offen für diesen Zweck lizenzierte Stimme (z. B. weitere Piper-Stimmen).
- Datei nach
services/voices/<name>.wavlegen (z. B.services/voices/elena.wav). - TTS-Server neu starten (Stimmen werden nur beim Start eingelesen):
pkill -f "python tts_server.py" ./scripts/start_services.sh - Prüfen:
curl http://127.0.0.1:8901/healthsollte<name>in dervoices-Liste zeigen. - In einem Sprecherprofil (Podcast) den betreffenden Sprecher auf
voice_id: "<name>"setzen, z. B. per API:curl -X PUT http://127.0.0.1:5055/api/speaker-profiles/{id} \ -H "Content-Type: application/json" -d '{... "speakers": [{"name": "Elena", ..., "voice_id": "elena"}], ...}'
Mit Piper lässt sich auch selbst eine Referenz-Stimme synthetisieren (statt eine echte Aufnahme zu verwenden):
echo "Ein Beispielsatz auf Deutsch." | piper --model <stimme>.onnx --output_file services/voices/<name>.wav
Weitere deutsche Piper-Stimmen: huggingface.co/rhasspy/piper-voices/tree/main/de/de_DE
(Lizenz jeweils im MODEL_CARD prüfen).
6. Modelle und Provider verwalten
Übersicht unter Settings → AI Providers / Models in der UI, oder per API:
curl http://127.0.0.1:5055/api/models | python3 -m json.tool # alle registrierten Modelle
curl http://127.0.0.1:5055/api/models/defaults | python3 -m json.tool # aktuelle Standardmodelle
Standardmodelle ändern
Sieben Rollen lassen sich unabhängig belegen: Chat, Transformation, großer Kontext, Embedding, Tools, Text-to-Speech, Speech-to-Text.
curl -X PUT http://127.0.0.1:5055/api/models/defaults \
-H "Content-Type: application/json" \
-d '{"default_tools_model": "<model_id>"}'
Der Endpunkt aktualisiert nur die tatsächlich mitgeschickten Felder — nicht angegebene Felder bleiben unverändert, es muss also nicht der komplette Satz aller sieben Modelle mitgeschickt werden.
Kostenübersicht der aktuell registrierten Modelle
| Modell | Provider | Kosten |
|---|---|---|
qwen3.5:27b |
Ollama (lokal) | 0 € (Standard für Chat/Tools/großer Kontext) |
nomic-embed-text |
Ollama (lokal) | 0 € (Standard-Embedding) |
qwen3-coder-30b-128k |
Ollama (lokal) | 0 € (optional, für Coding-Aufgaben) |
| Chatterbox TTS / faster-whisper | lokal | 0 € |
anthropic/claude-sonnet-5 |
OpenRouter | ~2$/10$ pro Mio. Tokens (Prompt/Antwort) |
qwen/qwen3-max |
OpenRouter | ~0,78$/3,90$ pro Mio. Tokens — günstigere Cloud-Alternative |
google/gemini-3.5-flash |
OpenRouter | ~1,50$/9$ pro Mio. Tokens — 1M Tokens Kontext |
Weitere OpenRouter-Modelle lassen sich jederzeit über POST /api/models registrieren
(provider: "openrouter") — aktuelle Preise: https://openrouter.ai/api/v1/models.
7. Dienste starten/stoppen
# Open Notebook (Docker)
docker compose up -d
docker compose down
# TTS/STT (lokale Hintergrundprozesse, nicht in Docker)
./scripts/start_services.sh
pkill -f "python tts_server.py"
pkill -f "python stt_server.py"
Ollama selbst läuft als systemd-Dienst und muss normalerweise nicht manuell verwaltet werden:
systemctl status ollama
ollama ps # aktuell geladene Modelle + GPU/CPU-Verteilung
8. Troubleshooting
„Chat gibt keine Antwort" (leere Antwort, kein Fehler)
Meist ein zu kleiner Kontext (num_ctx) am Ollama-Chat-Credential — siehe README, Abschnitt 2.6.
Prüfen:
curl -s http://127.0.0.1:5055/api/credentials | python3 -c "
import json,sys
for c in json.load(sys.stdin):
if c['provider']=='ollama': print(c['name'], c['num_ctx'])"
Sollte 98304 (oder höher, dann ggf. auf GPU-Auslastung achten) zeigen, nicht None/null.
Quelle hängt beim Verarbeiten / Einbetten fest (Endlos-Retry)
Meist Ressourcen-Engpass beim Embedding-Modell (GPU voll, Modell läuft teilweise auf CPU, Timeout). Prüfen:
ollama ps # PROCESSOR-Spalte: sollte "100% GPU" zeigen, nicht "xx%/yy% CPU/GPU"
Falls CPU-Anteil: Embedding-Modell ist zu groß für den freien GPU-Speicher. Standardmäßig ist
hier das kleine nomic-embed-text (274 MB) konfiguriert, das läuft normalerweise problemlos
komplett auf der GPU.
Antwort dauert sehr lange (mehrere Minuten)
Meist normal bei „vollständiger Inhalt"-Modus auf langen Dokumenten (siehe Abschnitt 3) — das Sprachmodell muss den kompletten Text lesen. Für Detailfragen auf lange Sicht besser die Such-/Ask-Funktion oder „nur Erkenntnisse" nach einer Zusammenfassung nutzen.
TTS/STT vom Container aus nicht erreichbar
docker compose exec open_notebook curl -sf http://host.docker.internal:8901/health
Bei Timeout: ufw-Regeln fehlen (siehe README 2.4) oder die Server laufen nicht
(./scripts/start_services.sh).
Podcast-Profil zeigt „Einrichtung erforderlich"
Das Episode- oder Sprecherprofil verweist auf ein Modell ohne konfiguriertes Credential
(z. B. nach einem Reset auf die mitgelieferten OpenAI-Standardprofile). Modell-IDs über
PUT /api/episode-profiles/{id} (outline_llm, transcript_llm) bzw.
PUT /api/speaker-profiles/{id} (voice_model) auf registrierte lokale/OpenRouter-Modelle
umstellen — siehe scripts/setup_models.sh für die IDs der Standardmodelle.
Podcast wird auf Englisch statt Deutsch erzeugt
Das verwendete Episode-Profil hat kein language-Feld gesetzt — ohne Angabe generiert das
Sprachmodell standardmäßig auf Englisch, unabhängig von der Sprache der Quelle. Prüfen und
korrigieren:
curl -s http://127.0.0.1:5055/api/episode-profiles | python3 -c \
"import json,sys; [print(p['name'], p['language']) for p in json.load(sys.stdin)]"
Fehlt de, per PUT /api/episode-profiles/{id} (vollständiger Body nötig, siehe oben)
"language": "de" ergänzen. Die drei mitgelieferten Profile (business_analysis,
solo_expert, tech_discussion) sind bereits korrigiert; bei neu angelegten eigenen Profilen
selbst daran denken.
Weitere technische Details
Siehe CLAUDE.md — dort stehen alle bisher aufgetretenen Probleme mit exakter
Ursache (Codestellen, Bibliotheks-Bugs) dokumentiert.