ElevenLabs Conversational-AI-Agent fuer DE-Voice-Bots
Wiederholbares Pattern fuer „Kunde will einen Voice-Bot, der im Browser laeuft, Reservierungen oder Bestellungen aufnimmt, in deutscher Customer-Care-Stimme spricht — und das in einer Session”. Komplette Pipeline ohne Telefonnummer, ohne Twilio, ohne Backend-Server fuer den Voice-Pfad. Tool-Calls gehen per Webhook raus.
Erste Anwendung: 2026-05-09, Aylem Eat & Meet POC (telefon-assistent-aws) — A/B parallel zum AWS-Polly-Stack.
Wann nutzen
- Kunden-Pitch / Sales-Demo wo „echte natuerliche Stimme” mehr ueberzeugt als „funktioniert technisch”
- POC vor der Telefonnummer-Investition: erst Persona + Stimme + Tools im Browser pruefen, dann Twilio drancanyon
- A/B-Vergleich gegen AWS-Polly-Stack (gleicher System-Prompt, anderer Voice-Stack)
- DACH-Customer-Care-Use-Cases (Restaurant, Praxis, Service-Hotline) — ElevenLabs hat hier deutlich bessere Voice-Qualitaet als Polly Generative
Nicht nutzen wenn:
- Daten muessen EU-only bleiben (ElevenLabs-Datenpfad pruefen, ggf. Polly + Bedrock EU)
- Kunde ist auf Subscription-Vermeidung — ConvAI ist paid feature, Free-Tier nur 10k credits
- Reine FAQ-Chat-Use-Cases ohne Voice — overkill, normaler LLM-Chat reicht
Voraussetzungen
- ElevenLabs-API-Key in
.env.local(Vault-Root) alsELEVENLABS_API_KEY - ElevenLabs-MCP registriert (elevenlabs)
- Browser mit Mikrofon-Zugriff (Chrome / Safari getestet)
Schritte
1. Voice-Auswahl: shared library durchsuchen
Eigene Library hat anfangs nur generierte Voices, fuer DE-Native Customer-Care nimmt man Voices aus dem shared pool. Tool: mcp__elevenlabs__search_voice_library.
Such-Begriffe die gut treffen:
german female warm/german male warm— guter Mix aus Stimm-Charakterdeutsch friendly— engerer DACH-Filter- Ziel:
Use Case: conversational(nichtnarrative_story— das klingt nach Hoerbuch)
Top-Stimmen aus dem Pool (Stand 2026-05):
| Voice | ID | Profil |
|---|---|---|
| Johanna – Warm, Clear & Professional Support | coPfQIqaxowKv5u2s2bV | Explizit fuer DACH customer care, mittlere Lage, Default-Empfehlung |
| Ela – Empathetic & Warm | SJJe86Va82zRzg6zi2dX | Junge Stimme, supportive flow, fuer freundlichere Brands |
| Martin – Warm, Conversational & Friendly | ztKVRvw89zjvli0JDeZR | Maennlich, conversational AI / phone support / IVR |
2. Voice in eigene Library kopieren
Shared-library-voices kann der Account erst nutzen, wenn sie in die eigene Library kopiert sind. Endpoint: POST /v1/voices/add/{public_owner_id}/{voice_id} mit body {"new_name": "..."}.
set -a; source .env.local; set +a
# 1) public_owner_id finden — der voice_id-Filter im /v1/shared-voices greift NICHT,
# daher per ?search=<name>&language=de und lokal nach voice_id filtern
curl -sS "https://api.elevenlabs.io/v1/shared-voices?search=Johanna&language=de" \
-H "xi-api-key: $ELEVENLABS_API_KEY" \
| python3 -c "import sys,json; [print(v.get('voice_id'), v.get('public_owner_id'), v.get('name')) for v in json.load(sys.stdin).get('voices',[])]"
# 2) in eigene Library adden — voice_id bleibt gleich!
curl -sS -X POST "https://api.elevenlabs.io/v1/voices/add/$OWNER/$VOICE_ID" \
-H "xi-api-key: $ELEVENLABS_API_KEY" \
-H "Content-Type: application/json" \
-d '{"new_name":"Aylem-Johanna"}'Wichtig: nach Add bleibt die voice_id identisch. Antwort gibt {"voice_id": "<same>"} zurueck — das ist kein Bug.
3. Conversational-AI-Agent anlegen
Per MCP-Tool mcp__elevenlabs__create_agent:
mcp__elevenlabs__create_agent(
name="Aylem Voice Agent (POC)",
first_message="Hallo, hier ist Aylem Eat & Meet. Was kann ich fuer Sie tun?",
system_prompt="<persona prompt>",
voice_id="coPfQIqaxowKv5u2s2bV",
language="de",
llm="gpt-4o-mini", # Latenz-optimiert; Claude per Custom-LLM ggf. spaeter
temperature=0.4,
max_tokens=200,
model_id="eleven_flash_v2_5", # 32-Sprachen, schnellstes ElevenLabs-Modell
stability=0.45, similarity_boost=0.8,
turn_timeout=7,
max_duration_seconds=300,
record_voice=True,
retention_days=30, # POC: 30 statt 730
)Antwort enthaelt Agent ID: agent_<id> — die merken.
TTS-Defaults die sich bewaehrt haben: stability=0.45, similarity_boost=0.8, style=0.15 — gibt natuerlich-warmen Sound ohne in Stoerlauten zu kippen.
4. Webhook-Tools erstellen
Tools sind seit ConvAI v2 eigene Resourcen (nicht inline am Agent). Endpoint: POST /v1/convai/tools mit tool_config.
curl -sS -X POST "https://api.elevenlabs.io/v1/convai/tools" \
-H "xi-api-key: $ELEVENLABS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"tool_config": {
"type": "webhook",
"name": "book_reservation",
"description": "Buche eine Tischreservierung. Nutze dieses Tool wenn der Anrufer einen Tisch reservieren moechte. Erfrage vorher alle Felder.",
"api_schema": {
"url": "https://placeholder.example.com/tools/book_reservation",
"method": "POST",
"request_body_schema": {
"type": "object",
"description": "Reservierungs-Daten",
"properties": {
"date": {"type": "string", "description": "YYYY-MM-DD"},
"time": {"type": "string", "description": "HH:MM (24h)"},
"guests": {"type": "integer", "description": "Anzahl Personen"},
"name": {"type": "string", "description": "Name des Anrufers"},
"phone": {"type": "string", "description": "Telefon Rueckruf"}
},
"required": ["date","time","guests","name","phone"]
}
},
"response_timeout_secs": 20
}
}'Antwort enthaelt id: tool_<id> — pro Tool merken.
5. Tools an Agent haengen
Tools werden ueber tool_ids: [...] am Agent referenziert (nicht inline). Endpoint: PATCH /v1/convai/agents/{agent_id}.
curl -sS -X PATCH "https://api.elevenlabs.io/v1/convai/agents/$AGENT_ID" \
-H "xi-api-key: $ELEVENLABS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"conversation_config": {
"agent": {
"prompt": {
"tool_ids": ["tool_<book>", "tool_<order>"]
}
}
}
}'end_call ist ein System-Tool und immer automatisch aktiv — nicht doppelt anlegen.
6. Auth/Embed-Mode setzen (Browser-Public oder Signed URL)
Fuer Browser-POC ohne Backend: enable_auth: false (Default bei neuem Agent — siehe platform_settings.auth). Damit darf jeder mit der Agent-ID per WebRTC verbinden.
Fuer Produktion spaeter umstellen auf signed URL:
- Backend macht
POST /v1/convai/conversation/get_signed_url?agent_id=...mit API-Key - Returns kurzlebige URL die das Frontend benutzt
- Verhindert dass Hobby-Sniffer dauerhaft auf den Agent verbinden und Credits verbrennen
7. Convai-Widget einbinden
Statische HTML reicht — das Widget ist komplett client-side. Snippet:
<elevenlabs-convai agent-id="agent_<id>"></elevenlabs-convai>
<script src="https://unpkg.com/@elevenlabs/convai-widget-embed" async type="text/javascript"></script>Optional CSS um das Widget mittig zu halten:
elevenlabs-convai { display: block; width: 100%; max-width: 480px; margin: 0 auto; }Default-Variant ist „bubble unten rechts”. Andere Varianten konfiguriert man am Agent unter platform_settings.widget (variant, placement, bg_color, border_radius etc.).
8. Optional: Knowledge-Base anhaengen
Wenn der Bot eine Speisekarte / Preisliste / FAQ kennen soll — mcp__elevenlabs__add_knowledge_base_to_agent mit URL, Datei (epub/pdf/docx/txt/html) oder Plain-Text. Wird zum Prompt-Kontext geadded.
Quirks die wir gelernt haben
voice_idundvoice_namenicht beide angeben im MCPtext_to_speech— sonst Fehler. Eines reicht.- shared-voices-Filter
voice_idgreift NICHT —?voice_id=wird ignoriert, immer per?search=<name>&language=defiltern und lokal nachvoice_idsuchen. - Free-Tier kann shared-library voices NICHT via TTS-API generieren (
paid_plan_required). ConvAI-Pfad rendert die Voice aber problemlos, weil das LLM die Antwort liefert und die Voice direkt im ElevenLabs-Render-Loop benutzt wird, ohne explizite TTS-API. → Konsequenz: fuer Voice-Sample-Vorhoeren entweder Default-Premade-Voice nehmen, oder direkt das offizielle Preview-MP3 aus dem Public-Bucket downloaden (URL steht insearch_voice_library-Output unterPreview URL). - Tool-
request_body_schema-Properties brauchen IMMERdescription— auch inarray.items. Ohne Description: 422 mit „Must set one of: description, dynamic_variable, is_system_provided, or constant_value”. - Voice-ID bleibt nach
voices/addgleich — kein neuer ID-Roundtrip noetig. Was sich aendert: Voice ist jetzt im eigenen Account-Inventar sichtbar. platform_settings.auth.enable_auth: falseist der Default bei neuen Agents — fuer schnellen POC ideal, fuer Produktion auf signed URLs umstellen.- API-Key-Header heisst
xi-api-key(nichtAuthorization: Bearer ...).
Latenz-Erwartung
eleven_flash_v2_5+gpt-4o-mini+ DE: Ende-zu-Ende-Antwortlatenz im Browser etwa 1.5–2.5 s (gemessen 2026-05-09 in Hamburg)- Mit Tool-Call (Webhook 200ms Roundtrip): plus 500ms–1s
- Faellt deutlich besser aus als der Polly+Lex+Lambda+Bedrock-Stack (gemessen ~3–5s im Aylem-POC)
Kosten
- ElevenLabs ConvAI ist paid feature, ab Creator-Tier (~0.10–0.15/Minute.
- LLM-Kosten separat —
gpt-4o-minietwa $0.0001/Turn bei 200 Tokens, fuer Telefon-Use-Cases vernachlaessigbar. - Voice-Cloning + Premium-Voices ggf. zusaetzlich, aber fuer Library-Voices kein Aufpreis.
Cross-Refs
- MCP-Setup: elevenlabs
- Erste Anwendung: telefon-assistent-aws (Aylem Eat & Meet, Phase 0.5)
- Anschluss-Pattern (noch zu schreiben): Tool-Webhook auf AWS Lambda hosten + signed URL fuer Produktion