Un copiloto de IA industrial es un asistente que permite a los operarios hacer preguntas en lenguaje natural, como "¿por qué se ralentizó la línea 2 después de comer?", y obtener respuestas basadas en datos reales de la planta. En esta guía aprenderás cómo se construye un copiloto así, por qué un árbol de topics ISA-95 bien estructurado es el ingrediente más importante y cómo conectar un copiloto de solo lectura a datos MQTT en vivo sin dejar que toque las máquinas.
Qué hace realmente un copiloto de IA industrial
La palabra "copiloto" se usa con poca precisión, así que conviene concretar. En una planta, un copiloto útil hace cuatro cosas:
- Responde preguntas de estado a partir de datos en vivo: velocidad actual, temperatura, estado de alarma, última pieza buena.
- Explica el contexto combinando valores en vivo con documentos: el procedimiento operativo para un código de fallo, el historial de mantenimiento de una bomba, la checklist de cambio de formato.
- Resume turnos, alarmas y paradas en un lenguaje que un supervisor puede pegar en una nota de relevo.
- Sugiere los siguientes pasos, pero deja la decisión y la acción en manos de una persona.
Lo que no debería hacer, al menos al principio, es emitir comandos. Un copiloto que lee es una herramienta de productividad. Un copiloto que escribe en los equipos es un sistema de control y requiere otro nivel de ingeniería, que tratamos en nuestra guía sobre control seguro de dispositivos IoT con IA.
El modelo de lenguaje de gran tamaño (LLM) en sí no sabe nada de tu planta. Todo lo que hace correcta la respuesta procede de los datos que le das en el momento de la pregunta. Por eso la arquitectura que rodea al modelo importa mucho más que la elección del modelo.
Por qué los datos en vivo estructurados superan a un volcado de datos
El enfoque ingenuo es exportar un CSV de tags y pegarlo en el prompt. Fracasa rápido: nombres de tag como PLC3_DB12_W4 no significan nada para un modelo, la instantánea está obsoleta cuando alguien lee la respuesta y la ventana de contexto se llena de valores irrelevantes.
Un espacio de nombres estructurado según ISA-95 resuelve los tres problemas. Cuando cada valor vive en una ruta como acme/plant1/assembly/line2/press4/temperature, la propia jerarquía aporta significado. El modelo puede ver que press4 pertenece a line2, que a su vez pertenece a assembly. Una pregunta sobre "la línea 2" se traduce de forma natural en el filtro de topic acme/plant1/assembly/line2/#. Es la misma idea que hay detrás del Unified Namespace, explicada en nuestro artículo sobre MQTT Sparkplug B y el Unified Namespace.
| Enfoque de datos | Actualidad | Significado para el LLM | Coste de contexto |
|---|---|---|---|
| Exportación de tags del PLC en bruto | Instantánea obsoleta | Bajo, nombres crípticos | Alto |
| Solo consultas al historiador | Bueno para el histórico, lento para el "ahora" | Medio | Medio |
| Topics MQTT ISA-95 con valores retenidos | En vivo | Alto, la jerarquía se describe sola | Bajo, filtro por subárbol |
| Topics ISA-95 más recuperación de documentos | En vivo más procedimientos | El más alto | De bajo a medio |
MQTT encaja de forma natural porque el broker ya guarda el último valor retenido de cada topic. Un servicio de copiloto puede suscribirse al subárbol que le interesa, mantener una instantánea en memoria y pasar al modelo solo la parte relevante para la pregunta.
Arquitectura de referencia para un copiloto de IA industrial
Una disposición práctica tiene cinco partes:
- Publicadores en el edge: gateways de PLC, nodos edge Sparkplug B o pequeños servicios Python publican los datos de las máquinas en el broker.
- El broker MQTT, en el centro. ConnectMQ detecta topics ISA-95 y de Unified Namespace, y puede decodificar payloads Sparkplug B y republicarlos en topics ISA-95 legibles; por ejemplo,
spBv1.0/factory1/DDATA/line1/cnc1se convierte enconnectmq/factory1/production/line1/cnc1/telemetry. Ese árbol republicado tiene exactamente la forma que un modelo de lenguaje maneja bien. - Un servicio de copiloto que se conecta al broker como un cliente MQTT corriente, se suscribe en modo de solo lectura y mantiene una instantánea en vivo.
- Herramientas que el LLM puede llamar, como
get_area_snapshot(path)olist_active_alarms(line). El modelo nunca consulta directamente el broker; se lo pide a tu código. - Un índice de documentos para procedimientos y manuales, que es el terreno de la generación aumentada por recuperación para datos industriales.
El servicio de copiloto es tu código, se ejecuta en tu infraestructura y habla con el proveedor de LLM que elijas. ConnectMQ es la capa de mensajería; no ejecuta el modelo. Esa separación es sana: puedes cambiar de modelo sin tocar la planta, y el mismo árbol de topics puede alimentar a la vez un gemelo digital 3D de la línea.
Si eres nuevo en el papel del broker dentro de este esquema, nuestro artículo sobre qué hace un broker MQTT es una introducción rápida.
Construir la capa de contexto en vivo en Python
El núcleo del copiloto es un pequeño servicio que refleja en memoria parte del árbol de topics y lo expone como herramienta. El ejemplo siguiente usa paho-mqtt 2.x y el servidor MQTT público gratuito para que puedas ejecutarlo de inmediato. Sustituye el prefijo por tu propio ID aleatorio.
import json
import threading
import time
import paho.mqtt.client as mqtt
BROKER = "broker.connectmq.com"
PREFIX = "connectmq/demo/k7f3q9/plant1" # usa tu propio id aleatorio
snapshot = {}
lock = threading.Lock()
def on_connect(client, userdata, flags, reason_code, properties):
print("connected:", reason_code)
client.subscribe(f"{PREFIX}/#", qos=1)
def on_message(client, userdata, msg):
try:
value = json.loads(msg.payload)
except ValueError:
value = msg.payload.decode(errors="replace")
with lock:
snapshot[msg.topic] = {"value": value, "received": time.time()}
def get_area_snapshot(path: str, max_age_s: int = 300) -> dict:
"""Tool exposed to the LLM: latest values under an ISA-95 path."""
base = f"{PREFIX}/{path.strip('/')}"
now = time.time()
with lock:
return {
topic[len(PREFIX) + 1:]: {
"value": entry["value"],
"age_s": round(now - entry["received"]),
"stale": now - entry["received"] > max_age_s,
}
for topic, entry in snapshot.items()
if topic == base or topic.startswith(base + "/")
}
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="copilot-reader-k7f3q9")
client.on_connect = on_connect
client.on_message = on_message
client.connect(BROKER, 1883, keepalive=60)
client.loop_start()
if __name__ == "__main__":
time.sleep(3)
print(json.dumps(get_area_snapshot("assembly/line2"), indent=2))
Para darle algo que leer, publica unos cuantos valores retenidos desde otra terminal:
mosquitto_pub -h broker.connectmq.com -p 1883 -i seed-k7f3q9 -r -q 1 \
-t connectmq/demo/k7f3q9/plant1/assembly/line2/press4/temperature -m '{"c": 71.4}'
mosquitto_pub -h broker.connectmq.com -p 1883 -i seed-k7f3q9 -r -q 1 \
-t connectmq/demo/k7f3q9/plant1/assembly/line2/press4/state -m '"RUNNING"'
Tres decisiones de diseño de ese código importan más de lo que parece:
- Cada valor se devuelve con su antigüedad y su estado de obsolescencia. Un LLM informará sin problema de una temperatura de hace dos horas como si fuera actual. Hacer explícita la obsolescencia permite al modelo decir "no hay datos recientes" en lugar de inventarse seguridad. Ten en cuenta que un valor retenido entregado al suscribirse recibe una marca de recepción nueva, así que para un control estricto de la obsolescencia incluye en el payload una marca de tiempo de origen.
- Las rutas son relativas y acotadas. La herramienta solo lee por debajo de
PREFIX, así que un modelo confundido no puede adentrarse en otros espacios de nombres. - El servicio es de solo lectura. Se suscribe y nunca publica en topics de equipos.
Después registras get_area_snapshot como herramienta (función) en la API de LLM que uses. Nuestra guía sobre function calling de LLM para IoT recorre el patrón de esquema de herramientas y, si prefieres una interfaz estándar, un servidor MCP para MQTT expone la misma capacidad a cualquier cliente compatible.
Escribir el prompt del copiloto para preguntas de planta
El prompt del sistema debe describir el espacio de nombres, no los datos. Algo así funciona bien:
You are an assistant for operators at plant1.
Live data is organised as <area>/<line>/<cell>/<signal>, for example assembly/line2/press4/temperature.
Use get_area_snapshot(path) to read live values. Never guess a value you did not read.
If a value is marked stale, say so. You cannot change any equipment. For actions, tell the operator what to check.
Answer in short sentences and quote the topic path for every number you mention.
Pedir al modelo que cite la ruta del topic de cada número es un hábito barato y potente. Los operarios pueden verificar cualquier afirmación en el explorador de topics en vivo, y las respuestas erróneas resultan fáciles de detectar y notificar.
Checklist de diseño de un copiloto de IA industrial
Antes de enseñar un copiloto a un equipo de turno, repasa esta lista:
- Calidad del espacio de nombres: ¿los topics tienen nombres coherentes hasta el nivel de señal, con unidades en el payload o en el nombre?
- Valores retenidos: ¿todos los topics de estado publican como retenidos, para que un nuevo suscriptor vea de inmediato los valores actuales?
- Credenciales de solo lectura: ¿el servicio de copiloto usa sus propias credenciales, que nunca se emplean para topics de comandos?
- Gestión de la obsolescencia: ¿cada resultado de herramienta incluye la antigüedad y el prompt indica al modelo que la respete?
- Trazabilidad: ¿cada respuesta cita rutas de topic o fuentes documentales?
- Registro: ¿se registran las preguntas, las llamadas a herramientas y las respuestas para su revisión?
- Alcance: ¿el copiloto está limitado a las líneas y áreas de las que es responsable el usuario?
- Escalado: ¿el copiloto indica al operario a quién llamar cuando no puede responder?
Errores comunes
Lecturas alucinadas. El modelo rellena los huecos con números plausibles. Contramedida: la instrucción de "nunca adivinar" más resultados de herramientas que muestren con claridad los datos ausentes.
Demasiado contexto. Volcar la planta entera en cada petición es lento y confunde al modelo. Deja que el modelo llame a la herramienta con una ruta acotada y resume las series numéricas antes de devolverlas.
Confusión de unidades. Un valor de 71.4 sin unidad invita a errores. Pon las unidades en el payload ({"c": 71.4}) o en metadatos que devuelva la herramienta.
Datos sensibles en brokers públicos. El área pública de broker.connectmq.com es legible por cualquiera que adivine el topic. Sirve para esta demo, pero los datos de planta en producción deben ir en un broker privado con sus propias credenciales.
Tratar al copiloto como una autoridad. Los operarios deben verlo como un compañero rápido que lee pantallas, no como el sistema de seguridad. Mantén la gestión de alarmas y los enclavamientos donde están.
Ejecutar el copiloto con datos de producción
Pasar de la demo a una línea real consiste sobre todo en cambiar la conexión. Crea un broker en el portal de ConnectMQ, copia las credenciales generadas y conéctate por TLS:
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="YOUR_CLIENT_ID")
client.username_pw_set("YOUR_USERNAME", "YOUR_PASSWORD")
client.tls_set() # el almacén de CA del sistema confía en el certificado de Let's Encrypt
client.connect("broker.connectmq.com", 8883, keepalive=60)
Un broker MQTT gestionado saca el broker de tu lista de cosas que parchear y monitorizar, para que el equipo pueda centrarse en la calidad del espacio de nombres y en el propio copiloto. Para una visión más amplia de cómo encajan la IA y la mensajería, consulta la guía de IA e IoT, y para las opciones de alojamiento lee sobre el enfoque de broker MQTT en la nube.
Dale a tu copiloto un espacio de nombres de planta en vivo
Un copiloto necesita una fuente de datos limpia, en vivo y bien estructurada antes que un modelo más grande. ConnectMQ te ofrece un broker MQTT gestionado con detección de topics ISA-95, decodificación de Sparkplug B y un explorador de topics en vivo para comprobar lo que ve el copiloto. Crea un broker Serverless gratuito en app.connectmq.com, sin tarjeta de crédito, y apunta a él el servicio de solo lectura anterior.
Preguntas frecuentes
¿Incluye ConnectMQ un copiloto de IA?
No. ConnectMQ es el broker MQTT que entrega los datos en vivo. El copiloto es tu propio servicio, que se conecta como cliente MQTT y llama al LLM que elijas.
¿Se debería permitir que un copiloto de IA industrial controle máquinas?
No al principio. Empieza en solo lectura, demuestra su precisión y utilidad, y solo más adelante añade acciones muy protegidas y confirmadas por personas, con listas permitidas, límites de frecuencia y registros de auditoría.
¿Por qué la estructura ISA-95 ayuda a un modelo de lenguaje?
La jerarquía de empresa, planta, área, línea y celda da a cada valor una ruta que se describe sola, de modo que el modelo puede traducir una pregunta sobre "la línea 2" en un filtro de topic preciso en lugar de adivinar a partir de nombres de tag crípticos.
¿Puede el copiloto usar también datos históricos?
Sí. Los valores MQTT en vivo responden a "qué está pasando ahora", mientras que un historiador o una base de datos de series temporales responde a "qué pasó". Expón cada uno como una herramienta independiente para que el modelo elija la fuente correcta.



