Saltar al contenido
megapromotingVamos a hablar
Productos Kallina

Agentes de voz con IA Plataforma

Una buena conversación continúa con una acción.

Construimos agentes que reciben e inician llamadas, usan la información del negocio y trabajan con tus sistemas. Desde la primera pregunta hasta una solicitud completa, una confirmación o la transferencia a un colega.

EscuchaVerificaAccionaVOZ + CONTEXTO + ACCIÓN
Cómo funciona Kallina

Kallina

De la información al trabajo hecho.

01

Escucha

Entiende la solicitud en el contexto de la conversación y de las reglas del negocio.

02

Verifica

Consulta la base de conocimientos y las integraciones autorizadas antes de responder.

03

Acciona

Completa los datos, ejecuta la acción permitida o transfiere la conversación a una persona.

Dónde resulta útil.

Recepción y soporte

Preguntas frecuentes, recepción de solicitudes y seguimiento a las personas que pidieron ser contactadas.

Pedidos y entregas

Confirmaciones y coordinación, con la información del sistema de pedidos conectado.

Calificación y programaciones

Recoge los detalles necesarios. El acceso al calendario y la reserva se establecen para cada integración.

Los escenarios, el número de teléfono, los idiomas y las acciones se configuran para cada implementación. El equipo mantiene la posibilidad de retomar la conversación.

Kallina en detalle

Qué puedes hacer con este proyecto.

Kallina es la plataforma sobre la que construimos agentes que hablan por teléfono y en la página web. Un agente tiene un rol escrito, una base de conocimientos aprobada, un conjunto de herramientas que puede invocar y un límite más allá del cual entrega la conversación a una persona. La conversación no termina en el transcript: la llamada tiene duración, coste por proveedor, grabación y análisis, todo vinculado a la cuenta de la empresa.

El motor de voz no es uno solo. En la configuración del agente eliges entre ElevenLabs Conversational AI, OpenAI Realtime, Gemini Live o «auto», en cuyo caso Kallina elige el proveedor según el idioma, la carga y la disponibilidad. Encima de eso eliges por separado el cerebro textual — el catálogo en el código tiene 78 entradas de OpenAI, Google, Anthropic, xAI y ElevenLabs, cada una con la latencia y el coste por minuto mostrados en la interfaz, para que la elección sea informada, no de oídas.

La telefonía es nuestra, no alquilada al proveedor de voz. Las llamadas pasan por un Asterisk propio, con enrutamiento por horario laboral y huso horario, horario nocturno (por ejemplo 22:00 → 06:00) y coincidencia por prioridad: el encabezado SIP Diversion, luego el número Kallina, luego la regla de reserva. Para OpenAI Realtime existe un puente AudioSocket que convierte el códec en ambos sentidos, g711_ulaw ↔ PCM16.

01

Tres proveedores de voz más una posición «auto»

En `AGENT_PROVIDERS` hay cuatro opciones: `elevenlabs` (ConvAI), `openai-realtime`, `gemini-live` y `auto`. Para text-to-speech en otros idiomas que no sean inglés, el predeterminado es `eleven_flash_v2_5` — 32 idiomas, aproximadamente 75 ms de latencia; la alternativa de mejor calidad, `eleven_turbo_v2_5`, cuesta aproximadamente 250 ms. La elección no está oculta en el código, es un campo en la configuración del agente.

02

Catálogo de modelos con latencia y coste mostrados

78 modelos en `LLM_MODELS`, agrupados por proveedor en la interfaz junto con la latencia medida y el coste por minuto — desde `gpt-5-nano` con aproximadamente 806 ms y unos 0,0004 $/min, hasta `claude-sonnet-4-6` con aproximadamente 1,55 s y unos 0,0225 $/min. Un cliente que pregunta «¿por qué responde lento?» recibe una respuesta con cifras, no una opinión.

03

Telefonía propia en Asterisk

La redirección de llamadas se configura por horas de trabajo y zona horaria, con soporte para horario nocturno y coincidencia por prioridad (cabecera SIP Diversion → número Kallina → regla de reserva). El puente `openai-realtime-bridge` hace la conversión AudioSocket entre g711_ulaw y PCM16 para el flujo de audio bidireccional.

04

Embed de voz en una sola línea, sin id de agente en la página

`<script src="https://app.kallina.info/embed.js" data-widget="WIDGET_ID"></script>`. La página nunca sabe qué agente responde y no guarda ninguna clave de proveedor: pide a Kallina una sesión, y Kallina devuelve una URL firmada de corta duración. También existe el modo `data-mode="inline"`, en el que el embed no dibuja absolutamente nada y la página crea su propia interfaz sobre la API `start()` / `stop()` / `toggle()` / `on(event, fn)`.

05

Campañas de llamadas salientes

Llamadas por lotes con 1–10 llamadas simultáneas, importación de contactos desde CSV, lógica de reintento, seguimiento en tiempo real con pausa, reanudación y parada, además de seguimiento por SMS.

06

Idiomas

La configuración del agente admite 32 idiomas (`LANGUAGES`), el mapa completo de idiomas de la plataforma tiene 41 entradas, y el panel de administración está traducido a 20 (`src/i18n/locales`). El rumano es el idioma predeterminado en `DEFAULT_VALUES`.

Datos y funcionamiento

Qué entra en el sistema. Qué hay que verificar.

Dónde están los datos
PostgreSQL mediante Supabase, con Row Level Security y pg_cron; 559 migraciones versionadas. La lógica del servidor son funciones edge Deno — 472 en el repo en la fecha de la verificación.
Lo que nunca llega a la página del cliente
La clave del proveedor de voz y el identificador del agente. El embed solicita `POST /functions/v1/widget-voice-session` con `widget_id` — la clave pública de `chat_widget_configs.widget_id`, no el id interno de la fila — y el servidor solicita por sí mismo a ElevenLabs una URL firmada, mediante `convai/conversation/get_signed_url`, y la devuelve. La versión antigua, que colocaba `agentId` directamente en HTML, eludía por completo Kallina.
Base de conocimientos
Documentos cargados en la plataforma, sincronizados con el RAG de ElevenLabs. Encima de ellos se añaden barreras de conversación, esquemas de recopilación de datos y criterios de evaluación del éxito de la llamada, definidos por agente.
Consumo medido antes, no después
La tabla `usage_events` mantiene el consumo desglosado por proveedor y por agente. Antes de cualquier acción que cuesta, la función `check-can-use` verifica el crédito — la puerta está antes de la llamada, no la factura de fin de mes.

De la exploración a la implementación

Cómo preparamos un proyecto con Kallina.

01

Elegimos un solo recorrido y le escribimos los límites

Un escenario con entrada clara y salida clara — llamada recibida en recepción, confirmación de pedido, campaña de llamadas. Escribimos explícitamente lo que el agente no tiene permiso de hacer y por qué vía entrega la conversación a una persona.

02

Conectamos el número y verificamos en ambos sentidos

El número entra en el trunk SIP de nuestro Asterisk. Las llamadas recibidas y las salientes se prueban por separado, porque pueden romperse por separado: una restricción del operador en las llamadas salientes deja las entradas funcionando perfectamente.

03

Verificamos la ruta sin consumir minutos

`scripts/verify-voice-path.mjs` recorre exactamente el camino de un navegador — la fila de la configuración, `get-widget-config`, luego `widget-voice-session` — y se detiene en la URL firmada, sin abrir el websocket. Se ejecuta en un solo widget o en todos los que tienen voz activa, con 1–3 en paralelo, y devuelve código de salida, así que puede entrar directamente en un cron.

Preguntas que vale la pena aclarar.

¿Qué motor de voz usa, concretamente?

Eliges entre ElevenLabs Conversational AI, OpenAI Realtime y Gemini Live, o dejas «auto» y Kallina decide según el idioma y la disponibilidad. Para la síntesis de voz en idiomas distintos del inglés, el valor por defecto es el modelo `eleven_flash_v2_5` — 32 idiomas, en torno a 75 ms; si quieres mayor calidad y aceptas más latencia, `eleven_turbo_v2_5` está en torno a 250 ms. Las voces de OpenAI Realtime son diez, y su motor llega hasta `gpt-realtime-2.1`.

¿Cómo se instala en un sitio?

Una línea: `<script src="https://app.kallina.info/embed.js" data-widget="WIDGET_ID"></script>`, cargada como script normal, no como módulo. El archivo se sirve hoy y tiene 13.762 bytes. Si quieres tu propia interfaz, `data-mode="inline"` no dibuja nada y te deja `start()`, `stop()`, `toggle()` y los eventos `state`, `message`, `error`. Atención al host: el archivo está en `app.kallina.info`, no en `kallina.info` — son dos aplicaciones en dos servidores distintos.

¿Se consumen minutos si el visitante rechaza el micrófono?

No. El orden en `embed.js` es: carga el SDK, pide el micrófono con `getUserMedia({audio:true})`, y solo después llama a `widget-voice-session`. Si la persona rechaza el micrófono, la solicitud de sesión ya no se hace en absoluto, así que no se emite ninguna URL firmada y no se consume nada.

¿Puede llamar él primero, no solo responder?

Sí — llamadas en lote, 1–10 simultáneas, contactos desde CSV, reintentos y follow-up por SMS. Pero las llamadas salientes dependen del operador telefónico, no solo de nosotros: en nuestro registro de problemas está documentado un caso en el que la central del operador empezó a devolver `403 Forbidden` en todas las salidas, con nuestra configuración sin cambios y con las llamadas recibidas funcionando con normalidad. Por eso probamos las salidas por separado antes de prometer una campaña.

¿En cuántos idiomas habla y en cuántos se administra?

La configuración del agente admite 32 idiomas, el mapa interno de idiomas tiene 41 entradas, y el panel de administración está traducido a 20. El rumano es el idioma por defecto de los agentes nuevos.

¿Se publica automáticamente en cada cambio de código?

No, y conviene saberlo antes de planificar un lanzamiento. El workflow de GitHub del repo apunta a un proyecto Supabase Cloud que fue eliminado, así que «push en main = publicación» ya no es cierto desde la migración a infraestructura propia. La publicación real se hace por SSH, con copia y reinicio. La consecuencia práctica: un cambio urgente necesita a una persona, no solo un commit.

¿Qué pasa si el agente no sabe la respuesta?

La entrega a una persona forma parte del escenario, no es una excepción. Cada agente tiene límites escritos y una vía de transferencia configurada en telefonía; y en la conversación hay barreras y criterios de evaluación del éxito, precisamente para que un caso fuera del rol se detenga, no se improvise.

Ejemplo ilustrativo

Una llamada recibida de noche, que llega donde debe

Un escenario de uso, sin datos de cliente ni resultados comerciales atribuidos.

Situación inicial

Alguien llama al número de la empresa a las 23:40, fuera del horario de recepción.

Cómo funciona

Asterisk aplica la regla de horario nocturno (por ejemplo 22:00 → 06:00) y hace la coincidencia por prioridad: el encabezado SIP Diversion, luego el número Kallina, luego la regla de respaldo. El agente nocturno responde en el proveedor elegido en la configuración, aclara la solicitud y llama a las herramientas que tiene permiso de usar.

Rezultatul

La llamada queda en el historial con transcripción, grabación de audio, duración y coste desglosado por proveedor. Lo que supera el rol del agente se detiene y se transfiere más adelante, en lugar de improvisarse.

Qué es necesario:El número conectado al trunk SIP de nuestro Asterisk, las llamadas salientes permitidas por el operador si se desea y la devolución de llamada, además de un agente con prompt, base de conocimientos aprobada y límites escritos.

Posibilidades de colaboración

Kallina, en el contexto de tu organización.

Información y recogida de solicitudes

Asistencia vocal sobre información aprobada, con traspaso a un operador y reglas claras sobre la grabación y conservación de las conversaciones.

Empresas privadas

Definimos un piloto en torno a un proceso real: usuarios, datos, integraciones, costes y criterios de aceptación. La ampliación sigue después de evaluar el resultado.

Instituciones y empresas públicas

Establecemos los requisitos de accesibilidad, alojamiento, protección de datos e interoperabilidad. Cualquier conexión con servicios AGE o STISC requiere la validación de la elegibilidad, el acceso y las aprobaciones.

Estos son escenarios de adaptación, no declaraciones sobre contratos o colaboraciones existentes. Las funciones propuestas se confirman en el ámbito de trabajo del proyecto.

Habla de un piloto

Parte de un ecosistema.

¿Qué te gustaría que funcionara mejor?

Cuéntanos tu proceso. Juntos decidimos qué merece la pena construir, qué podemos conectar y cómo verificamos el resultado.

Vamos a hablar