Erstellen Sie in 20 Minuten einen Voice-Agenten mit ElevenLabs und Twilio
- Veröffentlicht
- Zuletzt aktualisiert
AnhörenArtikel anhören
Ein Sprachagent kann eingehende Anrufe annehmen, Anrufer in Echtzeit mit Speech to Text (STT) transkribieren, mit einem großen Sprachmodell (LLM) eine Antwort generieren und über ein Text to Speech-Modul (TTS) antworten. Mit ElevenLabs und Twilio können Sie in rund 20 Minuten einen funktionierenden Agenten unter einer echten Telefonnummer einrichten.
Für Entwickler besteht der verwendete Stack aus ElevenLabs für Sprachsynthese (Flash v2.5) und Transkription (Scribe v2 Realtime), Twilio für Telefonie sowie OpenAI oder Anthropic als LLM. Alle diese Komponenten sind austauschbar. Sie können also die Komponenten wählen, mit denen Sie am besten vertraut sind.
Dieser Artikel zeigt, wie Sie mit Node.js und Typescript in 20 Minuten einen Sprachagenten erstellen. Wenn Sie eine verwaltete Alternative suchen, die Sprecherwechsel, Unterbrechungen und Telefonie übernimmt, ohne dass Sie die Kaskade selbst betreiben müssen, nutzen Sie ElevenAgents.
So funktioniert die Architektur eines Sprachagenten
Bevor Sie Code schreiben, sollten Sie verstehen, wie die drei Dienste in Ihrem Tech-Stack verbunden sind.
- Twilio: Verwaltet den Anruf und den Audiotransport.
- ElevenLabs: Übernimmt STT über Scribe v2 Realtime und TTS über Flash v2.5.
- LLM: Übernimmt Tool Calling und formuliert die Antwort.
Jede Stufe ist ein schlanker Adapter. Deshalb können Sie einen Dienst austauschen, ohne den Rest anzupassen. Sie könnten beispielsweise das OpenAI-LLM durch Anthropic ersetzen, ohne andere Komponenten neu schreiben zu müssen.
Ein Anruf erreicht Ihren Server über Twilio. Twilio nimmt den PSTN-Anruf entgegen, öffnet einen WebSocket zurück zu Ihrem Server und leitet das Audio des Anrufers als Stream Base64-kodierter Mu-Law-Frames weiter. Ihr Server führt die Kaskade aus und streamt synthetisiertes Audio über denselben WebSocket zurück. Twilio spielt es dem Anrufer vor.

So erstellen Sie einen Sprachagenten:
Ein Anrufer wählt Ihre Twilio-Nummer. Twilio ruft ein TwiML-Dokument von Ihrem Webhook ab. Das TwiML weist Twilio an, einen Media Stream zu Ihrem WebSocket-Endpunkt zu öffnen. Twilio streamt eingehendes Audio als JSON-Ereignisse mit Base64-Mu-Law-Nutzdaten (ulaw_8000).
Ihr Server leitet Audio-Chunks zur Streaming-Transkription an Scribe v2 Realtime weiter. Sobald ein Sprecherzug des Anrufers abgeschlossen ist, senden Sie das Transkript an das LLM und synthetisieren dann die Antwort mit Flash v2.5 in ulaw_8000. Die synthetisierten Mu-Law-Frames senden Sie Base64-kodiert über den WebSocket an Twilio zurück. Twilio spielt sie dem Anrufer vor.
Scribe v2 Realtime liefert Teiltranskriptionen mit etwa 150 ms Latenz. Flash v2.5 benötigt für die Modellinferenz etwa 75 ms, ohne Netzwerk- und Anwendungslatenz. Das LLM trägt am meisten und am wenigsten vorhersehbar zur Zeit bis zum ersten Audio bei. Dort fällt der größte Teil des Latenzbudgets an. Um die Pause kurz zu halten, streamen wir die LLM-Ausgabe Token für Token und beginnen mit der Synthese, bevor das Modell seinen Satz beendet hat.
Zu den Modellabwägungen hinter diesen Entscheidungen siehe die Modellübersicht und die Erklärung zum Verständnis von Latenz.
Was Sie vor dem Erstellen eines Sprachagenten benötigen
Dieser Leitfaden setzt vier Voraussetzungen voraus. Jede ist schnell eingerichtet, aber ohne eine davon kann der Server nicht laufen.
Prüfen Sie diese Voraussetzungen:
- Eine Twilio-Telefonnummer mit Voice-Funktion: Notieren Sie die Nummer sowie Ihre Account SID und Ihr Auth Token aus der Twilio-Konsole.
- ElevenLabs-API-Schlüssel: Er wird in Ihrem ElevenLabs-Dashboard erstellt. Der Schlüssel wird im Header xi-api-key übertragen und ist geheim. Bewahren Sie ihn daher ausschließlich serverseitig auf. Siehe API-Authentifizierung.
- LLM-API-Schlüssel: Dieses Tutorial behandelt Anthropic Claude und OpenAI als austauschbare Backends. Wählen Sie eines davon.
- Ngrok (oder ein anderer Tunnel) für die lokale Entwicklung: Twilio muss Ihren Server über eine öffentliche HTTPS- und WSS-URL erreichen. Ngrok ermöglicht das ohne Deployment.
Legen Sie Ihre Geheimnisse als Umgebungsvariablen fest und committen Sie sie nie.
Starten Sie dann einen Tunnel zum Port, den Ihr Server verwendet:
Das Twilio-Media-Streams-Protokoll verstehen
Twilio stellt keinen reinen Audio-Socket bereit. Stattdessen verpackt es alles in einem strukturierten JSON-Protokoll über WebSocket. Wenn Sie die vier Ereignistypen und das Sendeformat verstehen, ist der WebSocket-Handler aus Schritt 2 klar, bevor Sie ihn schreiben.
Sobald Twilio mit Ihrem WebSocket verbunden ist, sendet es eine Folge von JSON-Textnachrichten mit vier möglichen Ereignistypen.
Das Ereignis connected trifft zuerst ein und bestätigt, dass der WebSocket aktiv ist. Das Ereignis start wird beim Start des Media Streams einmal gesendet. Es enthält eine streamSid, die Sie speichern müssen, um Audio zurückzusenden, sowie Anrufmetadaten unter start.customParameters und start.callSid.
Das Ereignis media wiederholt sich: media.payload ist ein Base64-kodierter Chunk mit 8-kHz-Mu-Law-Audio, 20 ms pro Frame, und media.track ist für Anruferaudio inbound. Schließlich wird stop gesendet, wenn der Stream endet, typischerweise weil der Anruf beendet wurde.
Um Audio wiederzugeben, senden Sie eine Nachricht vom Typ media mit derselben streamSid und einer Base64-Mu-Law-Nutzlast. Um bereits eingereihtes Audio zu unterbrechen, senden Sie eine clear-Nachricht mit der streamSid. Dadurch wird Twilios ausgehender Puffer geleert.
Die ein- und ausgehenden Kodierungen sind identisch (ulaw_8000). Wir fordern ulaw_8000 von ElevenLabs Text to Speech an und leiten die Bytes ohne Zwischenschritt zur Neusampling direkt an Twilio weiter.
Schritt 1: Den TwiML-Webhook bereitstellen
Bei einem eingehenden Anruf sendet Twilio eine HTTP-Anfrage an Ihren Webhook. Sie antworten mit TwiML, das den Anruf mit Ihrem Media Stream verbindet. Das Verb <Connect><Stream> öffnet einen bidirektionalen WebSocket. Verwenden Sie hier <Connect> statt <Start>: Es hält den Anruf während des Streams aktiv und ermöglicht das Zurücksenden von Audio.
Der Webhook gibt folgendes TwiML zurück:
In Express ist das ein einzelner POST-Handler, der den Host einfügt und das Dokument zurückgibt:
Legen Sie in der Twilio-Konsole den Webhook „A call comes in“ der Nummer auf https://your-subdomain.ngrok.app/incoming-call mit HTTP POST fest.
Schritt 2: Den Media-Stream-WebSocket annehmen
Der WebSocket-Handler liest Twilio-Ereignisse, steuert die Kaskade und schreibt Audio zurück.
Wir speichern wenig Status pro Anruf: die streamSid, eine STT-Verbindung und ein Flag, das angibt, ob der Agent gerade spricht. Der Handler dekodiert jeden eingehenden Media-Frame aus Base64 und leitet die rohen Mu-Law-Bytes an STT weiter:
Schritt 3: Mit Scribe v2 Realtime transkribieren
Scribe v2 Realtime akzeptiert Audio-Chunks im Stream und gibt Teil- sowie Endtranskriptionen zurück. Mu-Law-Kodierung wird direkt unterstützt, daher übergeben wir Twilios Frames unverändert.
Es bietet außerdem Voice Activity Detection zur stillenbasierten Segmentierung und eine manuelle Commit-Steuerung zum Abschließen eines Segments. Für einen Telefonagenten ist VAD-basierte Segmentierung meist die richtige Wahl, da eine natürliche Pause das zuverlässigste Signal für das Ende eines Sprecherzugs ist.
Die Schritte: Öffnen Sie beim Anrufstart einen STT-Stream. Übermitteln Sie jeden eingehenden Mu-Law-Chunk. Reagieren Sie auf abgeschlossene Transkripte, indem Sie das LLM aufrufen.
Die Schnittstelle des Echtzeit-STT-Clients entwickelt sich weiter. Deshalb ist die folgende Form hinter einem kleinen TypeScript-Adapter (openRealtimeStt) gekapselt, den Sie anhand der aktuellen API implementieren, nicht anhand eines festen Satzes von Feldnamen. Behandeln Sie onFinal als Hook, der einen abgeschlossenen Sprecherzug an die nächste Stufe übergibt.
Die Echtzeiterkennung benötigt für Teiltranskriptionen etwa 150 ms. Dadurch bleibt die wahrgenommene Pause zwischen dem Ende des Anrufers und dem Start des Agenten kurz. Informationen zum Batch-Pendant und zum vollständigen Funktionsumfang finden Sie in der Speech-to-Text-Dokumentation und auf der Produktseite für Echtzeit-Speech-to-Text.
Schritt 4: Eine Antwort mit einem LLM generieren
In dieser Stufe wird die Antwort erzeugt. Das LLM erhält den Gesprächsverlauf und gibt den Text des Assistenten zurück. Streamen Sie die Antwort, damit Sie mit der Synthese beim ersten Satz beginnen können.
Hier wird OpenAI verwendet:
Die obige Modell-ID gpt-4.1-mini ist ein Beispiel für eine Wahl mit niedriger Latenz. claude-haiku-4-5 ist eine vergleichbare Option von Anthropic. Beide Anbieter können denselben llmReply-Vertrag erfüllen. Tauschen Sie den Funktionskörper aus, der Rest des Agenten bleibt unverändert.
Der System-Prompt begrenzt die Antwortlänge. Das ist am Telefon wichtig: Lange Antworten wirken langsam und lassen sich nur schwer natürlich unterbrechen.
Schritt 5: Mit Flash TTS in ulaw_8000 synthetisieren
Der Text muss nun in Audio umgewandelt werden, das Twilio abspielen kann. Fordern Sie Flash v2.5 mit outputFormat: "ulaw_8000" an, damit die Bytes Twilios erwarteter Kodierung entsprechen. Streamen Sie dann das Audio und leiten Sie jeden Chunk als media-Ereignis über den WebSocket zurück.
Sammeln Sie LLM-Token in satzgroßen Fragmenten und synthetisieren Sie jedes Fragment nach Abschluss, statt auf die gesamte Antwort zu warten. Das verkürzt die Zeit bis zum ersten Audio, weil der Anrufer den ersten Satz hört, während das Modell den zweiten noch erzeugt. Für eine präzisere Steuerung der inkrementellen Synthese zeigt der Echtzeit-TTS-WebSocket-Leitfaden, wie Sie Text in einen einzelnen offenen Synthese-Socket einspeisen. Der folgende HTTP-Streaming-Ansatz ist einfacher und für kurze Gesprächszüge ausreichend.
Ihren KI-Sprachagenten für den Produktionseinsatz absichern
Nach den fünf Schritten oben haben Sie einen funktionierenden Agenten. Das ist noch kein Produktiv-Deployment.
Bevor Sie den Agenten an eine echte Telefonleitung anschließen, müssen Sie mehrere Punkte beachten.
Twilio-Webhook-Signaturen validieren
Jeder, der Ihre Webhook-URL kennt, kann einen POST-Request dorthin senden. Prüfen Sie daher zuerst, ob die Anfrage tatsächlich von Twilio stammt. Twilio signiert jede Anfrage mit Ihrem Auth Token im Header X-Twilio-Signature. Alles, was die Validierung nicht besteht, lehnen Sie ab. Die Signatur wird über die vollständige URL und die POST-Parameter berechnet. Sie müssen sie daher auf dieselbe Weise wie Twilio berechnen.
Der Twilio-Helper übernimmt das für Sie:
Geheimnisse korrekt verwalten
Speichern Sie ELEVENLABS_API_KEY, den LLM-Schlüssel und TWILIO_AUTH_TOKEN in einem Secrets Manager, nicht im Quellcode oder in Klartext-Umgebungsdateien, die in ein Repository committet werden. Beschränken Sie den ElevenLabs-Schlüssel auf die Endpunkte, die dieser Dienst benötigt, und legen Sie ein Kreditlimit fest. So bleibt der Schaden bei einem Leak begrenzt.
Enterprise-Pläne können Schlüssel zusätzlich per IP-Whitelist auf bestimmte IP-Bereiche beschränken. Dieser Server verwendet den API-Schlüssel direkt, da er Ihr Backend nie verlässt. Würde Audiologik in einen Browser oder mobilen Client verlagert, würden Sie Einmal-Token verwenden, damit der Schlüssel nie clientseitig offengelegt wird.
Das Parallelitätslimit verstehen
Jeder Plan hat ein Parallelitätslimit, das je nach Modellfamilie variiert. Es zählt, wie viele Anfragen gleichzeitig aktiv Audio generieren.
Bei einem Telefonagenten ist diese Abrechnung vorteilhaft. Die Audiogenerierung ist schneller als die Wiedergabe. Daher verbraucht jeder Anruf TTS-Parallelität nur in den kurzen Zeitfenstern, in denen eine Antwort synthetisiert wird, nicht während des gesamten Anrufs. Als grobe Faustregel kann ein Parallelitätslimit von etwa fünf ungefähr 100 gleichzeitige Gesprächsanrufe unterstützen, da die Generierung lange vor der Wiedergabe endet.
Überwachen Sie dennoch die Reserve, statt zu raten. ElevenLabs-Antworten enthalten die Header current-concurrent-requests und maximum-concurrent-requests. Protokollieren Sie sie und lösen Sie eine Warnung aus, wenn Sie sich dem Maximum nähern. Bei Überschreitung des Limits werden Anfragen nach Priorität eingereiht, was typischerweise etwa 50 ms hinzufügt. Bei anhaltender Überlastung wird HTTP 429 zurückgegeben.
Behandeln Sie HTTP-429-Antworten mit einem kurzen Backoff. Bleiben sie bestehen, erhöhen Sie die Limits über ein Upgrade auf der Preisseite oder als Enterprise-Kunde über Ihren Account Manager.
Barge-in und Unterbrechungen behandeln
Ein Anrufer, der zu sprechen beginnt, während der Agent spricht, erwartet, dass der Agent stoppt. Das nennt man Barge-in. Die korrekte Behandlung ist ein wichtiger Faktor dafür, dass ein Agent natürlich statt geskriptet wirkt.
Erkennen Sie Sprache des Anrufers während der Agentenwiedergabe über das STT-VAD-Signal. Dann tun Sie zwei Dinge: Erstens stoppen Sie die Weiterleitung von TTS-Chunks. Das Flag agentSpeaking in speak erledigt dies bereits durch Abbruch der Schleife. Zweitens senden Sie Twilio eine clear-Nachricht, um bereits dort eingereihtes Audio zu löschen.
Wenn Sie clear auslassen, spielt Twilio gepuffertes Audio weiter ab, nachdem Sie das Senden gestoppt haben. Der Agent scheint dann über den Anrufer hinwegzusprechen.
Protokollieren, überwachen und Ausfälle sauber behandeln
Instrumentieren Sie jede Stufe, damit Sie Latenzen zuordnen können, wenn sich ein Anruf langsam anfühlt. Messen Sie die Zeit vom endgültigen Transkript bis zum ersten LLM-Token, vom ersten LLM-Token bis zum ersten TTS-Byte und vom ersten TTS-Byte bis zum an Twilio gesendeten Frame. Der Großteil der variablen Latenz liegt in der LLM-Stufe; STT und TTS sind vergleichsweise stabil.
Planen Sie außerdem für Teilausfälle. Das LLM kann ein Timeout erreichen, der STT-Stream kann abbrechen und die Netzwerk-Roundtrip-Zeit zu ElevenLabs variiert je nach geografischem Standort im öffentlichen Internet zwischen etwa 20 und 200 ms. Platzieren Sie Ihren Server nahe bei Ihren Anrufern, nicht nur nahe bei ElevenLabs. ElevenLabs leitet bereits zum nächstgelegenen Cluster in Nordamerika, Europa oder Südostasien weiter.
Wenn eine Stufe fehlschlägt, lassen Sie den Anrufer nicht in Stille zurück: Synthetisieren Sie eine kurze Fallback-Zeile („Entschuldigung, können Sie das wiederholen?“) und halten Sie den Anruf aktiv. Kapseln Sie jede Stufe mit einem Timeout und try/catch, damit ein fehlgeschlagener Sprecherzug nicht den gesamten WebSocket beendet.
Vor dem Release sollten Sie noch einige Standards festlegen:
- Begrenzen Sie die Antwortlänge im System-Prompt wie gezeigt, damit Sprecherzüge kurz und unterbrechbar bleiben.
- Begrenzen Sie den Gesprächsverlauf, damit lange Anrufe den LLM-Kontext nicht unbegrenzt vergrößern.
- Legen Sie eine maximale Anrufdauer als Absicherung gegen festhängende Sitzungen fest, die unbemerkt Parallelität verbrauchen.
Um die Komponenten, die Sie kontrollieren, weiter zu optimieren, erklärt das Latenzdokument, wodurch die Zeit bis zum ersten Audio entsteht. Die Modellübersicht behandelt die Abwägungen zwischen Geschwindigkeit und Qualität, und der Echtzeit-TTS-WebSocket-Leitfaden zeigt, wie Sie die Syntheselatenz mit inkrementeller Texteingabe weiter senken.
Produktionsreife Sprachagenten mit ElevenAPI erstellen
Nach 20 Minuten verfügen Sie über jede Ebene eines produktionsreifen Sprachagenten. Twilio übernimmt die Telefonie, Scribe v2 Realtime transkribiert, ein LLM generiert Antworten und Flash v2.5 spricht über denselben WebSocket zurück.
Wenn Sie die Kaskade nicht selbst betreiben möchten, bietet ElevenAgents Sprecherwechsel, Unterbrechungsbehandlung und Telefonieintegration als verwalteten Dienst auf Basis derselben Modelle, die Sie gerade manuell verbunden haben.
Um einen Stack unter Ihrer Kontrolle weiter zu optimieren, besuchen Sie die Produktseite von ElevenAPI für Pläne, Parallelitätslimits und die Stimmbibliothek. Alternativ können Sie sich registrieren und noch heute Ihren ersten Anruf starten.




