IA8 min di lettura
Cosa abbiamo imparato collegando un LLM locale a una linea telefonica
L'IA vocale gestita prevede una tariffazione al minuto, quindi il compenso per un agente che lavora si traduce in una fattura più alta. Sviluppare Vocale in modo che funzioni sia su un'API ospitata che su una GPU privata ci ha insegnato quattro cose su ciò che diventa davvero difficile quando i modelli vengono trasferiti in-house.

Ogni piattaforma di IA vocale gestita applica una tariffazione al minuto. Sembra ragionevole finché non la si utilizza su una linea di assistenza e non inizia a funzionare, perché la ricompensa per un buon operatore è un maggior numero di chiamate risposte, e la ricompensa per un maggior numero di chiamate risposte è una fattura più alta. Migliora le prestazioni, aumenta il costo. Su una linea di assistenza, che esiste proprio per assorbire il volume di chiamate, questo è l’incentivo sbagliato su cui puntare.
Abbiamo creato Vocale per rispondere alla linea telefonica di un’azienda: risponde al primo squillo, fornisce risposte basate sui manuali e sulle politiche aziendali e apre un ticket di assistenza quando la risposta onesta è che qualcuno deve esaminare la questione. Fin dall’inizio abbiamo preso una decisione che ha plasmato tutto ciò che è seguito. La piattaforma offre due motori dietro un unico prodotto. Nel livello in hosting, il riconoscimento vocale, il ragionamento e la sintesi vocale provengono da un’API di terze parti e ogni minuto viene conteggiato. Nel livello self-hosted, tutti e tre i componenti girano su una GPU controllata dall’azienda, nessun file audio o documento esce dall’edificio e una chiamata costa solo l’elettricità.
Entrambi i livelli si comportano in modo identico dal punto di vista di chi chiama. Arrivare a questo risultato è stata la parte interessante, ed ecco cosa abbiamo imparato.
Cosa c’è effettivamente nel ciclo
Un agente vocale non è un chatbot con un microfono attaccato. Ogni turno di conversazione è una catena, e ogni anello aggiunge un ritardo percepibile dall’orecchio umano.
L’audio arriva tramite WebRTC in una stanza LiveKit. Il rilevamento dell’attività vocale (noi usiamo Silero) determina quando il chiamante ha effettivamente iniziato e smesso di parlare. L’audio bufferizzato viene inviato a Faster-Whisper e ritorna sotto forma di trascrizione. Quel turno viene scritto su Postgres, poi il contesto della chat e la cronologia vengono inviati al modello linguistico, che sul nostro livello self-hosted è Qwen3-8B gestito da vLLM. I token tornano in streaming, vengono normalizzati e aggregati in frasi complete, e solo allora raggiungono XTTS-v2, che li converte in frame audio che tornano indietro tramite WebRTC.
Quattro modelli, una scrittura sul database e un giro completo, il tutto entro la pausa che un chiamante è disposto a tollerare prima di dire «pronto?» nel silenzio.
Eseguire quella catena localmente non è la parte difficile. Eseguirla localmente alla velocità di una conversazione, su hardware che un’azienda di medie dimensioni acquisterebbe effettivamente, è la vera sfida ingegneristica.
Lezione numero uno: l’interruzione è una caratteristica del prodotto, non un caso limite
I chiamanti parlano sopra l’operatore. Lo fanno costantemente, e lo fanno nel momento stesso in cui ne hanno sentito abbastanza, il che di solito avviene dopo circa sei parole di una risposta di venti. Un operatore che continua a parlare sembra malfunzionante in un modo da cui è difficile riprendersi, perché l’istinto umano è quello di alzare la voce, e a quel punto entrambe le parti parlano contemporaneamente in un sistema che non ascolta nessuna delle due.
Interrompere l’audio in uscita è la metà più ovvia. La metà che è facile trascurare è la trascrizione. Se la registrazione dell’operatore contiene ancora la frase completa che intendeva dire, la conversazione prosegue come se fosse una chiamata mai avvenuta. Se si pone una domanda di approfondimento su «la seconda opzione che hai menzionato», l’operatore risponderà con sicurezza a qualcosa che il chiamante non ha mai sentito.
Quindi, quando viene rilevato il parlato, interrompiamo l’audio e poi troncamo il turno memorizzato dell’agente a ciò che è stato effettivamente detto ad alta voce. La conversazione prosegue a partire dalla chiamata che il chiamante ha effettivamente vissuto, non da quella che il sistema aveva pianificato.
Lezione numero due: non è possibile eliminare la latenza, quindi bisogna colmarla
Quando una domanda richiede un dato concreto, l’agente effettua una ricerca nei documenti indicizzati prima di rispondere. Tale ricerca richiede un tempo sufficientemente lungo da essere percepita come una battuta mancante. Il silenzio durante una telefonata non è neutro. È allarmante.
Inseriamo un breve riempitivo naturale dopo circa mezzo secondo e lo annulliamo se il recupero dei dati avviene prima. Si tratta di un piccolo accorgimento con un effetto enorme: concede al recupero il tempo necessario, e quel tempo non viene percepito dal chiamante come silenzio di silenzio.
Questo aspetto è ancora più importante nel livello self-hosted, non meno. Un modello locale su una singola GPU presenta caratteristiche di latenza diverse rispetto all’API di un hyperscaler, e non sono uniformemente peggiori. Sono distribuite in modo diverso. Progettare la conversazione in modo da tollerare una latenza variabile ci ha permesso di cambiare il luogo in cui i modelli vengono eseguiti senza alterare la percezione dell’agente.
Lezione tre: il testo scritto non va letto ad alta voce
Importi monetari, date espresse in cifre, orari, acronimi, codici prodotto. Tutto ciò va bene sullo schermo, ma non nella voce. Se si fornisce a un modello vocale «1.250,00 entro il 15/03», si sentirà qualcosa che nessuna persona ha mai detto ad alta voce.
Abbiamo inserito un livello di normalizzazione tra il modello linguistico e il modello vocale che riscrive importi, date, orari e abbreviazioni nella loro forma parlata, in base alla lingua, prima che raggiungano la sintesi. Vocale funziona in sei lingue e questo livello è specifico per ogni lingua perché le regole differiscono realmente. Non esiste una scorciatoia che consenta di scriverlo una volta per l’inglese e poi tradurlo.
Questa è la componente meno affascinante del sistema e una di quelle che influisce maggiormente sul fatto che l’agente sembri una persona o un menu telefonico automatizzato.
Lezione quattro: la VRAM è il limite massimo, non la potenza di calcolo
Ecco l’aspetto che ci ha sorpreso di più e che cambia maggiormente il modo in cui si dimensiona l’hardware.
Una sessione vocale in tempo reale mantiene i propri modelli nella memoria video per tutta la durata della chiamata. La concorrenza è quindi limitata dalla VRAM, non dalla larghezza di banda grezza. È possibile avere una scheda con potenza di calcolo in eccesso che non è in grado di gestire un’altra chiamata, poiché non c’è spazio dove collocare i modelli.
Peggio ancora, se si lascia che il framework raggruppi le GPU per impostazione predefinita, le attività di riconoscimento vocale e di elaborazione del linguaggio finiscono sulla stessa scheda e si ostacolano a vicenda. Il sintomo non è un errore. È una conversazione che rallenta sotto carico in un modo che non è attribuibile a un singolo componente. Ora pianifichiamo le sessioni per scheda e distribuiamo il carico di lavoro tra le schede in modo esplicito.
Se state pianificando una distribuzione self-hosted, calcolate innanzitutto le chiamate simultanee in base alla memoria video. Tutto il resto deriva da quel numero.
Cosa non cambia
Il principio di base non cambia. Su entrambi i livelli l’agente risponde attingendo dai documenti caricati dall’azienda piuttosto che dalla memoria del modello: una domanda che richiede un fatto innesca una ricerca e la risposta viene assemblata in base ai risultati ottenuti. Quando non viene trovato nulla di pertinente, dirlo e offrirsi di aprire un ticket è la risposta corretta, ed è quella che l’agente fornisce. Un modello locale più piccolo non è un pretesto per fornire risposte errate, poiché il modello non è la fonte di verità in primo luogo. Lo è il recupero delle informazioni.
Anche il passaggio di consegne rimane invariato. Quando l’agente non è in grado di aiutare, raccoglie l’oggetto, il contatto e la priorità mentre il chiamante è ancora in linea, crea il ticket e allega la trascrizione.
Questo è il punto fondamentale nel costruire entrambi i livelli sulla base di un unico comportamento. Passare da uno all’altro è una questione di configurazione, non di ricostruzione.
Quindi quale dovreste utilizzare?
Onestamente: iniziate con la versione in hosting.
Il livello in hosting è il modo più veloce per scoprire se un operatore sulla vostra linea sia effettivamente utile, e questa è una questione di prodotto, non di infrastruttura. La nostra console l’ha stimato a circa sei centesimi al minuto di chiamata. Per un’azienda che riceve poche decine di chiamate al giorno, questa non è la voce di costo da ottimizzare per prima.
L’autohosting si ripaga su due soglie, che sono diverse tra loro.
La prima è il volume. Il costo misurato varia in base all’adozione, mentre il costo dell’hardware no; esiste quindi un punto di svolta in cui la GPU risulta semplicemente più economica. La posizione di quel punto dipende dal vostro volume di chiamate, e dovreste misurarlo anziché darlo per scontato. I contatori Vocale misurano la spesa per modello e per organizzazione proprio per questo motivo: la scelta tra un’API e una scheda dovrebbe essere una decisione basata su un dato numerico, non una discussione.
La seconda soglia non ha nulla a che vedere con il denaro. Alcune aziende non possono inviare l’audio delle chiamate, le trascrizioni o i documenti interni a terzi, a causa di un’autorità di regolamentazione, di un contratto con un cliente o di una politica aziendale. Per loro, il livello locale non rappresenta un’ottimizzazione. È l’unica versione di questo prodotto che è autorizzata ad esistere, e nessun prezzo al minuto rende accettabile il livello ospitato.
Vale la pena distinguere queste due soglie quando si valuta qualsiasi fornitore di IA vocale. Una piattaforma che offre solo inferenza a consumo ha silenziosamente deciso che la seconda soglia non si applica al vostro caso.
La versione breve
L’inferenza locale su una linea di assistenza è oggi praticabile. I modelli sono sufficientemente validi e gli strumenti (vLLM, Faster-Whisper, XTTS-v2, LiveKit) sono abbastanza maturi da rendere la pipeline un elemento non rischioso.
I rischi sono quelli che nessuno mostra nelle demo: essere interrotti, sembrare presenti mentre si riflette, leggere i numeri ad alta voce come un essere umano e sapere quante conversazioni possono effettivamente stare su una scheda. Se si gestiscono correttamente questi aspetti, la scelta tra un’API ospitata e la propria GPU diventa ciò che avrebbe dovuto essere fin dall’inizio, ovvero una voce di bilancio piuttosto che un limite a ciò che è consentito realizzare.
- Local LLM
- Voice AI
- Self-hosted
- RAG
- vLLM
- LiveKit
- Support automation