La diferencia entre un bot que responde y uno que vende
El 90% de los chatbots de WhatsApp que vemos en el mercado argentino hacen lo mismo: responden preguntas frecuentes con un menu de opciones numeradas ("Escribi 1 para precios, 2 para horarios, 3 para hablar con un humano"). Eso no es un chatbot con IA. Es un IVR con emojis.
Un chatbot con IA real entiende lo que el cliente escribe en lenguaje natural, mantiene contexto de la conversacion, consulta tu base de datos en tiempo real y puede cerrar una venta completa sin intervencion humana.
En NexPO construimos este tipo de bots para negocios reales. Almacen de Cerveza es un ejemplo: su bot toma pedidos completos las 24 horas.
Arquitectura de un chatbot que vende
``
+------------------+
| WhatsApp Cloud |
| API (Meta) |
+--------+---------+
|
Webhook | POST /webhook
v
+------------------+
| n8n / Backend |
| (Orquestador) |
+--------+---------+
|
+--------------+--------------+
| | |
v v v
+-------+------+ +----+-----+ +------+------+
| OpenAI GPT-4 | | Supabase | | WhatsApp |
| (Razonamiento)| | (Datos) | | (Respuesta) |
+--------------+ +----------+ +-------------+
`
Componente 1: WhatsApp Business API
No uses WhatsApp Web automatizado (es contra los ToS de Meta y te banean). Usa la API oficial:
- Meta Cloud API (gratuita, self-service): Meta hostea la infra. Vos solo manejas webhooks.
- BSPs (Business Solution Providers): Twilio, 360dialog, etc. Agregan features como templates pre-aprobados y dashboards.
Componente 2: Orquestador (n8n)
n8n es la pieza que conecta todo. Un flow tipico:
`
Trigger: Webhook de WhatsApp (mensaje entrante)
|
+--> Extraer texto del mensaje
+--> Buscar historial de conversacion en Supabase
+--> Enviar a OpenAI con contexto (system prompt + historial + datos del negocio)
+--> Recibir respuesta del LLM
+--> Si el LLM detecta intencion de compra:
| +--> Consultar stock en Supabase
| +--> Confirmar pedido
| +--> Guardar pedido en base de datos
| +--> Notificar al dueno
|
+--> Enviar respuesta al cliente via WhatsApp API
+--> Guardar mensaje en historial
`
Componente 3: El LLM (OpenAI GPT-4o)
El LLM es el cerebro. Pero un cerebro sin informacion no sirve. La clave esta en el system prompt.
El system prompt que hace la diferencia
Un system prompt generico genera respuestas genericas. Asi armamos los nuestros:
`
Sos el asistente virtual de [NOMBRE DEL NEGOCIO], una [TIPO DE NEGOCIO]
ubicada en [CIUDAD].
TU ROL:
- Atender consultas sobre productos, precios, disponibilidad y delivery
- Tomar pedidos completos cuando el cliente esta listo
- Derivar a un humano cuando no puedas resolver algo
- Horarios: [HORARIOS]
- Delivery: [ZONAS Y COSTOS]
- Metodos de pago: [METODOS]
- Politicas: [POLITICAS RELEVANTES]
REGLAS:
- Siempre responde en espanol argentino informal
- Si no sabes algo, deci "dejame consultar con el equipo"
- Nunca inventes precios o disponibilidad
- Si el cliente quiere comprar, guialo paso a paso:
- Si el cliente esta enojado o reclama, deriva a humano inmediatamente
- Maximo 2 mensajes de venta activa. Si el cliente no quiere, no insistas
- Mensajes cortos (maximo 3 oraciones por mensaje)
- Usa saltos de linea para separar ideas
- No uses emojis excesivos (maximo 1-2 por mensaje)
Inyeccion dinamica de catalogo
El catalogo no va hardcodeado en el prompt. Se consulta de Supabase antes de cada llamada al LLM:
`typescript
// Pseudo-codigo del flujo
async function handleMessage(userMessage: string, userId: string) {
// 1. Buscar historial
const history = await supabase
.from('chat_history')
.select('role, content')
.eq('user_id', userId)
.order('created_at', { ascending: true })
.limit(20)
// 2. Buscar catalogo actualizado
const { data: products } = await supabase
.from('products')
.select('name, price, stock, category')
.gt('stock', 0)
// 3. Armar el prompt con datos frescos
const systemPrompt = buildSystemPrompt({
catalog: products,
businessInfo: BUSINESS_CONFIG,
})
// 4. Llamar a OpenAI
const response = await openai.chat.completions.create({
model: 'gpt-4o',
messages: [
{ role: 'system', content: systemPrompt },
...history.data.map(h => ({ role: h.role, content: h.content })),
{ role: 'user', content: userMessage },
],
temperature: 0.7,
max_tokens: 300,
})
// 5. Detectar si hay intencion de compra
// (se puede hacer con function calling de OpenAI)
const reply = response.choices[0].message.content
// 6. Guardar en historial y responder
await saveToHistory(userId, userMessage, reply)
await sendWhatsAppMessage(userId, reply)
}
`
Function Calling para tomar pedidos
En vez de parsear texto libre para detectar si el cliente quiere comprar, usamos Function Calling de OpenAI:
`typescript
const tools = [
{
type: 'function',
function: {
name: 'crear_pedido',
description: 'Crear un pedido cuando el cliente confirma su compra',
parameters: {
type: 'object',
properties: {
items: {
type: 'array',
items: {
type: 'object',
properties: {
producto: { type: 'string' },
cantidad: { type: 'number' },
},
required: ['producto', 'cantidad'],
},
},
direccion: { type: 'string' },
metodo_pago: {
type: 'string',
enum: ['efectivo', 'transferencia', 'mercadopago'],
},
},
required: ['items'],
},
},
},
{
type: 'function',
function: {
name: 'escalar_a_humano',
description: 'Derivar la conversacion a un operador humano',
parameters: {
type: 'object',
properties: {
motivo: { type: 'string' },
},
required: ['motivo'],
},
},
},
]
`
Cuando el LLM invoca
crear_pedido`, nuestro backend lo procesa automaticamente: verifica stock, crea el pedido en Supabase, y le manda la confirmacion al cliente.
Los 5 errores que arruinan un chatbot
1. No mantener historial de conversacion
Sin historial, cada mensaje del cliente es una conversacion nueva. El bot no recuerda que el cliente ya dijo su direccion, que productos eligio, ni que le pregunto hace 2 minutos.
Solucion: Guardar los ultimos 15-20 mensajes en Supabase y enviarlos como contexto en cada request al LLM.
2. Respuestas demasiado largas
WhatsApp no es un email. Un mensaje de 500 palabras no se lee. El bot tiene que responder en 1-3 oraciones, maximo.
3. No tener escalado a humano
Si el bot no puede resolver algo y sigue insistiendo, el cliente se frustra y no vuelve. El escalado tiene que ser automatico (cuando detecta enojo, reclamo o pedido de hablar con alguien) y manual (boton para el operador para tomar control).
4. Inventar informacion
Si el LLM no tiene el dato en su contexto, va a inventar. "Si, hacemos delivery a tu zona" cuando en realidad no hacen. Solucion: en el system prompt, ser explicito sobre que hacer cuando no sabe ("deci que vas a consultar y escala").
5. No medir conversiones
Si no medis cuantas conversaciones terminan en pedido vs. cuantas en abandono, no podes mejorar. Logueamos cada conversacion con su outcome: pedido_completado, escalado, abandonado, solo_consulta.
Costos reales
| Componente | Costo |
|---|---|
| Desarrollo del bot | USD 1.500 - 3.000 (unico) |
| WhatsApp Cloud API | Gratis (1.000 conv/mes) o USD 0.03-0.08/conv |
| OpenAI GPT-4o | USD 10-30/mes (500-1.000 consultas) |
| n8n hosting | USD 0 (self-hosted) o USD 20/mes (cloud) |
| Supabase | USD 0-25/mes |
| Total mensual | USD 10-75/mes |
Como empezar
- Defini que tiene que hacer el bot: Responder preguntas? Tomar pedidos? Agendar turnos? No todo junto al principio.
- Arma tu catalogo en una base de datos: El bot necesita datos estructurados. Si tu catalogo esta en un PDF o en la cabeza del dueno, primero hay que estructurarlo.
- Empeza con un bot de FAQ + escalado: No arranques con toma de pedidos. Primero valida que el bot responde bien las preguntas frecuentes.
- Medí y ajusta: Las primeras 2 semanas vas a tener que ajustar el prompt constantemente. Es normal. El bot "aprende" en el sentido de que vos le vas refinando las instrucciones.
¿Necesitas ayuda con tu proyecto?
Diagnostico gratuito, presupuesto cerrado y soporte post-lanzamiento incluido.