Relay

En vivo

Proyecto personal explorando voz con IA en tiempo real. El caso de uso es un recepcionista de clínica; el punto real fue alcanzar un presupuesto de latencia percibida sub-segundo con instrumentación completa por etapa.

Rol
Solo — arquitectura, pipeline de voz, frontend, despliegue
Período
nov 2025 → Actual
Stack
  • Next.js 16
  • TypeScript
  • LiveKit Cloud
  • Twilio
  • Deepgram
  • Claude Haiku 4.5
  • Cartesia Sonic-3
  • Cal.com
  • Inngest
  • Supabase
  • PostgreSQL
  • Prisma
  • Tailwind v4

Qué hace

Un administrador de clínica se registra, crea una organización y configura un agente — prompt de persona, voz, horario comercial, base de FAQ. Apunta un número Twilio al SIP trunk y listo.

Llega un cliente. Aproximadamente medio segundo después de terminar de hablar, el agente responde con voz natural. Mientras la llamada está en curso:

  1. Un waveform en vivo pulsa con el audio entrante.
  2. La transcripción se llena token-por-token con etiquetas de quien habla en cada turn.
  3. Un medidor de latencia muestra STT, LLM TTFT, TTS TTFA y end-to-end p95 en tiempo real, con cada etapa en rojo cuando excede el presupuesto.
  4. Cualquier tool que el agente invoque — check_availability, lookup_kb, book_appointment, transfer_to_human — aparece en una timeline inline con input, output, duración.

El operador puede tomar la llamada desde el dashboard en cualquier momento.

Cuando la llamada cuelga, un job Inngest baja la grabación, le pide a Claude Sonnet 4.6 un resumen estructurado, clasifica el resultado (SCHEDULED, QUALIFIED, TRANSFERRED, NOT_QUALIFIED, NO_ANSWER), puntúa el sentimiento y extrae temas. La página de detalle muestra la grabación en un player scrub-able con la transcripción resaltando el segmento actualmente hablado.

El mismo dashboard incluye campañas outbound (subida CSV, respeto del horario comercial, retries con cooldown), una página de analytics (volumen, conversión, latencia p95, heatmap día-de-la-semana × hora) y una integración Cal.com para agendar citas en medio de la llamada.

Por qué lo construí

Quería construir la experiencia de IA de cara al usuario más difícil que se me ocurriera — voz — en calidad de producción, en un stack donde el presupuesto de latencia es la feature headline. Los negocios de servicios (clínicas, consultórios) son el usuario canónico correcto porque tienen volumen real, ingresos reales en juego por llamadas perdidas y no se interesan por la novedad por la novedad.

Cómo funciona

Pipeline de voz en tiempo real

  • Twilio termina la llamada PSTN y la bridgea a LiveKit Cloud vía SIP.
  • Un worker Node de larga duración entra a la sala LiveKit y corre el loop de la conversación. El worker se despliega aparte del app Next.js — las funciones Vercel no pueden mantener un websocket abierto por 10 minutos.
  • Deepgram maneja STT, VAD y turn-detection en una API streaming. Los eventos end-of-turn disparan el LLM, eliminando la varianza de 150–300ms de pipelines separados con VAD + silence-timer.
  • Claude Haiku 4.5 conduce la conversación. Los tokens streamados se dividen sentence-by-sentence y se entregan a Cartesia Sonic-3 para que el audio empiece a sonar antes de que el LLM termine de generar.
  • Tool use es nativo en la llamada del Anthropic SDK. Cuatro tools disponibles durante la llamada: check_availability, book_appointment, lookup_kb, transfer_to_human. Cada tool se valida con Zod, se graba con input/output/duración, y el LLM continúa con el resultado de la tool como un turn normal.
  • Interrupción / barge-in adaptativos cancelan la generación LLM en vuelo y vacían la cola de audio TTS en el momento en que el usuario empieza a hablar.
  • La latencia se instrumenta por etapa y se escribe a la base para el medidor en vivo y el dashboard de analytics.

Multi-tenant B2B

Tres capas de aislamiento — alcance de fila en Postgres, guards de capa de aplicación en toda server action y credenciales de sub-cuenta Twilio por organización. El worker LiveKit lee la organización de los headers SIP de modo que una ruta mal configurada nunca puede bridgear a la sala de otro tenant.

Estado

Demo en vivo en relay-five-peach.vercel.app. Loom walkthrough y case study completo a continuación.

Preguntas

¿Qué es Relay?

Relay es un recepcionista de voz con IA multi-tenant para negocios de servicios como clínicas. Atiende llamadas inbound 24/7, califica leads, agenda citas vía Cal.com y transfiere a humano cuando es necesario. Los operadores ven cada llamada en vivo en el dashboard con waveform, transcripción en streaming y medidor de latencia por etapa.

¿Cuál es el presupuesto de latencia de Relay?

El objetivo es p95 ≤ 900ms de respuesta percibida por el usuario, medido desde el fin del habla del usuario hasta el inicio del audio del agente. Cada etapa se instrumenta por separado — STT finalize, LLM TTFT, LLM total, TTS TTFA, tool total, end-to-end — y se expone como un medidor en vivo coloreado en rojo cuando cualquier etapa excede su presupuesto.

¿Por qué LiveKit + Deepgram + Cartesia en lugar de un solo proveedor?

Cada etapa es best-of-breed y reemplazable individualmente. LiveKit maneja la terminación SIP desde Twilio y la sala de audio. El STT streaming de Deepgram empaqueta VAD y turn detection en una sola API, eliminando la varianza de 150–300ms de pipelines separados con VAD + silence-timer. El Sonic-3 de Cartesia es TTS genuinamente faster-than-realtime, lo que hace posible el presupuesto sub-segundo.

¿Cómo funciona el aislamiento multi-tenant en Relay?

Tres capas — alcance de fila por organizationId en Postgres, guards de capa de aplicación en toda server action y credenciales de sub-cuenta Twilio por organización. El worker LiveKit lee la organización de los headers SIP de modo que una ruta mal configurada nunca puede bridgear a la sala de otro tenant.

← Todos los proyectos