Anpassad LLM-integrering
Driv en Twilio-telefonagent med din egen LLM med hjälp av Speech Engine SDK.
Översikt
ElevenAgents inbyggda Twilio-integrering omfattar användningsfallet där ElevenLabs är värd för LLM:en. Använd den här guiden när du behöver full kontroll över LLM-hjärnan på din egen server — din egen modell, RAG-pipeline, routning av funktionsanrop eller annat resonemang på serversidan — och agenten fortfarande finns på ett Twilio-telefonnummer.
Den anpassade LLM-delen levereras av Speech Engine SDK, som öppnar en WebSocket mellan ElevenLabs och din server så att din LLM kan strömma svar medan samtalet pågår. Twilio-delen använder Media Streams för att vidarebefordra samtalsljud till agenten.
Arkitektur
Speech Engine SDK exponerar två WebSocket-slutpunkter i agentens konversationssystem:
- Brain WebSocket körs på din server. ElevenLabs ansluter till den för att leverera transkript och ta emot LLM-genererad text.
- Conversation WebSocket körs på ElevenLabs. Klienter ansluter till den för att skicka in ljud och ta emot syntetiserat ljud. Twilio-bryggan ansluter via en signerad URL och vidarebefordrar μ-law-ljud i båda riktningarna.
Eftersom Twilio Media Streams och Speech Engine båda använder ulaw_8000 vidarebefordrar bryggan base64-kodat ljud utan omkodning.
Bryggan och brain-servern kan köras i samma process om det passar — exemplet nedan kombinerar dem.
När du ska använda det här mönstret
Både den här guiden och den inbyggda Twilio-integreringen placerar en agent på ett Twilio-telefonnummer. Skillnaden är vem som äger LLM:en:
- Inbyggd integrering: ElevenLabs är värd för LLM:en och du konfigurerar den via agenten. Enklare.
- Anpassad LLM via Speech Engine SDK (den här guiden): du är värd för LLM:en på din egen server. Full kontroll över modellen, RAG, funktionsanrop och affärslogik. Fler rörliga delar.
Om din LLM-logik ryms inom standardkonfigurationen för agenten bör du använda den inbyggda integreringen. Använd den här guiden när din brain behöver köra kod i din egen infrastruktur.
Det här mönstret använder Speech Engine SDK, som använder en WebSocket-anslutning för att kommunicera mellan din server och ElevenLabs API. Du kan också använda guiden Custom LLM, som använder en OpenAI-kompatibel HTTP-slutpunkt i stället för Speech Engine SDK.
Den största skillnaden mellan de två är WebSockets jämfört med HTTP-förfrågningar. Med WebSockets upprätthåller du en enda anslutning i stället för att upprätta en ny HTTP-anslutning för varje tur, vilket kan minska fördröjningen.
Förutsättningar
- Ett Twilio-konto och ett telefonnummer med röstfunktioner.
- En Speech Engine-resurs. Följ snabbstartsguiden för Speech Engine för att skapa en och lära dig mönstret för brain-servern.
- En offentlig HTTPS-tunnel (t.ex. ngrok). Twilio ringer upp din brygga via det offentliga internet.
- Python 3.9+ eller Node.js 18+.
Konfigurera agenten för μ-law-ljud
Twilio Media Streams använder 8 kHz μ-law-ljud. Konfigurera Speech Engine så att den tar emot och skickar ut samma format, så att bryggan inte behöver omkoda.
eleven_flash_v2 håller fördröjningen för text-till-tal låg, vilket är viktigt i ett telefonsamtal. Blocket request_headers instruerar ElevenLabs att inkludera x-api-key: <shared-secret> i varje WebSocket-anslutning till brain-servern — brain-servern kontrollerar headern för att säkerställa att endast din Speech Engine kan nå den.
Bygg bryggservern
Bryggan har tre rutter:
POST /incoming-call— Twilio-webhook. Returnerar TwiML som instruerar Twilio att öppna en Media Stream till/media-stream.GET /media-stream— Twilio Media Streams WebSocket. Vidarebefordrar ljud till och från Speech Engine Conversation WebSocket.GET /ws— Brain WebSocket. ElevenLabs ansluter hit när en konversation startar. Kör standardservernengine.serve()/engine.attach().
Skapa en signerad URL för Speech Engine
Bryggan begär en signerad URL varje gång ett nytt samtal kommer in. URL:en innehåller Speech Engine-ID:t och en engångssignatur, så bryggan behöver aldrig den råa API-nyckeln.
Servera TwiML-svaret
När ett samtal kommer in skickar Twilio en POST-förfrågan till /incoming-call. Svaret är TwiML som öppnar en Media Stream till bryggans egen /media-stream WebSocket.
RequestValidator (Python) och twilio.webhook({ validate: true }) (Node) kontrollerar headern X-Twilio-Signature mot TWILIO_AUTH_TOKEN. Utan validering kan vem som helst på det offentliga internet skicka en POST-förfrågan till /incoming-call och debitera samtal på ditt konto.
Koppla ihop Media Stream
Media Stream är en WebSocket som skickar en sekvens av JSON-händelser: connected, start, media (ljudets nyttolast) och stop. Bryggan öppnar en Speech Engine Conversation WebSocket vid start och vidarebefordrar ljud i båda riktningarna tills strömmen stängs.
Händelsen interruption från Speech Engine utlöser en clear-händelse på Twilio-strömmen, som kasserar buffrat ljud så att avbrott fungerar smidigt. Händelsen ping besvaras med pong för att hålla Conversation WebSocket aktiv.
Kör brain-servern parallellt
Brain-servern är standardservern för Speech Engine som visas i snabbstartsguiden. Det enda tillägget är kontrollen av den delade hemligheten vid WebSocket-uppgraderingen — acceptera anslutningen endast om x-api-key matchar värdet som du angav i Speech Engine.
Se snabbstartsguiden för Speech Engine för den fullständiga implementeringen av on_transcript, inklusive ett LLM-anrop och strömmat svar.
Peka Twilio mot bryggan
Starta bryggan och en offentlig tunnel
Notera den https://-URL som ngrok skriver ut — Twilio skickar en POST-förfrågan till den.
Uppdatera Speech Engine ws_url
Ange speech_engine.ws_url till den offentliga WebSocket-URL:en för din brain-slutpunkt så att ElevenLabs vet var den ska ansluta.
Konfigurera Twilio-numret
Öppna telefonnumrets Voice Configuration i Twilio-konsolen:
- A call comes in: Webhook
- URL:
https://abc123.ngrok.io/incoming-call - HTTP method: POST
Om numret är kopplat till en Elastic SIP Trunk ska du koppla bort det först — ett Twilio-nummer dirigeras antingen till en trunk eller till en webhook, inte båda.
Produktionsöverväganden
- Webhook-validering: validera alltid
X-Twilio-Signaturepå/incoming-call. Exemplet ovan använder Twilios hjälpbibliotek; hoppa inte över detta steg. - Delad hemlighet: tillämpa den delade hemligheten på brain WebSocket. Utan den kan vem som helst som gissar din ngrok-URL ansluta och utge sig för att vara ElevenLabs.
- Stabil värd: URL:er i ngroks kostnadsfria nivå ändras vid varje omstart. Använd en reserverad ngrok-domän eller ett riktigt värdnamn så att du inte behöver uppdatera Speech Engine
ws_urloch Twilio-webhooken efter varje omstart. - Fördröjning: varje samtal lägger till två nätverkshopp utöver LLM:ens tid till första token. Använd en modell med låg fördröjning och strömma svar för att hålla den upplevda fördröjningen låg.
- En eller två processer: exemplet placerar bryggan och brain-servern på samma port så att en enda ngrok-tunnel täcker allt. I produktion kan du dela upp dem på två tjänster så länge båda har en offentlig URL.
- Promptinjektion: talad inmatning från ett telefonsamtal är otillförlitlig användarinmatning. Validera transkript innan de påverkar verktygsanrop eller databasskrivningar.