Notas de construcción · Arquitectura de IA y seguridad

Arquitectura de IA actual del chatbot de Klaros: diseño a prueba de fallos y anclaje sin tokens

· 100 % anclado en hechos · Fundador, Klaros

Cuando construimos la primera versión del chatbot de IA de Klaros para WhatsApp, tomamos una decisión arquitectónica deliberada: «Reglas primero, LLM al final, humano por encima siempre». Envolver un LLM sin restricciones alrededor de los webhooks entrantes y confiar en que las instrucciones del sistema aguanten es una receta para el desastre en WhatsApp.

En una operación de WhatsApp, basta un precio alucinado, un mensaje automático inoportuno lanzado encima de una conversación de venta que lleva una persona, o un envío de formato libre sin verificar fuera de la ventana de servicio de 24 horas de Meta, para dañar la confianza del cliente de forma permanente. Diseñamos el chatbot de Klaros en torno a límites de seguridad que fallan en cerrado: las reglas deterministas se ejecutan primero, y el LLM solo se invoca cuando hace falta ayuda no determinista.

Resumen

Desde la perspectiva directa de quien lo desarrolla, la arquitectura actual del chatbot prioriza la seguridad y el control del coste: (1) agent-decision.mjs ejecuta un árbol de 8 niveles de prioridad que cede ante el personal humano durante 24 h; (2) ai-auto-reply.mjs impone el acotado a hechos con citas obligatorias de fragmentos (usedFacts) y degrada a transferencia humana toda respuesta sin citar; (3) learned-answer.mjs intercepta consultas repetidas mediante coincidencia de Jaccard para servir respuestas verificadas con coste cero en tokens; y (4) retrieve.mjs puntúa la relevancia de términos con BM25 en JavaScript puro en menos de 10 ms dentro de Cloudflare Workers.

El razonamiento: reglas primero, LLM al final

En la API de WhatsApp Cloud, los mensajes de formato libre solo pueden enviarse dentro de una ventana de servicio abierta de 24 horas, mientras que los mensajes de plantilla salientes cuestan dinero por cada entrega. Un modelo de chatbot sin restricciones que se inventa precios u ofrece descuentos fuera de los parámetros aprobados rompe el cumplimiento con Meta y quema presupuesto.

Situamos el LLM en la etapa 9000 (last_resort, último recurso). Las bajas, los disparadores por palabra clave, las reglas de ausencia, los pasos de secuencia y la detección de intervención humana se ejecutan de forma determinista antes de que llegue a construirse siquiera una llamada a la API del LLM.

El árbol de 8 niveles de prioridad y la cesión ante el humano

En agent-decision.mjs, cada contacto se evalúa a través de 8 niveles de prioridad explícitos. Nuestra decisión más determinante fue la Prioridad 1: comprobación de actividad humana fuera de línea (detectOfflineConversation()). Si una persona de ventas o de soporte ha intervenido en el hilo en las últimas 8 horas, toda acción automática del chatbot cede durante 24 horas. El asistente nunca habla por encima de un compañero.

Esquema del código: estructura del árbol de prioridades en agent-decision.mjs

// Prioridad 1: cesión ante una persona del equipo
if (await detectOfflineConversation(contactId)) {
  return buildPauseDecision("Personal humano activo en el hilo");
}
// Prioridad 2: cumplimiento de la lista de no contactar
if (contact.opted_out || contact.dnc) {
  return buildDncDecision();
}
// Prioridades 3-7: secuencias deterministas y filtros de cualificación
// Prioridad 8: planificador LLM como respaldo si hace falta planificación no determinista

Respuestas automáticas acotadas a hechos y reglas de cita

Cuando se ejecuta el respondedor automático (ai-auto-reply.mjs), recibe como mucho 6 fragmentos de conocimiento recuperados. El prompt exige un sobre de acción JSON estricto con índices de cita explícitos en usedFacts:

{
  "canAnswer": true,
  "reply": "Nuestro plan estándar incluye 3 líneas...",
  "action": "reply",
  "usedFacts": [1, 3]
}

Si el modelo genera una respuesta de texto sin citar al menos un índice de fragmento recuperado, nuestro validador de salida marca la falta de atribución y degrada el resultado a una transferencia a un humano (HANDOFF). El chatbot nunca entrega a un cliente potencial texto que no esté anclado.

Mecánica de la caché de preguntas sin coste en tokens

Las respuestas verificadas del operador se indexan en knowledge_answers. En learned-answer.mjs (etapa 8000), las consultas entrantes se tokenizan y se puntúan mediante similitud de Jaccard. Cuando la similitud alcanza el umbral de 0,6 con dos o más palabras de contenido compartidas, la respuesta verificada se envía con coste cero en tokens, evitando por completo la inferencia del LLM. Cualquier operador puede calcular su reducción exacta de coste en tokens con nuestra calculadora de costes de WhatsApp.

Motor de búsqueda BM25 sin dependencias

La recuperación en uni-cloud/src/services/knowledge/retrieve.mjs usa puntuación BM25 de términos en JavaScript puro sobre fragmentos SQLite en D1. Aplicamos una razón discriminante de frecuencia documental (1/3) para filtrar términos de relleno sin depender de ninguna base de datos vectorial externa, manteniendo la ejecución por debajo de 10 ms dentro de los aislados de Cloudflare Workers.

Matriz de compromisos de la arquitectura

El diseño actual del chatbot representa decisiones de ingeniería explícitas:

Recibe la próxima nota de construcción por WhatsApp

Escribe a nuestra línea y envía NOTES. La última nota de ingeniería vuelve directamente, en el mismo hilo, desde el número que envía todo lo demás. Responde STOP cuando quieras y se detiene.

Enviar NOTES por WhatsApp

Pregunta a nuestro número de WhatsApp cuánto cuesta

No es un formulario de ventas. Escribe a la línea y envía precios. Recibirás nuestro catálogo en vivo como lista de WhatsApp, con las plazas realmente disponibles y un enlace de pago en lo que toques. El recorrido completo es el producto, demostrándose a sí mismo antes de que sea tuyo.

Preguntas que nos hacen sobre esto

¿Por qué el chatbot de Klaros usa una arquitectura de reglas primero en lugar de prompts LLM sin restricciones?

En la API oficial de WhatsApp Cloud, los mensajes de formato libre solo pueden enviarse dentro de una ventana de servicio abierta de 24 horas, y los mensajes automáticos sin verificar pueden activar bloqueos por spam. Klaros ejecuta reglas de secuencia deterministas, comprobaciones de baja y detección de intervención humana antes de llamar al LLM, de modo que el asistente falla en cerrado y con barreras de seguridad.

¿Cómo funciona la caché de respuestas aprendidas sin coste en tokens?

Las respuestas verificadas del operador se guardan en la tabla knowledge_answers. Las consultas entrantes se tokenizan y se evalúan con similitud de Jaccard. Si la similitud alcanza el umbral de 0,6 con al menos dos palabras de contenido compartidas, la respuesta guardada se envía sin coste alguno en tokens.

¿Cómo evita el acotado a hechos las alucinaciones de la IA en WhatsApp?

El respondedor automático pasa al LLM un máximo de 6 fragmentos de conocimiento recuperados y exige un sobre de acción JSON estricto. La respuesta debe citar los índices exactos de los fragmentos en usedFacts. Si faltan las citas, el analizador de salida rechaza el texto y lo degrada a una transferencia a un humano.

¿Qué ocurre cuando una persona del equipo toma el control de una conversación?

La heurística de Prioridad 1, detectOfflineConversation(), comprueba si ha habido interacción de personal humano en las últimas 8 horas. Si la detecta, toda la mensajería automática con IA se pausa durante 24 horas para que el asistente nunca interrumpa a una persona del equipo.

¿Qué proveedores y modelos de LLM admite la pasarela de IA de Klaros?

Klaros admite Cloudflare Workers AI (Llama 3.3 70B Instruct), DeepSeek Chat, OpenAI GPT-4o-mini, Anthropic Claude Haiku y modelos locales Ollama/Qwen para instalaciones de escritorio.

Escrito el 19 de agosto de 2026. Traducido al español el 2 de septiembre de 2026. Ampliamos el texto cuando cambian los hechos. Relacionado: todas las notas en español, la versión original en inglés.