Chatty por dentro
Doc vivo Este artículo se actualiza a medida que mi workflow cambiaEl mapa de la plataforma que corre mis bots de venta. Un artículo vivo que se actualiza cuando la arquitectura cambia.
Chatty es la plataforma que armé para correr bots de venta arriba de Chatwoot. Hoy corre un bot para una tienda de tecnología que atiende sus chats de WhatsApp e Instagram: busca en el catálogo real, cotiza canjes y cuotas, arma reservas y, cuando la charla necesita una persona, la pasa con el contexto ya escrito. La parte del negocio, con números y lo que el bot no hace, está en la página de bots. Esto es el reverso: cómo está hecho.
Este artículo es el mapa. Cada pieza tiene su propio post, linkeado acá. Sigue marcado como doc vivo porque se actualiza cuando la arquitectura cambia.
El recorrido de un mensaje
El buffer. La gente escribe en ráfagas: “Buenas”, y a los cinco segundos “precio del 16?”. Responder cada mensaje por separado se sentía torpe. La ventana de 30 segundos salió de medir el tiempo entre mensajes en 790 conversaciones: la mediana era de 10 segundos. Fue el cambio que más mejoró la percepción de calidad, y no toca ni una línea del prompt.
Un solo agente. Hubo clasificador, router y un grafo de workflows. Se borraron en julio. Quedó un agente con cuatro herramientas: buscar productos, calcular canje, cotizar pago y derivar a humano. Las herramientas devuelven filas, nunca prosa.
El espejo del catálogo. Las herramientas no leen el sistema de la tienda en vivo. Leen una copia normalizada en Postgres que se sincroniza cada media hora, en una transacción: el que está respondiendo ve el catálogo viejo entero o el nuevo entero, nunca uno a medias. El dólar del día también vive ahí. Ninguna cifra viaja por el modelo.
Los guards. Antes de que una respuesta salga, veintiocho reglas la revisan: montos que no salieron de una herramienta, stock que la búsqueda no devolvió, una cotización de canje sin haber preguntado modelo y batería. Si una falla, el modelo regenera dentro del mismo run, con una nota correctiva. Si reincide, la respuesta se descarta y la charla pasa a una persona. El mecanismo entero está en Una regla que tira la respuesta a la basura. Por qué la escalera termina en el prompt y no empieza ahí lo cuento en Las alucinaciones no se evitan con el prompt.
El veredicto. Lo que recibe el cliente lo decide una función pura: respuesta, derivación o fallback, con el motivo. Se testea sin modelo, sin base y sin timeouts. Es el 80% de la confianza del sistema y el 20% del código.
El pase. Tres caminos llevan una charla a una persona: el modelo llama la herramienta de derivación, una tabla de doce reglas fuerza el pase aunque no la haya llamado (un comprobante de pago adjunto, un “te paso con un asesor” sin herramienta), o el turno no produjo nada enviable. En los tres la conversación cambia de dueño en Chatwoot, con el motivo en una nota, y cada turno siguiente pregunta quién atiende antes de escribir. Los tres caminos y lo que costó que el bot se callara están en Cuándo el bot pasa a una persona.
Las pruebas. Cuatro capas. Unitarias sobre el veredicto. Un test de contrato contra el sistema real de la tienda. Noventa y seis conversaciones con guion fijo, multi-turno, contra el bot real y una base congelada: esas son el filtro para mergear. Y un replay donde un modelo juega al cliente y otro juzga el transcript, que nunca es filtro, es observación. Las cuatro capas, con lo que cuestan, están en Las pruebas que sí corro.
El loop de mantenimiento. El bot se mantiene con skills que corre Claude Code contra el repo y contra producción: una audita conversaciones y abre issues, otra convierte una captura que manda la tienda en un issue con el trace ya investigado, otra toma el issue, arregla y escribe las pruebas nuevas. Cada arreglo trae una nota de novedades en lenguaje de tienda, que el cliente lee desde su propio Claude. Los cinco skills, y la semana en que un arreglo sin prueba no arregló nada, están en El loop de mantenimiento son skills.
El MCP. El mismo servidor expone un MCP con OAuth por tienda. Encima corre un reporte diario: demanda que no se pudo satisfacer, lista de espera, embudo de reservas, de qué anuncio vino cada cliente. La frontera que estoy probando es esa: el bot captura, el MCP consume. Cómo pregunta la tienda y la vez que el reporte adivinaba lo que el bot ya sabía están en El bot captura, el MCP consume.
Stack
Bun y Hono para el servidor, Postgres en Supabase, pg-boss para las colas, Mastra para el agente y los traces, Drizzle para el esquema, Fly para el deploy, Sentry para errores. Un modelo abierto por API como primario, con una cadena de fallback donde cada eslabón está por un incidente con fecha. El dominio está en castellano y la infraestructura en inglés, a propósito.
La serie
- Este artículo, el mapa.
- Las alucinaciones no se evitan con el prompt: la escalera de datos, herramientas, guards y prompt.
- Una regla que tira la respuesta a la basura: cómo funciona un guard con reintento, y lo que ningún guard atrapa.
- Las pruebas que sí corro: cuatro capas, cuáles frenan un cambio, y lo que cuesta correrlas.
- Cuándo el bot pasa a una persona: los tres caminos al pase, y por qué el bot se calla después.
- El loop de mantenimiento son skills: evidencia para abrir, una prueba que falla para cerrar, y la nota que lee la tienda.
- El bot captura, el MCP consume: cómo pregunta la tienda, el reporte del día, y qué le toca al bot y qué no.