Integrazione LLM personalizzato
Panoramica
L’integrazione nativa con Twilio di ElevenAgents copre il caso in cui ElevenLabs fornisce il modello LLM. Usa questa guida quando hai bisogno del pieno controllo del motore LLM sul tuo server — il tuo modello, pipeline RAG, instradamento delle function call o altri ragionamenti lato server — e l’agente si trova comunque su un numero di telefono Twilio.
La parte relativa al modello LLM personalizzato è fornita da Speech Engine SDK, che apre un WebSocket tra ElevenLabs e il tuo server, in modo che il tuo LLM possa trasmettere le risposte man mano che la chiamata procede. La parte relativa a Twilio usa Media Streams per inoltrare l’audio della chiamata all’agente.
Architettura
Speech Engine SDK espone due endpoint WebSocket nel sistema di conversazione dell’agente:
- Il WebSocket del motore viene eseguito sul tuo server. ElevenLabs si connette per inviare le trascrizioni e ricevere il testo generato dall’LLM.
- Il WebSocket della conversazione viene eseguito su ElevenLabs. I client vi si connettono per inviare audio e ricevere in risposta audio sintetizzato. Il bridge Twilio si connette tramite un URL firmato e inoltra l’audio μ-law in entrambe le direzioni.
Poiché Twilio Media Streams e Speech Engine usano entrambi ulaw_8000, il bridge inoltra audio codificato in base64 senza transcodifica.
Il bridge e il server del motore possono essere eseguiti nello stesso processo, se è più comodo: l’esempio seguente li combina.
Quando usare questo schema
Sia questa guida sia l’integrazione nativa con Twilio collocano un agente su un numero di telefono Twilio. La differenza sta in chi gestisce il modello LLM:
- Integrazione nativa: ElevenLabs fornisce il modello LLM, che configuri tramite l’agente. Più semplice.
- LLM personalizzato tramite Speech Engine SDK (questa guida): fornisci il modello LLM sul tuo server. Controllo completo sul modello, RAG, function call e logica di business. Più componenti da gestire.
Se la logica del tuo LLM rientra nella configurazione standard dell’agente, preferisci l’integrazione nativa. Usa questa guida quando il tuo motore deve eseguire codice sulla tua infrastruttura.
Questo schema usa Speech Engine SDK, che utilizza una connessione WebSocket per comunicare tra il tuo server e l’API ElevenLabs. Puoi anche usare la guida LLM personalizzato, che utilizza un endpoint HTTP compatibile con OpenAI anziché Speech Engine SDK.
La principale differenza tra i due è WebSocket rispetto alle richieste HTTP. L’uso di WebSocket consente di mantenere un’unica connessione invece di stabilire una nuova connessione HTTP per ogni turno, con possibili miglioramenti della latenza.
Prerequisiti
- Un account Twilio e un numero di telefono abilitato alle chiamate vocali.
- Una risorsa Speech Engine. Segui la guida rapida di Speech Engine per crearne una e conoscere lo schema del server del motore.
- Un tunnel HTTPS pubblico (ad esempio, ngrok). Twilio chiama il tuo bridge tramite Internet pubblico.
- Python 3.9+ o Node.js 18+.
Configura l’agente per l’audio μ-law
Twilio Media Streams usa audio μ-law a 8 kHz. Configura Speech Engine affinché accetti ed emetta lo stesso formato, così il bridge non dovrà effettuare transcodifica.
eleven_flash_v2 mantiene bassa la latenza della sintesi vocale, un aspetto importante in una chiamata telefonica. Il blocco request_headers indica a ElevenLabs di includere x-api-key: <shared-secret> in ogni connessione WebSocket del motore: il server del motore verifica l’header per assicurarsi che possa raggiungerlo solo il tuo Speech Engine.
Crea il server bridge
Il bridge espone tre route:
POST /incoming-call— webhook Twilio. Restituisce TwiML che indica a Twilio di aprire un Media Stream verso/media-stream.GET /media-stream— WebSocket di Twilio Media Streams. Inoltra l’audio da e verso il WebSocket della conversazione Speech Engine.GET /ws— WebSocket del motore. ElevenLabs si connette qui quando inizia una conversazione. Esegue il server standardengine.serve()/engine.attach().
Genera un URL firmato per Speech Engine
Il bridge richiede un URL firmato ogni volta che arriva una nuova chiamata. L’URL incorpora l’ID di Speech Engine e una firma monouso, così il bridge non ha mai bisogno della chiave API non elaborata.
Fornisci la risposta TwiML
Quando arriva una chiamata, Twilio invia una richiesta POST a /incoming-call. La risposta è TwiML che apre un Media Stream verso il WebSocket /media-stream del bridge.
RequestValidator (Python) e twilio.webhook({ validate: true }) (Node) verificano l’header X-Twilio-Signature rispetto a TWILIO_AUTH_TOKEN. Senza convalida, chiunque su Internet pubblico potrebbe inviare una richiesta POST a /incoming-call e addebitare chiamate al tuo account.
Collega il Media Stream
Il Media Stream è un WebSocket che invia una sequenza di eventi JSON: connected, start, media (il payload audio) e stop. Il bridge apre un WebSocket della conversazione Speech Engine su start e inoltra l’audio in entrambe le direzioni finché lo stream non si chiude.
L’evento interruption di Speech Engine attiva un evento clear nello stream Twilio, che elimina l’audio in buffer affinché l’interruzione vocale funzioni correttamente. All’evento ping viene risposto con pong per mantenere attivo il WebSocket della conversazione.
Esegui anche il server del motore
Il server del motore è il server Speech Engine standard mostrato nella guida rapida. L’unica aggiunta è la verifica del segreto condiviso durante l’upgrade WebSocket: accetta la connessione solo se x-api-key corrisponde al valore impostato in Speech Engine.
Consulta la guida rapida di Speech Engine per l’implementazione completa di on_transcript, inclusa una chiamata LLM e una risposta in streaming.
Indica a Twilio il bridge
Avvia il bridge e un tunnel pubblico
Prendi nota dell’URL https:// visualizzato da ngrok: Twilio vi invierà richieste POST.
Aggiorna ws_url di Speech Engine
Imposta speech_engine.ws_url sull’URL WebSocket pubblico dell’endpoint del tuo motore, così ElevenLabs sa dove connettersi.
Configura il numero Twilio
Nella console Twilio, apri la Voice Configuration del tuo numero di telefono:
- A call comes in: Webhook
- URL:
https://abc123.ngrok.io/incoming-call - HTTP method: POST
Se il numero è collegato a un Elastic SIP Trunk, scollegalo prima: un numero Twilio viene instradato a un trunk oppure a un webhook, non a entrambi.
Considerazioni per la produzione
- Convalida del webhook: convalida sempre
X-Twilio-Signaturesu/incoming-call. L’esempio precedente usa la libreria di supporto di Twilio; non saltare questo passaggio. - Segreto condiviso: applica il segreto condiviso sul WebSocket del motore. Senza di esso, chiunque indovini il tuo URL ngrok può connettersi e impersonare ElevenLabs.
- Host stabile: gli URL del piano gratuito di ngrok cambiano a ogni riavvio. Usa un dominio ngrok riservato o un hostname reale per non dover aggiornare
ws_urldi Speech Engine e il webhook Twilio dopo ogni riavvio. - Latenza: ogni chiamata aggiunge due passaggi di rete al tempo al primo token dell’LLM. Usa un modello a bassa latenza e trasmetti le risposte in streaming per ridurre la latenza percepita.
- Un processo o due: l’esempio colloca il bridge e il motore sulla stessa porta, così un unico tunnel ngrok copre tutto. In produzione, puoi suddividerli in due servizi, purché ciascuno disponga di un URL pubblico.
- Prompt injection: l’input vocale di una chiamata telefonica è input utente non attendibile. Convalida le trascrizioni prima che influenzino chiamate agli strumenti o scritture nel database.