Zbuduj agenta głosowego w 20 minut z ElevenLabs i Twilio
- Opublikowano
- Ostatnia aktualizacja
PosłuchajPosłuchaj tego artykułu
Agent głosowy może odbierać połączenia, transkrybować rozmówców na żywo (speech to text, STT), generować odpowiedzi przez duży model językowy (LLM) i mówić z powrotem przez moduł text to speech (TTS). Z ElevenLabs i Twilio uruchomisz działającego agenta na prawdziwym numerze w około 20 minut.
Dla deweloperów cały stack to ElevenLabs do syntezy mowy (Flash v2.5) i transkrypcji (Scribe v2 Realtime), Twilio do obsługi połączeń i OpenAI lub Anthropic jako LLM. Każdy z tych elementów możesz zamienić na inny, jeśli wolisz.
W tym artykule pokazujemy, jak zbudować agenta głosowego w 20 minut, używając Node.js i Typescript. Jeśli wolisz gotowe rozwiązanie, które samo obsługuje zmiany rozmówcy, przerywanie i połączenia, bez konieczności samodzielnego zarządzania całością, sprawdź ElevenAgents.
Jak działa architektura agenta głosowego
Zanim zaczniesz pisać kod, warto zrozumieć, jak łączą się wszystkie trzy usługi w stacku.
- Twilio: obsługuje połączenie telefoniczne i przesyłanie dźwięku.
- ElevenLabs: obsługuje STT przez Scribe v2 Realtime i TTS przez Flash v2.5.
- LLM: odpowiada za wywołania narzędzi i generowanie odpowiedzi.
Każdy etap to cienka warstwa, więc możesz wymienić dowolny element bez ruszania reszty. Na przykład możesz zamienić LLM OpenAI na Anthropic bez przepisywania pozostałych komponentów.
Połączenie telefoniczne trafia na twój serwer przez Twilio. Twilio odbiera połączenie PSTN, otwiera WebSocket do twojego serwera i przesyła dźwięk rozmówcy jako strumień ramek mu-law zakodowanych w base64. Twój serwer obsługuje całą kaskadę i odsyła zsyntetyzowany dźwięk przez ten sam WebSocket, a Twilio odtwarza go rozmówcy.

Tak wygląda przepływ, który wykorzystasz do zbudowania agenta głosowego:
Rozmówca dzwoni na twój numer Twilio. Twilio pobiera dokument TwiML z twojego webhooka. TwiML mówi Twilio, by otworzył Media Stream do twojego endpointu WebSocket. Twilio przesyła dźwięk jako zdarzenia JSON z ładunkami mu-law (ulaw_8000) w base64.
Twój serwer przekazuje fragmenty dźwięku do Scribe v2 Realtime do transkrypcji na żywo. Gdy rozmówca skończy mówić, wysyłasz transkrypt do LLM, a potem generujesz odpowiedź przez Flash v2.5 w ulaw_8000. Zsyntetyzowane ramki mu-law odsyłasz do Twilio przez WebSocket (base64), a Twilio odtwarza je rozmówcy.
Scribe v2 Realtime daje częściowe transkrypcje z opóźnieniem ok. 150 ms, a Flash v2.5 działa z opóźnieniem ok. 75 ms (bez sieci i aplikacji). Najwięcej czasu zajmuje LLM – to on decyduje o długości oczekiwania na pierwsze dźwięki. Żeby skrócić przerwę, przesyłamy odpowiedź LLM token po tokenie i zaczynamy syntezę zanim model skończy zdanie.
Więcej o wyborze modeli znajdziesz w przeglądzie modeli i w wyjaśnieniu jak działa opóźnienie.
Co musisz mieć, zanim zaczniesz budować agenta głosowego
Potrzebujesz czterech rzeczy. Każdą da się szybko skonfigurować, ale brak którejkolwiek zablokuje uruchomienie serwera.
Sprawdź, czy masz:
- Numer Twilio z obsługą Voice: Zanotuj numer, Account SID i Auth Token z konsoli Twilio.
- Klucz API ElevenLabs: utworzysz go w swoim panelu ElevenLabs. Klucz przesyłamy w nagłówku xi-api-key i jest tajny, więc trzymaj go tylko po stronie serwera. Zobacz
- Klucz API LLM:W tym poradniku możesz użyć Anthropic Claude lub OpenAI – wybierz jeden.
- Ngrok (lub inny tunel) do lokalnych testów: Twilio musi dotrzeć do twojego serwera przez publiczny HTTPS i WSS, a ngrok to umożliwia bez wdrażania czegokolwiek.
Ustaw swoje sekrety jako zmienne środowiskowe i nigdy ich nie commituj.
Następnie uruchom tunel na porcie, którego użyje twój serwer:
Jak działa protokół Twilio Media Streams
Twilio nie daje surowego gniazda audio. Zamiast tego wszystko opakowuje w ustrukturyzowany JSON przez WebSocket. Znając cztery typy zdarzeń i format wysyłki, łatwo zrozumiesz handler WebSocket z kroku 2.
Po połączeniu z twoim WebSocketem Twilio wysyła sekwencję wiadomości JSON, które mogą mieć cztery typy zdarzeń.
Najpierw przychodzi zdarzenie connected, które potwierdza połączenie WebSocket. Start pojawia się raz na początku streamu; zawiera streamSid, który musisz zapisać, bo będzie potrzebny do wysyłania dźwięku, oraz metadane połączenia w start.customParameters i start.callSid.
Media to zdarzenie powtarzalne: media.payload to fragment 8kHz mu-law w base64 (20 ms na ramkę), a media.track to dźwięk rozmówcy. Na końcu stop pojawia się, gdy stream się kończy, zwykle po rozłączeniu.
Aby odtworzyć dźwięk, wysyłasz wiadomość typu media z tym samym streamSid i ładunkiem mu-law w base64. Aby przerwać już zakolejkowany dźwięk, wysyłasz wiadomość clear ze streamSid, co czyści bufor Twilio.
Kodowanie wejścia i wyjścia jest identyczne (ulaw_8000). Zamawiamy ulaw_8000 z ElevenLabs Text to Speech i przekazujemy bajty prosto do Twilio bez żadnej konwersji.
Krok 1: Obsłuż webhook TwiML
Gdy przychodzi połączenie, Twilio wysyła żądanie HTTP do twojego webhooka, a ty odpowiadasz TwiML, który łączy rozmowę z Media Stream. <Connect><Stream> otwiera dwukierunkowy WebSocket. Użyj <Connect>, nie <Start>: utrzymuje połączenie przez cały czas streamu i pozwala odsyłać dźwięk, co jest tu kluczowe.
Webhook zwraca taki TwiML:
W Express to pojedynczy handler POST, który wstawia hosta i zwraca dokument:
W konsoli Twilio ustaw webhook "A call comes in" na https://your-subdomain.ngrok.app/incoming-call z użyciem HTTP POST.
Krok 2: Obsłuż WebSocket Media Stream
Handler WebSocket czyta zdarzenia Twilio, obsługuje kaskadę i odsyła dźwięk.
Trzymamy trochę stanu na połączenie: streamSid, połączenie STT i flagę, czy agent właśnie mówi. Handler dekoduje każdą ramkę media z base64 i przekazuje surowe bajty mu-law do STT:
Krok 3: Transkrybuj przez Scribe v2 Realtime
Scribe v2 Realtime przyjmuje strumieniowe fragmenty dźwięku i zwraca częściowe oraz końcowe transkrypcje. Obsługuje mu-law bezpośrednio, więc przekazujemy mu ramki Twilio bez zmian.
Dodatkowo oferuje Voice Activity Detection do segmentacji na podstawie ciszy i ręczną kontrolę zatwierdzania segmentów. Dla agenta telefonicznego segmentacja przez VAD jest zwykle najlepsza, bo naturalna pauza to najpewniejszy sygnał końca wypowiedzi rozmówcy.
Kroki: Otwórz stream STT na początku rozmowy. Przesyłaj każdą ramkę mu-law. Na końcowe transkrypty reaguj wywołaniem LLM.
Klient STT na żywo wciąż się rozwija, więc poniższy kształt trzymamy za małym adapterem TypeScript (openRealtimeStt), który piszesz pod API na żywo, a nie sztywny zestaw pól. Traktuj onFinal jako hook przekazujący zakończoną wypowiedź do kolejnego etapu.
Opóźnienie rozpoznawania na żywo to ok. 150 ms dla częściowych wyników, więc przerwa między końcem wypowiedzi rozmówcy a startem agenta jest krótka. O wersji batch i pełnych możliwościach przeczytasz w dokumentacji Speech to Text oraz na stronie produktu Speech to Text na żywo.
Krok 4: Generuj odpowiedź przez LLM
To etap, w którym powstaje odpowiedź. LLM bierze historię rozmowy i zwraca tekst asystenta. Strumieniuj odpowiedź, żeby zacząć syntezę już od pierwszego zdania.
Tutaj używamy OpenAI:
Powyższy model, gpt-4.1-mini, to przykład niskiego opóźnienia; claude-haiku-4-5 to podobna opcja od Anthropic. Każdy z nich może obsłużyć ten sam kontrakt llmReply – wystarczy podmienić ciało funkcji, reszta agenta zostaje bez zmian.
System prompt ogranicza długość odpowiedzi, co ma znaczenie przez telefon: długie odpowiedzi są wolne i trudno je naturalnie przerwać.
Krok 5: Syntezuj przez Flash TTS w ulaw_8000
Teraz tekst trzeba zamienić na dźwięk, który Twilio odtworzy. Zamów Flash v2.5 z outputFormat: "ulaw_8000", by bajty pasowały do kodowania Twilio, potem strumieniuj dźwięk i odsyłaj każdy fragment przez WebSocket jako zdarzenie media.
Zbieraj tokeny LLM w fragmenty zdań i syntezuj każdy fragment od razu, zamiast czekać na całą odpowiedź. Dzięki temu rozmówca słyszy pierwsze zdanie, gdy model generuje kolejne. Jeśli chcesz większą kontrolę nad syntezą krok po kroku, zobacz przewodnik po TTS WebSocket na żywo – poniższy sposób HTTP jest prostszy i wystarcza do krótkich wypowiedzi.
Jak przygotować agenta głosowego AI do produkcji
Po tych pięciu krokach masz działającego agenta. To nie to samo co wdrożenie produkcyjne.
Zanim podłączysz agenta do prawdziwej linii, musisz pamiętać o kilku rzeczach.
Weryfikuj podpisy webhooków Twilio
Każdy, kto pozna twój URL webhooka, może do niego POSTować, więc najpierw sprawdź, czy żądanie faktycznie pochodzi z Twilio. Twilio podpisuje każde żądanie twoim Auth Tokenem w nagłówku X-Twilio-Signature – odrzucaj wszystko, co nie przejdzie walidacji. Podpis liczy się po pełnym URL i parametrach POST, więc musisz liczyć go tak samo jak Twilio.
Pomaga w tym gotowa biblioteka Twilio:
Dbaj o bezpieczeństwo sekretów
Trzymaj ELEVENLABS_API_KEY, klucz LLM i TWILIO_AUTH_TOKEN w menedżerze sekretów, nie w kodzie ani w jawnych plikach env w repo. Ogranicz klucz ElevenLabs tylko do endpointów potrzebnych tej usłudze i ustaw limit wydatków, żeby ewentualny wyciek nie był groźny.
W planach Enterprise możesz dodatkowo ograniczyć klucz do wybranych adresów IP. Ten serwer używa klucza bezpośrednio, bo nigdy nie opuszcza backendu; jeśli logika audio trafiłaby do przeglądarki lub aplikacji mobilnej, przejdź na tokeny jednorazowe, by klucz nie był widoczny po stronie klienta.
Zrozum limit współbieżności
Każdy plan ma limit współbieżności, inny dla każdej rodziny modeli. Limit liczy, ile żądań jednocześnie generuje dźwięk.
Dla agenta telefonicznego to działa na twoją korzyść. Generowanie dźwięku jest szybsze niż odtwarzanie, więc każde połączenie zużywa TTS tylko przez chwilę, gdy trwa synteza odpowiedzi, a nie przez cały czas rozmowy. W praktyce limit współbieżności ok. 5 pozwala obsłużyć nawet 100 rozmów naraz, bo generowanie kończy się dużo szybciej niż odtwarzanie.
Mimo to monitoruj zapas, nie zgaduj. Odpowiedzi ElevenLabs mają nagłówki current-concurrent-requests i maximum-concurrent-requests – loguj je i ustaw alerty, gdy zbliżasz się do limitu. Po przekroczeniu limitu żądania trafiają do kolejki (zwykle +50 ms), a długotrwałe przeciążenie daje HTTP 429.
Obsługuj HTTP 429 krótkim opóźnieniem. Jeśli się powtarzają, zwiększ limity na stronie cen lub – w Enterprise – przez opiekuna konta.
Obsłuż barge-in i przerywanie
Rozmówca, który zaczyna mówić, gdy agent mówi, oczekuje, że agent się zatrzyma. To barge-in – poprawna obsługa sprawia, że agent brzmi naturalnie, a nie jak automat.
Wykrywaj mowę rozmówcy podczas odtwarzania agenta przez sygnał VAD z STT. Gdy ją wykryjesz, zrób dwie rzeczy: przestań przesyłać fragmenty TTS (flaga agentSpeaking już to obsługuje, przerywając pętlę) i wyślij do Twilio wiadomość clear, by wyczyścić już zakolejkowany dźwięk.
Jeśli pominiesz clear, Twilio dalej odtwarza buforowany dźwięk, więc agent mówi ponad rozmówcą.
Loguj, monitoruj i obsługuj błędy z klasą
Mierz każdy etap, by wiedzieć, gdzie pojawia się opóźnienie. Zmierz czas od końcowego transkryptu do pierwszego tokena LLM, od tokena LLM do pierwszego bajtu TTS i od TTS do ramki wysłanej do Twilio. Najwięcej zmienności znajdziesz w LLM; STT i TTS są stabilne.
Planuj częściowe awarie. LLM może się rozłączyć, stream STT może się zerwać, a czas do ElevenLabs przez internet waha się od 20 do 200 ms w zależności od lokalizacji. Umieść serwer blisko rozmówców, nie tylko blisko ElevenLabs – ElevenLabs już kieruje ruch do najbliższego klastra (Ameryka Północna, Europa, Azja Południowo-Wschodnia).
Gdy etap zawiedzie, nie zostawiaj rozmówcy w ciszy: wygeneruj krótką linijkę awaryjną ("Przepraszam, możesz powtórzyć?") i utrzymaj połączenie. Każdy etap opakuj timeoutem i try/catch, by jedna nieudana tura nie zerwała całego WebSocket.
Warto ustawić jeszcze kilka domyślnych opcji przed wdrożeniem:
- Ogranicz długość odpowiedzi w system prompt, by wypowiedzi były krótkie i łatwe do przerwania.
- Ogranicz historię rozmowy, by długie połączenia nie rozrastały kontekstu LLM bez końca.
- Ustaw maksymalny czas rozmowy, by uniknąć zablokowania współbieżności przez zawieszone sesje.
Aby dalej optymalizować to, na co masz wpływ, zobacz dokument o opóźnieniach, który wyjaśnia, skąd bierze się czas do pierwszego dźwięku, przegląd modeli omawia kompromisy szybkości i jakości, a przewodnik po TTS WebSocket na żywo pokazuje, jak jeszcze bardziej skrócić opóźnienie przez podawanie tekstu fragmentami.
Buduj gotowych do produkcji agentów głosowych z ElevenAPI
Po 20 minutach masz już wszystkie warstwy produkcyjnego agenta głosowego. Twilio obsługuje połączenia, Scribe v2 Realtime transkrybuje, LLM generuje odpowiedzi, a Flash v2.5 mówi przez ten sam WebSocket.
Jeśli nie chcesz samodzielnie zarządzać całą kaskadą, ElevenAgents oferuje obsługę zmian rozmówcy, przerywania i integrację z telefonią jako gotową usługę na tych samych modelach, które właśnie połączyłeś.
Jeśli chcesz dalej optymalizować własny stack, sprawdź stronę produktu ElevenAPI z planami, limitami współbieżności i biblioteką głosów. Albo po prostu zarejestruj się i zacznij już dziś – wykonaj pierwsze połączenie.
.webp&w=3840&q=80)
.webp&w=3840&q=80)

.webp&w=3840&q=80)
