Handoff al técnico por WhatsApp
Cómo el evento industrial llega al técnico con todo el contexto sin que lo repita el agente.
Handoff al técnico por WhatsApp
Cuando el agente industrial detecta un evento crítico y abre una tarea, el técnico recibe un WhatsApp con toda la información de la máquina. Al responder, puede preguntar por manuales o reportar el cierre de la tarea sin volver a identificarse. Este documento describe el flujo punta a punta.
Resumen ejecutivo
El cambio de juego: el técnico no vuelve a escribir "Soy Juan del turno de la tarde, la máquina 042 está fallando". Responde al WhatsApp con "¿qué manual hay para esto?" y el agente ya sabe quién es, qué máquina falla y qué tarea tiene abierta.
Antes del handoff el técnico tenía que:
- Leer el mensaje del evento en WhatsApp.
- Abrir otra ventana para buscar el manual.
- Autenticarse con su cédula al agente conversacional para ver documentos restringidos.
- Copiar el asset_id manualmente al query.
Con el handoff: responde al mismo WhatsApp y todo está en contexto.
¿Para qué sirve?
- Eliminar fricción de identificación. El phone que recibe el WhatsApp ya está ligado al personnel registrado. La sesión se preautentica con los roles del técnico automáticamente.
- Evitar la pérdida de contexto entre agentes. El agente industrial procesa eventos; el agente de WhatsApp conversa. Sin handoff, el segundo no sabe qué disparó la conversación. Con handoff, sí.
- Scopear las búsquedas al activo real. Cuando el técnico pregunta "¿cómo se limpia?", el agente responde sobre la bomba AST-042 que está fallando, no sobre cualquier bomba del catálogo.
- Soportar múltiples eventos simultáneos. Si a un técnico le asignan dos tareas de activos distintos en la misma hora, ambos contextos quedan activos en la conversación y el agente los distingue al responder.
¿Cómo funciona?
sequenceDiagram
participant PLC as Sensor / PLC
participant MA as Agente de máquinas
participant DB as MongoDB
participant WA as WhatsApp
participant T as Técnico
participant CA as Agente conversacional
PLC->>MA: Evento (overheating, AST-042, critical)
MA->>MA: assign_task → task MAN-001
MA->>DB: push_machine_context(conv, asset_id, task_id, personnel_id)
MA->>WA: send_whatsapp_message (plantilla determinista)
WA->>T: "🔴 MAN-001 Activo AST-042 · overheating..."
T->>WA: "¿qué manual aplica?"
WA->>CA: webhook (conversación = Juan)
CA->>DB: lee machine_contexts activos + personnel roles
CA->>CA: prompt enriquecido + sesión preautenticada
CA->>DB: query manuals con asset_id implícito
DB-->>CA: sección del manual de AST-042
CA->>T: "Procedimiento 4.2: purgar el circuito..."Pasos en detalle
- El agente industrial crea la tarea y notifica. Al llamar
assign_task, el servicio guarda en la conversación de WhatsApp del técnico tres cosas:personnel_id: quién es el destinatario.machine_contexts[]: stack de contextos industriales activos, conasset_id,task_id,event_id, severidad, diagnóstico, TTL de 6 horas.- Mensaje saliente: plantilla determinista con severidad, activo, tarea y una frase de invitación a conversar.
- El técnico responde. Evolution API entrega el mensaje al webhook de Rela-ai. El webhook reconoce la conversación por el phone.
- La sesión se preautentica. El webhook lee
personnel_id, resuelve al técnico en_personnel, hereda susrolesy eleva la sesión aauthenticated. Queda marcada conpreauth_source="personnel". - El prompt se enriquece. El agente conversacional construye su prompt con: su system prompt normal + los contextos industriales activos (uno por evento abierto) + el mensaje del usuario.
- Las queries quedan acotadas al activo. Cuando el agente llama a un
tool de consulta (manuales, procedimientos, historial), el dispatcher
inyecta
asset_iddel contexto activo como filtro implícito. El LLM no tiene que repetir el ID. - El cierre es un tool más. Si el técnico dice "ya quedó resuelto", el
agente llama
update_taskconstatus=doney notas del técnico. La tarea cambia de estado; la alerta relacionada puede cerrarse.
TTL y multi-contexto
Cada entrada en machine_contexts[] lleva triggered_at y
expires_at = triggered_at + 6h. El job interno
POST /internal/cleanup-machine-context corre horariamente y purga las
entradas expiradas.
Si llegan dos eventos de activos distintos a un mismo técnico, el stack tiene dos entradas activas. El prompt le muestra al agente un bloque por evento:
Active industrial context (2 open tickets)
[1] MAN-001 · Activo AST-042 · overheating (critical)
Diagnóstico: purgar el circuito de refrigeración...
[2] MAN-002 · Activo AST-105 · vibration anomaly (high)
Diagnóstico: bearing desalineado, ajustar torque...El técnico responde "el segundo" y el agente sabe que habla de AST-105.
Configuración
Todo el handoff se activa al configurar la notificación del agente de máquinas
en Agente de máquinas → Notificaciones:
- Habilitar WhatsApp.
- Seleccionar el número conectado.
- Elegir Destinatario = un técnico registrado en
Personal.
Seleccionar un técnico con perfil (no "Número personalizado") es lo que activa
la preautenticación y la preservación de contexto. Si eliges un número
custom sin personnel, el WhatsApp sigue saliendo pero el técnico arranca
anónimo y no podrá consultar colecciones con access_roles configurados.
Roles del técnico
Los roles del técnico viven en _personnel.roles (array de strings). El
sistema los hereda tal cual a la sesión. Si el técnico tiene rol technician
y una colección manuals tiene access_roles: ["technician"], la consulta
pasa.
Si una colección tiene access_roles que no están en los roles del técnico,
la consulta falla con un mensaje natural: "No tengo permiso para consultar
esa información con tu perfil." — el agente nunca devuelve un JSON crudo al
usuario.
Limitaciones
- El handoff requiere que el número del técnico esté en
_personnel.phoneexactamente como lo envía el PLC al agente. Formatos distintos no hacen match. - Un mismo número de WhatsApp atiende a un solo agente conversacional por tenant. No se puede tener dos agentes de WhatsApp apuntando al mismo número.
- La preautenticación asume que el phone es factor de identificación suficiente. Si un técnico pierde el teléfono, cualquiera con ese número puede consultar hasta que se cambie el registro o se agregue auth explícita por OTP.
- Los contextos expirados (más de 6 horas desde el push) no se ven ni se renderizan aunque permanezcan en el array hasta que el cleanup corra.
- El campo
asset_idsólo viaja si el evento lo trae enmetadata.asset_id. Sensores mal mapeados no propagan el contexto.
Beneficios clave
- Un solo flujo WhatsApp, sin pedir al técnico que se identifique dos veces.
- Respuestas del agente acotadas al activo real desde la primera pregunta.
- Multi-ticket: el técnico puede atender varios eventos abiertos sin mezclarlos.
- Cierre de tarea conversacional sin abrir el dashboard.
- Expiración automática del contexto para que las conversaciones viejas no sesguen respuestas futuras.
Cómo verificarlo
El script scripts/e2e/machine_agent_demo/run_demo.py del repo relaai-api
ejecuta el flujo punta a punta contra un tenant real (sin enviar WhatsApp real
ni llamar a Gemini). Valida que el contexto se persiste, la sesión se
preautentica con los roles correctos y el cleanup purga las expiradas.
Edge Gateway — Instalación y Operación
Cómo instalar el contenedor rela-ai-edge en tu planta, registrarlo, asignarle fuentes, monitorear el fleet y solucionar problemas de conexión.
Eventos en Vivo
Stream en tiempo real de eventos entrantes de máquinas e industria. Monitoreo directo durante turnos críticos o comisionamientos.