Todos los artículos

IA8 min de lectura

Lo que aprendimos al conectar un LLM local a una línea telefónica

La IA de voz gestionada se factura por minutos, por lo que la recompensa para un agente que funciona es una factura más elevada. Desarrollar Vocale para que funcione tanto en una API alojada como en una GPU privada nos ha enseñado cuatro cosas sobre lo que realmente resulta complicado cuando los modelos se trasladan a nuestras propias instalaciones.

Diagrama de secuencia de un turno conversacional en Vocale: El audio de WebRTC llega a un servidor LiveKit y a un agente; la detección de actividad vocal de Silero identifica el habla; Faster-Whisper devuelve una transcripción; el turno se guarda en PostgreSQL; el contexto del chat se envía a Qwen3-8B, gestionado por vLLM; los tokens transmitidos se normalizan y se agrupan en frases; XTTS-v2 las reproduce como audio, y el audio se devuelve a la persona que llama.

Todas las plataformas gestionadas de IA de voz facturan por minutos. Eso parece razonable hasta que la pones en una línea de atención al cliente y empieza a funcionar, porque la recompensa para un buen agente es responder a más llamadas, y la recompensa por responder a más llamadas es una factura más elevada. Cuanto mejor funciona, más cuesta. En una línea de atención al cliente, que existe precisamente para absorber el volumen de llamadas, ese es un incentivo erróneo por el que optar.

Creamos Vocale para atender la línea telefónica de una empresa: descuelga al primer tono, responde basándose en los manuales y políticas de la propia empresa, y abre un ticket de asistencia cuando la respuesta sincera es que alguien tiene que ocuparse del asunto. Al principio tomamos una decisión que marcó el rumbo de todo lo que vino después. La plataforma ofrece dos motores detrás de un mismo producto. En el nivel alojado, el reconocimiento de voz, el razonamiento y la síntesis de voz provienen de una API de terceros y se cobra por cada minuto. En el nivel autohospedado, los tres se ejecutan en una GPU controlada por la empresa, ningún archivo de audio o documento sale del edificio y una llamada solo cuesta electricidad.

Ambos niveles se comportan de forma idéntica desde el punto de vista de la persona que llama. Lograrlo fue lo interesante, y esto es lo que aprendimos.

¿Qué hay realmente en el bucle?

Un agente de voz no es un chatbot al que se le ha acoplado un micrófono. Cada turno conversacional es una cadena, y cada eslabón añade un retraso que un ser humano puede percibir.

El audio llega a través de WebRTC a una sala de LiveKit. La detección de actividad de voz (utilizamos Silero) determina cuándo la persona que llama ha empezado y dejado de hablar realmente. El audio almacenado en el búfer se envía a Faster-Whisper y vuelve en forma de transcripción. Ese turno se escribe en Postgres; a continuación, el contexto y el historial del chat se envían al modelo de lenguaje, que en nuestro nivel autohospedado es Qwen3-8B, gestionado por vLLM. Los tokens se transmiten de vuelta, se normalizan y se agrupan en frases completas, y solo entonces llegan a XTTS-v2, que los convierte en tramas de audio que se envían de vuelta a través de WebRTC.

Cuatro modelos, una escritura en la base de datos y un viaje de ida y vuelta, todo ello dentro de la pausa que una persona que llama está dispuesta a tolerar antes de decir «¿hola?» en medio del silencio.

Ejecutar esa cadena localmente no es lo difícil. Ejecutarla localmente a velocidad conversacional, en el hardware que una empresa mediana compraría realmente, es donde reside el reto de ingeniería.

Lección uno: la interrupción es una característica del producto, no un caso excepcional

Las personas que llaman hablan al mismo tiempo que el agente. Lo hacen constantemente, y lo hacen en el momento en que han oído lo suficiente, lo que suele ocurrir tras unas seis palabras de una respuesta de veinte. Un agente que sigue hablando suena como si algo fallara, de una forma de la que es difícil recuperarse, porque el instinto humano es hablar más alto, y ahora ambas partes están hablando a la vez en un sistema que no escucha a ninguna de las dos.

Cortar el audio de salida es la mitad obvia. La mitad que es fácil pasar por alto es la transcripción. Si el propio registro del agente sigue conteniendo la frase completa que pretendía decir, la conversación continúa a partir de una llamada que nunca tuvo lugar. Haz una pregunta de seguimiento sobre «la segunda opción que mencionaste» y el agente responderá con seguridad sobre algo que la persona que llama nunca ha oído.

Por eso, cuando se detecta voz, detenemos el audio y luego recortamos el turno almacenado del agente a lo que realmente se dijo en voz alta. La conversación continúa a partir de la llamada que experimentó la persona que llama, no de la que el sistema había planeado.

Lección dos: no se puede eliminar la latencia, así que hay que rellenarla

Cuando una pregunta requiere un dato concreto, el agente busca en los documentos indexados antes de responder. Esa búsqueda tarda lo suficiente como para que se perciba como una línea perdida. El silencio en una llamada telefónica no es neutro. Resulta alarmante.

Insertamos un relleno breve y natural al cabo de medio segundo aproximadamente, y lo cancelamos si la búsqueda devuelve un resultado antes. Se trata de un pequeño detalle con un efecto desmesurado: le da a la búsqueda el tiempo que necesita, y ni un solo instante de ese tiempo se percibe para la persona que llama como silencio incómodo.

Esto es aún más importante en el nivel de autoalojamiento, no menos. Un modelo local en una sola GPU tiene características de latencia diferentes a las de la API de un hiperescalador, y no son uniformemente peores. Simplemente se distribuyen de forma diferente. Diseñar la conversación para tolerar una latencia variable significaba que podíamos cambiar el lugar donde se ejecutan los modelos sin alterar la percepción del agente.

Lección tres: el texto escrito no se lee en voz alta

Cantidades de dinero, fechas expresadas en dígitos, horas, acrónimos, códigos de producto. Todo ello está bien en una pantalla, pero no en una voz. Si le das a un modelo de voz «1.250,00 a 15/03», oirás algo que ninguna persona ha dicho nunca en voz alta.

Incorporamos una capa de normalización entre el modelo lingüístico y el modelo de voz que reescribe las cantidades, fechas, horas y abreviaturas a su forma hablada, según el idioma, antes de que lleguen a la síntesis. Vocale funciona en seis idiomas, y esta capa es específica para cada idioma porque las reglas difieren realmente. No hay ningún atajo que permita escribirlo una vez en inglés y traducirlo.

Este es el componente menos glamuroso del sistema y uno de los que más influye en que el agente suene como una persona o como un menú telefónico.

Lección cuatro: la VRAM es el límite, no la potencia de cálculo

Esta es la que más nos sorprendió y la que más cambia la forma de dimensionar el hardware.

Una sesión de voz en directo mantiene sus modelos en la memoria de vídeo mientras dura la llamada. Por lo tanto, la concurrencia está limitada por la VRAM, no por el rendimiento bruto. Puedes tener una tarjeta con capacidad de cálculo de sobra que no pueda aceptar otra llamada, porque no hay sitio donde almacenar los modelos.

Peor aún, si dejas que el marco de trabajo agrupe las GPU de forma predeterminada, las tareas de voz y lenguaje acabarán en la misma tarjeta y se agotarán mutuamente. El síntoma no es un error. Se trata de una conversación que se ralentiza bajo carga de una forma que no se puede atribuir a ningún componente en concreto. Ahora asignamos sesiones por tarjeta y distribuimos la carga de trabajo entre las tarjetas de forma explícita.

Si estás planeando una implementación autohospedada, calcula primero el número de llamadas simultáneas en función de la memoria de vídeo. Todo lo demás se deriva de esa cifra.

Lo que no cambia

El funcionamiento básico no cambia. En ambos niveles, el agente responde a partir de los documentos subidos por la empresa, en lugar de a partir de la memoria del modelo: una pregunta que requiere un dato concreto desencadena una búsqueda, y la respuesta se construye a partir de los resultados obtenidos. Cuando no se encuentra nada relevante, indicar que así es y ofrecer abrir un ticket es la respuesta correcta, y es la que da. Un modelo local más pequeño no es una licencia para «alucinar» más, porque el modelo no es la fuente de verdad en primer lugar. La recuperación sí lo es.

El traspaso tampoco cambia. Cuando el agente no puede ayudar, recoge el asunto, el contacto y la prioridad mientras la persona que llama sigue en línea, crea el ticket y adjunta la transcripción.

Ese es el objetivo de construir ambos niveles en función de un mismo comportamiento. Pasar de uno a otro es una cuestión de configuración, no de reconstruir el sistema.

Entonces, ¿cuál deberías utilizar?

Sinceramente: empieza con el modelo alojado.

El nivel alojado es la forma más rápida de averiguar si un agente en tu línea resulta útil en absoluto, y eso es una cuestión de producto, no de infraestructura. Nuestra propia consola lo calculó en unos seis céntimos por minuto de llamada. Para una empresa que recibe unas pocas docenas de llamadas al día, esa no es la partida que merezca la pena optimizar en primer lugar.

El autohospedaje se amortiza a partir de dos umbrales, y son umbrales diferentes.

El primero es el volumen. El coste medido aumenta con el uso, pero el coste del hardware no, por lo que hay un punto de cruce en el que la GPU resulta simplemente más barata. La ubicación de ese punto depende de tu volumen de llamadas, y deberías medirlo en lugar de darlo por sentado. Vocale calcula el gasto por modelo y por organización precisamente por esta razón: la elección entre una API y una tarjeta debería ser una decisión basada en cifras, no en argumentos.

El segundo umbral no tiene nada que ver con el dinero. Algunas empresas no pueden enviar el audio de las llamadas, las transcripciones o los documentos internos a terceros, ya sea por requisitos regulatorios, por un contrato con el cliente o por una política interna. Para ellas, el nivel local no supone una optimización. Es la única versión de este producto que se permite utilizar, y ningún precio por minuto hace que el nivel alojado sea aceptable.

Merece la pena distinguir estos dos umbrales a la hora de evaluar a cualquier proveedor de IA de voz. Una plataforma que solo ofrece inferencia medida ha decidido, de forma tácita, que el segundo umbral no se aplica a tu caso.

La versión resumida

La inferencia local en una línea de atención al cliente es viable hoy en día. Los modelos son lo suficientemente buenos y las herramientas (vLLM, Faster-Whisper, XTTS-v2, LiveKit) están lo bastante maduras como para que el proceso no suponga un riesgo.

Los riesgos son aquellos que nadie muestra en las demostraciones: que te interrumpan, que se note que estás pensando, leer números en voz alta como un humano y saber cuántas conversaciones caben realmente en una tarjeta. Si se resuelven bien estos aspectos, la elección entre una API alojada y tu propia GPU se convierte en lo que debería haber sido desde el principio: una partida presupuestaria en lugar de una limitación a lo que se te permite desarrollar.

  • Local LLM
  • Voice AI
  • Self-hosted
  • RAG
  • vLLM
  • LiveKit
  • Support automation