Agentes de VozIVRAgentes de IATutorial

Reemplaza tu Centralita por un Agente de Voz

Marque 1 para ventas es una tabla de ruteo leída en voz alta. Crea un agente de voz que contesta, entiende, resuelve y pasa a una persona cuando corresponde.

Redactado por: Victor VillalobosRevisado por: Jennifer Villalobos26 de julio de 202611 min de lectura
Ver como Markdown

Todo menú telefónico es la misma disculpa. Marque 1 para ventas. Marque 2 para soporte. Marque 3 para volver a escuchar estas opciones.

Es una tabla de ruteo, leída en voz alta, a la velocidad del habla. Quien llama ya sabe lo que quiere. Solo tiene que esperar a que le reciten tu organigrama y después adivinar en qué rama entra alguien como él.

La alternativa no es un menú mejor. Es ningún menú: se contesta el teléfono, la persona dice lo que necesita, y del otro lado algo entiende, resuelve, y pone a un humano cuando de verdad hace falta un humano.

Eso es un agente de voz, y es más o menos una tarde de trabajo.

Lo que te cuesta de verdad la centralita vieja

No el alquiler de la línea. Otras tres cosas.

Llamadas abandonadas. Cada capa de menú pierde gente. Cuelgan y prueban con un competidor, o eligen la rama equivocada y caen con alguien que no los puede ayudar, que es peor porque ahora dos personas perdieron el tiempo.

Ningún registro de lo que la gente quería. Un IVR sabe que marcaron 2. No sabe que estaban preguntando por el reembolso de una orden de marzo. Esa intención es lo más valioso de la llamada y tu central telefónica la tira a la basura cada vez.

No puede hacer nada. Un menú rutea. No puede consultar una reserva, cotizar un precio ni actualizar una dirección. Todo termina en un traspaso a una persona, incluida la mitad de las llamadas que esa persona va a resolver leyendo un campo de una pantalla.

Un agente de voz arregla las tres por la misma razón: es una conversación, así que escucha la intención, y tiene tools, así que puede actuar sobre ella.

Lo que vas a construir

El menú viejoUn agente de voz de Zavu
Marque 1 para ventasQuien llama dice lo que quiere
Un árbol que mantienes en un portalUn prompt en tu repo, con version control
Rutea y se desentiendeConsulta y responde durante la llamada
Transfiere a ciegasTransfiere cuando tu prompt lo dice, al número que definiste
Sabe que marcaron un dígitoTranscripción completa, duración y costo por llamada

El agente no es un producto aparte del que contesta WhatsApp. Es el mismo agente con un bloque voice: mismo prompt, mismo modelo, mismas tools, misma knowledge base.

Antes de empezar

Tres requisitos, y uno tarda un día.

  • Un sender con número de teléfono. Ese número es al que llama la gente.
  • Voice Agents habilitado para tu team. Está en beta y se prende por team, así que los endpoints de voz devuelven 403 hasta que alguien lo activa. Escribe a hi@zavu.dev y pídelo.
  • Balance positivo. Las llamadas se cobran por minuto conectado. Las llamadas entrantes solo se contestan mientras tu balance está sobre cero, que es un modo de falla que conviene conocer antes de que pase un lunes.

Quién hace qué

Tú pones la cuenta, el número y el criterio sobre cuándo debe atender una persona. Tu coding agent escribe y publica el resto.

Tu coding agent
Creas la cuenta de ZavuEncuentra o crea el sender
Corres zavu login y autorizasEscribe defineAgent con el bloque de voz
Pides que habiliten Voice AgentsEscribe las tools que llama durante la llamada
Apruebas comprar un númeroSetea los secrets y deploya
Atiendes la primera llamada de pruebaLee la transcripción y corrige el prompt

La única parte que tipeas

bash
npx skills add zavudev/zavu-skills npx zavudev login

El primer comando instala las skills de Zavu en tu coding agent. Claude Code, Cursor, Copilot, Codex y unos 40 más están soportados; el installer te pregunta cuáles. Una de esas skills es voice-agent, que es lo que evita que tu agente invente campos de configuración que no existen.

login abre el browser, eliges el proyecto y la key queda en ~/.zavu/credentials.json. De aquí en adelante describes.

Después describes el agente

text
Construye un voice agent de Zavu para mi clínica en mi sender actual. Que conteste en español, diga los horarios, busque una cita por número de teléfono, la reagende, y transfiera a +14155551234 cuando pidan una persona o suenen molestos. Tope de doce minutos. Deploya.

No necesitas conocer los comandos de abajo. Están para que reconozcas lo que pasa por la pantalla, y para que notes si se saltó un paso.

bash
npx zavudev whoami # qué proyecto estoy por tocar npx zavudev senders list # el número al que va a llamar la gente npx zavudev fn secrets set SENDER_ID "jn76vnxet8g5nq661by3v06y1581bmmn" npx zavudev deploy

Si prefieres arrancar de algo probado, hay un catálogo de agentes de voz listos:

bash
npx zavudev agents catalog
text
id name voice tools category fermi Fermi, Lead Qualification yes 5 sales curie Curie, Customer Support yes 5 support kepler Kepler, Video Call Booking yes 2 frontDesk hopper Hopper, Lead Capture and Booking yes 5 sales aria Aria, Multi-channel concierge yes 3 frontDesk atlas Atlas, Product Expert yes 0 support

npx zavudev agents pull curie --sender "$SENDER_ID" baja uno a tu repo como TypeScript editable. Es un punto de partida que es tuyo, no una caja negra que alquilas.

Lee lo que escribió

ts
import { defineAgent, defineTool } from "@zavudev/functions" defineAgent({ senderId: process.env.SENDER_ID!, name: "Clínica Norte", provider: "zavu", model: "openai/gpt-4o-mini", channels: ["voice", "whatsapp"], voice: { enabled: true, model: "openai/gpt-4o", greeting: "Clínica Norte, buenos días. ¿En qué le puedo ayudar?", language: "es", interruptible: true, maxCallDurationMinutes: 12, maxIdleSeconds: 30, transferPhoneNumber: "+14155551234", voicemailAction: "hangup", }, prompt: "Eres la recepción de Clínica Norte. Responde en español, una o dos frases. Transfiere a una persona cuando lo pidan, o cuando estén molestos.", })

Cinco campos deciden si la llamada se siente humana.

interruptible es barge-in. Quien llama puede cortar al agente a mitad de frase y este se calla a escuchar. Déjalo prendido. Un agente que habla por encima de la gente es exactamente lo que todos ya odian de las llamadas automáticas.

maxIdleSeconds corta la llamada después de silencio, para que un teléfono boca abajo en una mochila no te facture doce minutos.

maxCallDurationMinutes es el freno duro. Existe porque una conversación que salió mal suele salir mal por mucho rato.

voicemailAction define qué pasa cuando en una llamada saliente contesta una contestadora: hangup en silencio, o leave_message y hablar. Dejar un mensaje cuando querías hablar con una persona es cómo un agente útil se vuelve una molestia.

transferPhoneNumber es la salida de emergencia, y merece su propia sección.

La transferencia es por lo que te juzgan

Si defines transferPhoneNumber, el agente recibe una tool de transferencia. Además siempre recibe una de colgar, así que puede terminar por su cuenta una llamada que ya terminó.

Dos cosas para saber, y la segunda sorprende.

La transferencia solo existe si el sender también tiene un número desde el cual llamar. Si defines el destino y te olvidas del número del sender, el agente se queda sin con qué escalar y sin forma de decirlo.

Una transferencia reenvía la llamada. No le explica nada al humano. Tu colega atiende un teléfono que suena sin idea de que quien llama ya pasó noventa segundos explicándose. Si quieres que lo sepa, eso lo construyes tú: la transcripción completa está en el registro de la llamada y en el webhook call.completed, así que puedes mandar un resumen a Slack, WhatsApp o tu helpdesk en el momento de la transferencia. Dilo también en el prompt, para que el agente avise qué va a pasar en vez de quedarse mudo.

Dale algo que hacer

Un menú rutea. Esta es la parte que hace que un agente valga más que un menú:

ts
defineTool({ name: "find_appointment", description: "Busca la próxima cita de un paciente por número de teléfono.", parameters: { type: "object", properties: { phone: { type: "string", description: "Número en formato E.164" } }, required: ["phone"], }, handler: async ({ phone }) => { const res = await fetch("https://api.clinica.example/citas?phone=" + phone) if (!res.ok) return { found: false, reason: "lookup_failed" } return { found: true, ...(await res.json()) } }, })

Vale decirlo explícito: las tools sí corren en voz. En el path de texto plano no, que es lo que confunde a la gente en la dirección contraria. Un agente de voz puede consultar cosas de verdad a mitad de frase, y esa es toda la razón para apuntar uno a tu número de teléfono.

Prueba el handler solo, antes de cualquier llamada:

bash
npx zavudev fn invoke --tool find_appointment --args '{"phone":"+14155551234"}'

Eso corre en tu máquina, contra código sin commitear, en menos de un segundo.

Escúchalo antes que un cliente

Dos chequeos distintos, que atrapan fallas distintas.

bash
npx zavudev agents test --sender "$SENDER_ID" --message "quiero cambiar mi cita del martes"

Esto ejercita el cerebro: prompt, modelo, knowledge base. No se entrega nada, no se cobra nada, no queda registro. También imprime warnings sobre lo que un dry run no puede demostrar, y en un agente de voz el más útil es que ese path no llama tools aunque la llamada sí las va a llamar.

Después llámate a ti mismo:

bash
npx zavudev calls create --to "+56TUPROPIONUMERO"

Tu teléfono suena y el agente te habla. Ninguna otra cosa te va a decir que el saludo dura tres segundos de más, o que la voz lee un número de teléfono como un entero gigante. Presta atención a la interrupción: háblale encima a propósito y fíjate si se calla.

Después lee la llamada:

bash
npx zavudev calls list --limit 5 npx zavudev calls get <callId>

list muestra dirección, estado, duración y por qué terminó cada llamada. get devuelve la transcripción turno por turno. Esa transcripción es lo que tu central telefónica nunca te dio, y de ahí sale la próxima versión del prompt.

Después entrégale el loop:

text
Lee la transcripción de mis últimas tres llamadas. Todos preguntaron por estacionamiento y el agente no sabía. Agrégalo a la knowledge base, acorta el saludo, y vuelve a deployar.

También llama hacia afuera

El mismo agente coloca llamadas:

bash
npx zavudev calls create --to "+56912345678" --language es-ES --max-minutes 5

Recordatorios de cita, ventanas de entrega, un pago que falló. --language acepta auto para seguir el idioma de quien contesta. voicemailAction define qué pasa cuando atiende una máquina, que en campañas salientes es la mayoría de las veces.

Salientes es también donde un agente deja de ser una comodidad y pasa a ser algo que puede molestar a miles de personas rápido. Recordatorios que la gente pidió, sí. Llamadas en frío, no. El consentimiento y los horarios permitidos son tu responsabilidad, y ni el modelo ni la API los van a respetar por ti.

Qué queda de cada llamada

Se disparan cuatro eventos de webhook: call.initiated, call.answered, call.completed, call.failed. Todos llevan el id de la llamada, dirección, from, to, estado, duración y por qué terminó.

Los dos terminales además llevan cost, en USD, después de que la llamada se cobró. Ese no es el número crudo del carrier: es lo que se te facturó de verdad, telefonía y pipeline de voz juntos, así que puedes poner un precio real al lado de una conversación real.

Cómo se cobra esto en Zavu

La voz es por minuto conectado. El pipeline administrado son $0.0625 por minuto más telefonía, contados desde que atienden hasta que cortan. Los modelos estándar están cubiertos por esa tarifa; un modelo premium suma su propio costo por tokens. Al colocar la llamada se reserva un estimado corto y se liquida contra la duración real al terminar.

El plan cubre todo lo de alrededor. Free es $0, Hobby son $25 al mes, y de ahí escala. Cada plan incluye una cuota de números, tres en Hobby, y el primer número de Estados Unidos es gratis para cada team. Los números extra cuestan alrededor de un dólar al mes cada uno.

Construir es gratis. Skills, CLI, SDKs, deploy y cada redeploy. agents test no cobra. fn invoke corre local. Lo que pagas es una llamada conectada.

El número para quedarse: una llamada de cinco minutos en el pipeline administrado son unos treinta centavos más telefonía. Compáralo con lo que cuesta una persona esos mismos cinco minutos, y después con lo que cuesta una llamada abandonada, que es el orden que importa.

Las tarifas se mueven. La página de precios es la que está al día.

Tres reglas que mantienen esto honesto

Nunca finjas un éxito. Una tool que reporta una cita reagendada que nunca reagendó hace que el agente le diga a una persona real, en voz alta y con tono seguro, que su martes está resuelto. Devuelve la falla. El agente la va a decir, y quien llamó puede hacer algo al respecto. Esto es peor en voz que en cualquier otro lado, porque nadie relee una llamada telefónica.

Avisa que vas a transferir. Silencio seguido de tono suena a que te cortaron. Una frase, después la transferencia.

Un dry run no es una llamada. agents test demuestra que el prompt es sensato. No demuestra que el saludo suene bien, que la voz pronuncie el nombre de tu empresa, ni que el agente se calle cuando lo interrumpen. Eso solo lo demuestra una llamada real, así que haz la primera a tu propio teléfono.

Dónde te deja esto

Tu número de teléfono ahora contesta, entiende, consulta algo real y pone a una persona cuando corresponde. El comportamiento vive en un archivo al que le puedes hacer diff, con una transcripción por llamada y un costo al lado.

El menú nunca fue el producto. Era el compromiso que aceptaste porque el software no podía sostener una conversación. Ahora puede.

Necesitas ayuda? Contáctanos o únete a nuestra comunidad en Discord para soporte.

Siguenos en redes sociales

Listo para empezar?

Comienza a construir gratis, o agenda una llamada para discutir tu caso de uso específico.

Reemplaza tu IVR por un Agente de Voz con IA | Zavu Blog