24 de febrero de 2026 • 6 min de lectura
Especialista en IA y Automatización
Diseño sistemas de comunicación impulsados por IA. Mi trabajo se centra en agentes de voz, chatbots de WhatsApp, asistentes de IA y automatización de flujos, construidos principalmente sobre Twilio, n8n y LLM modernos como OpenAI y Claude. En los últimos 7 años he entregado más de 30 proyectos de automatización que manejan más de 250 000 interacciones mensuales.
Si te gusta el contenido que hago, puedes suscribirte y recibir información valiosa por correo. No se envía spam, solo novedades sobre publicaciones interesantes o contenido especializado del que hablo.
Casi todos los tutoriales de asistentes de IA se enfocan en prompts o modelos.
En producción, eso rara vez es lo difícil.
El desafío real es construir un sistema que:
En este artículo desarmo la arquitectura completa de un agente de IA en WhatsApp que agenda turnos automáticamente.
En lugar de un tutorial paso a paso, esto es un recorrido práctico de ingeniería:
Antes de meternos en detalles, esta es la arquitectura general:
WhatsApp (Twilio) → Webhook → Normalización → Ramificación audio/texto → Transcripción (si hace falta) → Agente de IA (tools + memoria) → Parser de salida → Respuesta

Principio clave:
El LLM es apenas un componente dentro de un sistema más grande.
Un agente conversacional que agenda turnos tiene que respetar restricciones reales:
Sin resolver eso primero, el modelo se vuelve poco confiable por más bueno que sea.
Todos los mensajes entrantes llegan por webhook.
Configuración de ejemplo del nodo:
{
"type": "n8n-nodes-base.webhook",
"parameters": {
"httpMethod": "POST",
"path": "your-webhook-id"
},
"name": "Webhook"
}
Decisión de diseño:
Nunca dejes que los nodos de abajo dependan de la estructura cruda del webhook. Normalizá temprano.
Convertimos el payload entrante en un formato interno estable:
{
"type": "n8n-nodes-base.set",
"name": "Edit Fields",
"parameters": {
"assignments": {
"assignments": [
{ "name": "type", "value": "={{ $json.body.MessageType }}" },
{ "name": "body", "value": "={{ $json.body.Body }}" },
{ "name": "from", "value": "={{ $json.body.From }}" },
{ "name": "recording", "value": "={{ $json.body.MediaUrl0 }}" }
]
}
}
}
Esto importa porque el resto del sistema queda independiente de los formatos propios de cada proveedor.
Los mensajes de audio requieren pasos extra:
Lógica de ejemplo del switch:
{
"type": "n8n-nodes-base.switch",
"name": "Switch",
"parameters": {
"rules": {
"values": [
{ "outputKey": "Audio", "conditions": [{ "leftValue": "={{ $json.type }}", "rightValue": "audio" }] },
{ "outputKey": "Text", "conditions": [{ "leftValue": "={{ $json.type }}", "rightValue": "text" }] }
]
}
}
}
Principio importante:
El agente de IA nunca debería saber si la entrada fue audio o texto.
Los audios se traen de los servidores de Twilio y se transcriben con OpenAI.
{
"type": "n8n-nodes-base.httpRequest",
"name": "HTTP Request",
"parameters": {
"url": "={{ $json.recording }}",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "twilioApi"
}
}
{
"type": "@n8n/n8n-nodes-langchain.openAi",
"name": "Transcribe a recording",
"parameters": {
"resource": "audio",
"operation": "transcribe",
"options": { "language": "es" }
}
}
Idea clave:
Normalizá las entradas ANTES de que lleguen al agente. Si no, los prompts se complican sin necesidad.
Las dos ramas convergen en una sola estructura estandarizada:
const base = { ...$('Edit Fields').first().json };
const normalizedBody = (base.type === 'audio')
? ($input.first().json.text ?? '').trim()
: (base.body ?? '');
return [{
json: {
...base,
body: normalizedBody,
from: base.from.split('whatsapp:')[1]
}
}];
Eso reduce muchísimo la complejidad río abajo.
Antes de generar la respuesta, mandamos un indicador de "escribiendo" por Twilio con un nodo HTTP Request.
{
"type": "n8n-nodes-base.httpRequest",
"name": "Señal de escribiendo respuesta",
"parameters": {
"method": "POST",
"url": "https://messaging.twilio.com/v2/Indicators/Typing.json",
"bodyParameters": {
"parameters": [
{ "name": "messageId", "value": "={{ $('Webhook').item.json.body.MessageSid }}" },
{ "name": "channel", "value": "whatsapp" }
]
}
}
}
Cambio chico, salto grande en inteligencia percibida. El usuario siente que interactúa con un sistema real y no con una automatización.
El agente se compone de:
GPT-4.1-mini con esquema de salida estructurada. Uso un modelo mini porque escala bien en ahorro, sin gastar tiempo pensando sobre información que ya tiene.
Sesión indexada por número de teléfono.
Ventana limitada a las últimas interacciones para que no crezca sin control.
Regla de diseño clave:
El modelo no inventa datos. Consulta tools.
{
"model": "gpt-4.1-mini",
"response_format": "json_schema"
}
La salida estructurada evita fallas río abajo.
Una restricción fundamental:
Los eventos del calendario representan tiempo ocupado, no disponibilidad.
El sistema tiene que:
Esa sola regla evita la mayoría de las fallas reales de agendamiento.
Los agentes no siempre devuelven la misma estructura de salida.
En lugar de confiar ciegamente en la respuesta, parseamos a la defensiva:
function tryParseJson(output) {
try { return JSON.parse(output); } catch { return null; }
}
Los sistemas de producción asumen variabilidad.
El nodo final devuelve el mensaje generado por la IA usando Twilio. Simple, pero recién después de las capas de validación y formato.
{
"type": "n8n-nodes-base.twilio",
"name": "Send an SMS/MMS/WhatsApp message",
"parameters": {
"toWhatsapp": true,
"to": "={{ $('Normalizar datos').item.json.from }}",
"message": "={{ $json.message }}"
}
}
Los agentes de IA no son chatbots con mejores prompts.
Son sistemas compuestos por:
Si estás armando algo parecido y querés ayuda para pasar de prototipo a producción, escribime.
Descubre cuánto te está costando tu sistema de comunicaciones.
Obtén la auditoría de comunicaciones