28 may 2025
·
Roberto Morales
¿Qué pasaría si pudieras llamar a la inteligencia artificial por teléfono?
En esta serie, profundizamos en cómo estamos construyendo herramientas de IA en tiempo real. Hoy, estamos convirtiendo una simple llamada telefónica en una conversación real con un asistente de IA sin pantallas, sin clics, solo con voz.
Hablando con ChatGPT por teléfono: cómo creamos un asistente de IA en tiempo real con GPT-4o, Whisper y ElevenLabs
Imagina preguntar a ChatGPT cualquier cosa que no sea por escrito, sino simplemente haciendo una llamada telefónica. Sin navegador, sin pantalla. Solo tu voz… y una respuesta en tiempo real. En Borah Digital, lo hicimos posible.
Construimos un asistente de IA basado en teléfono que te permite tener conversaciones fluidas y naturales con baja latencia, simplemente llamando a un número de teléfono (usando Twilio).
Sí: llamas y la IA responde.
Cómo funciona. Arquitectura técnica
Esta experiencia fluida se alimenta de un sistema bellamente orquestado de herramientas y lógica:
Twilio recibe la llamada que hacemos desde nuestro teléfono personal
Un servidor Node recopila los fotogramas de audio hasta que detecta 2 segundos de silencio
Convertimos el audio del formato u-law 8kHz de Twilio a PCM 16kHz, para que OpenAI Whisper pueda entenderlo
Whisper transcribe ese audio a texto, que se envía a un LLM para su interpretación.
Usando el LLM, generamos una respuesta a nuestra pregunta y la enviamos a ElevenLabs.
ElevenLabs convierte la respuesta del LLM en habla natural, la convierte de nuevo a formato u-law 8kHz y la envía a Twilio a través de un WebSocket.
El resultado: una conversación en tiempo real con una IA que se siente… real. Suena interesante, ¿no? Vamos a profundizar en los detalles.
Transformaciones de u-law 8kHz a PCM 16kHz:
Twilio nos da audio en 8kHz 8-bit u-law, que es perfecto para telecomunicaciones pero terrible para modelos de IA.
Así que, convertirlo a 16kHz PCM es esencial.
Para esto, usamos wavefile, una biblioteca que facilita trabajar con archivos de audio:
Utilizamos PCM 16kHz porque la mayoría de los modelos de ASR modernos funcionan realmente bien con esta configuración. Aumentar la frecuencia de muestreo no inventa nueva información, pero nos ayuda a evitar suposiciones extrañas hechas por el re-muestreador interno de Whisper. (Intentamos ejecutar todo en 8kHz u-law, pero Whisper no pudo entender lo que se decía por teléfono y por lo tanto no pudo transcribirlo.)
Al devolver la respuesta, ElevenLabs ya nos proporciona una salida u-law 8kHz optimizada para Twilio, por lo que no hay necesidad de re-codificación.
Detección de voz, energía y silencio:
Un desafío interesante fue evitar cortes en medio de la frase donde la voz del usuario se interrumpiera y el LLM perdiera contexto.
Para resolver esto, aplicamos un detector de actividad vocal ultraligero (VAD) basado en niveles de energía:
Si el valor devuelto por calculateSimpleEnergy
, que nos da el nivel de energía aproximadamente cada 20ms, es mayor que el umbral establecido en la constante SILENCE_THRESHOLD
, marcamos el estado como HABLANDO. De lo contrario, se interpretará como ruido ambiental y se marcará como SILENCIO, para ser ignorado.
Una vez que la energía cae por debajo de SILENCE_THRESHOLD
, comenzamos a contar el silencio.
Si este silencio dura más que el tiempo establecido en SILENCE_DURATION_MS
, enviamos el búfer.
Además, invertimos los bits de esta manera: audioBuffer[i] ^ 0xFF
, ya que los flujos de medios de Twilio los entregan en reversa. Por otro lado, es cierto que sample < 128 ? sample * 2 : (sample - 128) * 4
no es una decodificación precisa, pero es lo suficientemente buena por ahora.
Como primera versión, este VAD es funcional (con SNR estable a 8kHz), aunque para entornos más ruidosos, podríamos necesitar soluciones más avanzadas como WebRTC-VAD, que puede detectar si hay voz en un segmento de audio.
Enviar datos con procesos asíncronos:
Utilizar lógica asíncrona fue esencial en este proyecto debido a la naturaleza en tiempo real de las llamadas telefónicas (transcripción, razonamiento, síntesis…). Para manejar esto, implementamos la siguiente solución:
Además de esto, toda la lógica se ejecuta en paralelo gracias a un processing
bandera para cada conexión.
Mientras se genera la respuesta, seguimos recibiendo y desechando audio entrante, así que la presión de retroceso es efectivamente cero. En términos generales, así es como utilizamos esta bandera:
Resultados:
La latencia de la conversación es de alrededor de un segundo, prácticamente inapreciable para el usuario.
El umbral de energía simple combinado con un tamaño de búfer variable basado en ese valor funciona sorprendentemente bien.
En Borah, creemos que la voz sigue siendo la interfaz más natural.
Con solo unas pocas líneas de código, procesamiento de señales e IA, hemos convertido un número de teléfono en un asistente virtual listo para convertirse en tu próximo "empleado" de servicio al cliente.
¿Te gustaría implementar esto en tu negocio?
Escríbenos, nos encantaría dar voz a tus ideas.