IoT et IA

Copilote IA industriel pour les opérateurs : ancrer les réponses dans des données ISA-95 en direct

Un copilote IA industriel ne vaut que par les données qu'il voit. Ce guide montre comment ancrer un assistant pour opérateurs dans des topics MQTT structurés selon ISA-95 et alimentés en direct, pour des réponses actuelles, traçables et sûres.

Panneau de chat d'un copilote IA industriel à côté d'un tableau de bord de ligne de production lisant des topics MQTT ISA-95 en direct
Essayez-le sur votre propre broker MQTTObtenez un broker MQTT privé et managé avec l’offre Free et partez d’exemples de code prêts à l’emploi.
Essayer gratuitement Exemples de code Aucune carte bancaire requise

Un copilote IA industriel est un assistant qui permet aux opérateurs de poser des questions en langage courant, comme « pourquoi la ligne 2 a-t-elle ralenti après le déjeuner ? », et d'obtenir des réponses fondées sur les données réelles de l'usine. Dans ce guide, vous verrez comment un tel copilote est construit, pourquoi une arborescence de topics ISA-95 bien structurée en est l'ingrédient le plus important, et comment brancher un copilote en lecture seule sur des données MQTT en direct sans le laisser toucher aux machines.

Ce que fait réellement un copilote IA industriel

Le terme « copilote » est employé de façon assez vague, il est donc utile d'être précis. En usine, un copilote utile fait quatre choses :

  1. Il répond aux questions d'état à partir des données en direct : vitesse actuelle, température, état des alarmes, dernière pièce bonne.
  2. Il explique le contexte en combinant les valeurs en direct avec des documents : le mode opératoire associé à un code défaut, l'historique de maintenance d'une pompe, la check-list de changement de série.
  3. Il résume les postes, les alarmes et les arrêts dans une langue qu'un chef d'équipe peut coller dans une note de relève.
  4. Il suggère des étapes suivantes, mais laisse la décision et l'action à un humain.

Ce qu'il ne doit pas faire, du moins au début, c'est envoyer des commandes. Un copilote qui lit est un outil de productivité. Un copilote qui écrit vers les équipements est un système de contrôle-commande, et il exige un tout autre niveau d'ingénierie, que nous abordons dans notre guide sur le contrôle sécurisé des appareils IoT par l'IA.

Le grand modèle de langage (LLM) lui-même ne sait rien de votre usine. Tout ce qui rend la réponse correcte provient des données que vous lui fournissez au moment de la question. C'est pourquoi l'architecture autour du modèle compte bien plus que le choix du modèle.

Pourquoi des données en direct structurées valent mieux qu'un vidage de données

L'approche naïve consiste à exporter un CSV de variables et à le coller dans le prompt. Elle échoue vite : des noms de variables comme PLC3_DB12_W4 ne signifient rien pour un modèle, l'instantané est périmé dès que quelqu'un lit la réponse, et la fenêtre de contexte se remplit de valeurs sans rapport.

Un espace de noms structuré selon ISA-95 résout ces trois problèmes. Lorsque chaque valeur se trouve à un chemin comme acme/plant1/assembly/line2/press4/temperature, la hiérarchie elle-même porte du sens. Le modèle voit que press4 appartient à line2, qui appartient à assembly. Une question sur « la ligne 2 » correspond naturellement au filtre de topic acme/plant1/assembly/line2/#. C'est la même idée que celle de l'Unified Namespace présentée dans notre article sur MQTT Sparkplug B et l'Unified Namespace.

Approche des données Fraîcheur Sens pour le LLM Coût en contexte
Export brut des variables d'automate Instantané périmé Faible, noms cryptiques Élevé
Requête sur l'historien uniquement Bonne pour l'historique, lente pour « maintenant » Moyen Moyen
Topics MQTT ISA-95 avec valeurs en retained message En direct Élevé, la hiérarchie se décrit d'elle-même Faible, filtrage par sous-arborescence
Topics ISA-95 plus recherche documentaire En direct plus procédures Le plus élevé Faible à moyen

MQTT s'y prête naturellement, car le broker conserve déjà la dernière valeur en retained message de chaque topic. Un service copilote peut s'abonner à la sous-arborescence qui l'intéresse, maintenir un instantané en mémoire et ne transmettre au modèle que la partie utile à la question.

Architecture de référence d'un copilote IA industriel

Une organisation pratique comporte cinq éléments :

  1. Les publieurs en périphérie : passerelles d'automates, edge nodes Sparkplug B ou petits services Python publient les données machines vers le broker.
  2. Le broker MQTT au centre. ConnectMQ détecte les topics ISA-95 et Unified Namespace, et peut décoder les payloads Sparkplug B pour les republier dans des topics ISA-95 lisibles : par exemple, spBv1.0/factory1/DDATA/line1/cnc1 devient connectmq/factory1/production/line1/cnc1/telemetry. Cette arborescence republiée a exactement la forme qu'un modèle de langage manipule bien.
  3. Un service copilote qui se connecte au broker comme un client MQTT ordinaire, s'abonne en lecture seule et maintient un instantané en direct.
  4. Des outils que le LLM peut appeler, comme get_area_snapshot(path) ou list_active_alarms(line). Le modèle n'interroge jamais directement le broker ; il passe par votre code.
  5. Un index documentaire pour les procédures et les manuels, qui relève de la génération augmentée par récupération pour les données industrielles.

Le service copilote est votre code, qui tourne sur votre infrastructure et dialogue avec le fournisseur de LLM de votre choix. ConnectMQ est la couche de messagerie ; il n'exécute pas le modèle. Cette séparation est saine : vous pouvez changer de modèle sans toucher à l'usine.

Si le rôle du broker dans ce schéma est nouveau pour vous, notre article sur le rôle d'un broker MQTT constitue une introduction rapide.

Construire la couche de contexte en direct en Python

Le cœur du copilote est un petit service qui reflète en mémoire une partie de l'arborescence de topics et l'expose sous forme d'outil. L'exemple ci-dessous utilise paho-mqtt 2.x et le serveur MQTT public gratuit, réservé aux tests et aux prototypes, pour que vous puissiez l'exécuter immédiatement. Remplacez le préfixe par votre propre identifiant aléatoire.

import json
import threading
import time
import paho.mqtt.client as mqtt

BROKER = "broker.connectmq.com"
PREFIX = "connectmq/demo/k7f3q9/plant1"   # use your own random id
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))

Pour lui donner quelque chose à lire, publiez quelques valeurs en retained message depuis un autre 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"'

Trois choix de conception dans ce code comptent plus qu'il n'y paraît :

  • L'âge et la péremption sont renvoyés avec chaque valeur. Un LLM rapportera volontiers une température vieille de deux heures comme actuelle. Rendre la péremption explicite permet au modèle de dire « pas de données récentes » au lieu d'afficher une confiance inventée. Notez qu'une valeur en retained message livrée au moment de l'abonnement reçoit un horodatage de réception récent : pour une péremption stricte, incluez un horodatage source dans le payload.
  • Les chemins sont relatifs et circonscrits. L'outil ne lit jamais qu'en dessous de PREFIX, si bien qu'un modèle désorienté ne peut pas s'aventurer dans d'autres espaces de noms.
  • Le service est en lecture seule. Il s'abonne et ne publie jamais sur les topics des équipements.

Vous enregistrez ensuite get_area_snapshot comme outil (fonction) auprès de l'API de LLM que vous utilisez. Notre guide sur le function calling LLM pour l'IoT détaille le pattern de schéma d'outil, et si vous préférez une interface standard, un serveur MCP pour MQTT expose la même capacité à tout client compatible.

Rédiger le prompt du copilote pour les questions d'usine

Le prompt système doit décrire l'espace de noms, pas les données. Un texte comme celui-ci fonctionne 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.

Demander au modèle de citer le chemin du topic pour chaque chiffre est une habitude peu coûteuse et très efficace. Les opérateurs peuvent vérifier n'importe quelle affirmation dans l'explorateur de topics en direct, et les mauvaises réponses deviennent faciles à repérer et à signaler.

Check-list de conception d'un copilote IA industriel

Avant de présenter un copilote à une équipe de poste, passez en revue cette liste :

  1. Qualité de l'espace de noms : les topics sont-ils nommés de façon cohérente jusqu'au niveau du signal, avec les unités dans le payload ou dans le nom ?
  2. Retained messages : chaque topic d'état est-il publié en retained message, afin qu'un nouvel abonné voie immédiatement les valeurs actuelles ?
  3. Identifiants en lecture seule : le service copilote utilise-t-il ses propres identifiants, jamais employés pour les topics de commande ?
  4. Gestion de la péremption : chaque résultat d'outil inclut-il l'âge, et le prompt demande-t-il au modèle d'en tenir compte ?
  5. Traçabilité : chaque réponse cite-t-elle les chemins de topics ou les sources documentaires ?
  6. Journalisation : les questions, appels d'outils et réponses sont-ils journalisés pour être revus ?
  7. Périmètre : le copilote est-il limité aux lignes et zones dont l'utilisateur est responsable ?
  8. Escalade : le copilote indique-t-il à l'opérateur qui appeler lorsqu'il ne peut pas répondre ?

Pièges courants

Mesures hallucinées. Le modèle comble les trous avec des chiffres plausibles. Contre-mesure : l'instruction « ne jamais deviner » et des résultats d'outils qui montrent clairement les données manquantes.

Trop de contexte. Déverser toute l'usine dans chaque requête est lent et embrouille le modèle. Laissez le modèle appeler l'outil avec un chemin restreint, et résumez les séries numériques avant de les renvoyer.

Confusion d'unités. Une valeur 71.4 sans unité invite à l'erreur. Placez les unités dans le payload ({"c": 71.4}) ou dans les métadonnées renvoyées par l'outil.

Données sensibles sur un serveur public. La zone publique du serveur MQTT public gratuit broker.connectmq.com est lisible par quiconque devine le topic. C'est sans importance pour cette démo, mais les données de production d'une usine ont leur place sur un broker privé avec ses propres identifiants.

Considérer le copilote comme une autorité. Les opérateurs doivent le voir comme un collègue rapide qui lit les écrans, pas comme le système de sécurité. Laissez la gestion des alarmes et les verrouillages là où ils sont.

Exécuter le copilote sur des données de production

Passer de la démo à une vraie ligne revient surtout à changer la connexion. Créez un broker dans le portail ConnectMQ, copiez les identifiants générés et connectez-vous via TLS :

client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="YOUR_CLIENT_ID")
client.username_pw_set("YOUR_USERNAME", "YOUR_PASSWORD")
client.tls_set()  # system CA store trusts the Let's Encrypt certificate
client.connect("broker.connectmq.com", 8883, keepalive=60)

Un broker MQTT managé retire le broker de la liste des éléments à mettre à jour et à surveiller, et l'équipe peut se concentrer sur la qualité de l'espace de noms et sur le copilote lui-même. Pour une vue plus large de l'articulation entre IA et messagerie, consultez le guide IA et IoT, et pour les options d'hébergement, lisez notre article sur l'approche du broker MQTT cloud.

Donnez à votre copilote un espace de noms d'usine en direct

Un copilote a besoin d'une source de données propre, en direct et bien structurée avant d'avoir besoin d'un plus gros modèle. ConnectMQ vous offre un broker MQTT managé avec détection des topics ISA-95, décodage Sparkplug B et un explorateur de topics en direct pour vérifier ce que voit le copilote. Créez un broker Serverless (Free) sur app.connectmq.com, sans carte bancaire, et connectez-y le service en lecture seule présenté ci-dessus.

Questions fréquentes

ConnectMQ inclut-il un copilote IA ?

Non. ConnectMQ est le broker MQTT qui achemine les données en direct. Le copilote est votre propre service, qui se connecte en tant que client MQTT et appelle le LLM de votre choix.

Un copilote IA industriel doit-il pouvoir piloter des machines ?

Pas au début. Commencez en lecture seule, prouvez sa précision et son utilité, puis n'ajoutez que plus tard des actions strictement encadrées et confirmées par un humain, avec listes autorisées, limites de débit et journaux d'audit.

Pourquoi la structure ISA-95 aide-t-elle un modèle de langage ?

La hiérarchie entreprise, site, zone, ligne et cellule donne à chaque valeur un chemin qui se décrit de lui-même : le modèle peut ainsi associer une question sur « la ligne 2 » à un filtre de topic précis au lieu de deviner à partir de noms de variables cryptiques.

Le copilote peut-il aussi utiliser des données historiques ?

Oui. Les valeurs MQTT en direct répondent à « que se passe-t-il maintenant », tandis qu'un historien ou une base de données de séries temporelles répond à « que s'est-il passé ». Exposez chacun sous forme d'outil distinct pour que le modèle choisisse la bonne source.

Articles liés

Tous les articles →

Votre broker MQTT privé, à quelques clics

Créez un compte, récupérez les identifiants de votre broker et connectez votre premier appareil — aucun serveur à installer, mettre à jour ou dimensionner.