Une IA qui analyse les données des usines produit parfois des résultats faux mais convaincants. Voici comment une architecture hybride corrige le problème.

UNE IA QUI DONNE DES RÉSULTATS FAUX, MÊME AVEC LES MEILLEURES TECHNOLOGIES

Une entreprise a créé un réseau d’agents d’IA pour conseiller des usines sur l’amélioration de leurs opérations. Les utilisateurs pouvaient télécharger des fichiers Excel avec des données d’évaluation directement dans une interface de chat. Le premier prototype semblait fonctionner parfaitement au début.

Sauf que la plupart des résultats étaient faux . Pire encore, l’IA apprenait rapidement à générer des chiffres qui semblaient plausibles mais étaient inventés. Avec le langage fluide des modèles comme les LLM (Large Language Models), ces résultats trompeurs passaient pour des vérités. Et ce problème n’était pas limité à un seul modèle : ChatGPT, Gemini Enterprise, DIA Brain et Microsoft Copilot présentaient tous les mêmes défauts.

Les données plausibles ne suffisent pas. Les systèmes d’IA en entreprise ont besoin de données fiables .

POURQUOI LES IA PUREMENT PROBABILISTES ÉCHOUENT SUR LES ANALYSES DE DONNÉES

L’enquête a révélé des modes de défaillance récurrents. Même avec l’activation du Code Interpreter, ces systèmes produisaient des résultats incorrects. Pourtant, le Code Interpreter est conçu pour exécuter du code Python et garantir des calculs précis. Alors pourquoi ces erreurs ?

Le problème vient du fait que les LLM excellent dans l’interprétation et l’interaction, mais ils ne sont pas adaptés pour les analyses de données fondamentales. Ces analyses nécessitent une exécution déterministe, c’est-à-dire des calculs reproductibles et fiables à 100 %. Or, les modèles probabilistes introduisent des variations aléatoires, même minimes, qui faussent les résultats.

LE CAS D’USAGE : CONSEILLER LES USINES POUR AMÉLIORER LEURS PERFORMANCES

Bien que le cas d’usage spécifique soit secondaire, il est utile de le comprendre pour saisir le défi architectural sous-jacent. L’objectif principal de l’agent d’IA est d’aider les usines et les flux de valeur à améliorer leur maturité opérationnelle : optimiser les processus, augmenter la productivité, réduire les niveaux de stock et, finalement, diminuer les coûts opérationnels.

Pour y parvenir, l’agent fonctionne en deux modes :

  • Un mode conversationnel où l’utilisateur discute avec l’agent pour obtenir des idées et des recommandations.
  • Un mode analytique où l’agent doit traiter et analyser des données d’évaluation de manière fiable.

Dans le second mode, l’agent doit être capable de traiter des fichiers Excel sans préparation manuelle préalable. Cependant, la structure de ces fichiers est complexe : plus de 800 colonnes, dont plus de 160 champs de texte libre avec des observations qualitatives, des forces, des faiblesses et des recommandations des évaluateurs.

LA SOLUTION : SÉPARER L’ANALYSE DÉTERMINISTE DU RAISONNEMENT PAR IA

L’idée centrale pour surmonter ce défi analytique a été de clairement séparer l’analyse de données déterministe du raisonnement et de l’interprétation par LLM. La figure 2 montre l’architecture du système après plusieurs itérations d’amélioration. Ce système a été implémenté dans Microsoft Copilot Studio car cette plateforme permet de combiner des éléments de workflow déterministe, comme des sujets et des flux, avec des composants basés sur des LLM.

L’agent parent gère toute la communication avec l’utilisateur. Il coordonne les sous-agents et le module d’analyse, délègue les tâches, reçoit leurs réponses et compose la réponse finale.

Les sous-agents sont des modules spécialisés basés sur des LLM avec accès à des sources de connaissances spécifiques. Ces sources incluent des descriptions des attentes de niveau de maturité pour les flux de valeur, des questionnaires avec des questions d’évaluation détaillées, et des directives générales pour l’excellence opérationnelle. Les sous-agents sont appelés par l’agent parent selon leurs capacités spécifiques et répondent à l’agent parent plutôt qu’à l’utilisateur directement.

Le module d’analyse est le principal sujet de cet article. Il effectue l’analyse de données déterministe et est conçu pour fournir des résultats analytiques reproductibles et fiables. Il reçoit une instruction d’analyse en langage naturel de l’agent parent, appelée Parent_Instruction. Le module d’analyse lui-même est composé de sujets, de flux et de modules d’IA, appelés prompts dans Copilot Studio.

LE MODULE D’ANALYSE : DEUX COMPOSANTS CLÉS POUR DES RÉSULTATS FIABLES

1. LE SUJET TRECEIVEEXCEL_FILE : GÉRER LE TÉLÉCHARGEMENT DES FICHIERS

Le sujet TreceiveExcel_File gère le téléchargement et le stockage des fichiers d’évaluation. Il est déclenché lorsque qu’un fichier est téléchargé dans la fenêtre de chat, indiqué par la variable System.Activity.Attachments ayant une valeur. Le sujet vérifie si le fichier téléchargé est un fichier Excel et, si c’est le cas, le stocke dans la variable globale Assessment_File.

2. LE SUJET TANALYZEASSESSMENTS : TRADUIRE LES DEMANDES EN RÈGLES D’ANALYSE

Le sujet Tanalyzeassessments est activement appelé par l’agent parent s’il a une tâche d’analyse à effectuer et reçoit Parent_Instruction en entrée. Une seconde entrée est le fichier d’évaluation stocké dans la variable globale Assessment_File. Ce sujet contient les deux composants analytiques principaux : Analysis_Planner et Analysis_Engine. Tous deux sont intégrés dans des flux agentiques, FCallAnalysis_Planner et FCallAnalysis_Engine. Ces flux servent de connecteurs entre le sujet Tanalyzeassessments et les prompts d’IA PAnalysisPlanner et PAnalysisEngine.

3. LE FLUX FCALLANALYSIS_PLANNER : TRANSFORMER LES DEMANDES EN RÈGLES

Le flux FCallAnalysis_Planner reçoit une seule entrée : Parent_Instruction, et la transmet au prompt PAnalysisPlanner. Ce composant génère la Selection_Rule, l’instruction d’analyse principale à exécuter par PAnalysisEngine. Le fonctionnement interne de PAnalysisPlanner est détaillé dans la section suivante.

4. LE FLUX FCALLANALYSIS_ENGINE : EXÉCUTER LES ANALYSES DE MANIÈRE DÉTERMINISTE

Le flux FCallAnalysis_Engine reçoit trois entrées : la Selection_Rule générée par Analysis_Planner, un Mapping_File fourni depuis SharePoint, et le fichier Assessment_File. Ces trois entrées sont transmises au prompt d’IA PAnalysisEngine, qui effectue l’analyse des données comme spécifié par Analysis_Planner.

L’ANALYSIS_PLANNER : TRADUIRE LES DEMANDES EN LANGAGE NATUREL EN RÈGLES STRUCTURÉES

Analysis_Planner est la partie intelligente du pipeline d’analyse et génère l’instruction d’analyse, appelée Selection_Rule. Cette instruction est une traduction de la Parent_Instruction en langage naturel et est généralement unique pour chaque demande. Pour minimiser les variations probabilistes, le processus de traduction est contraint par des règles strictes.

Analysis_Planner n’analyse pas lui-même les données d’évaluation. Sa seule responsabilité est de traduire la Parent_Instruction probabiliste en une spécification d’analyse déterministe.

Voici un exemple de Parent_Instruction : « Résume les potentiels d’amélioration pour le chapitre 1.4 Système de Prévention des Défaillances dans l’usine AbcP. »

À partir de cette instruction, Analysis_Planner doit déterminer :

  • Le type d’analyse requis (par exemple, résumé textuel).
  • Les catégories de contenu d’évaluation pertinentes (par exemple, « potentiel »).
  • Si la maturité conceptuelle ou d’exécution est demandée.
  • Si des chapitres spécifiques sont mentionnés.
  • Si des filtres de lignes sont nécessaires (par exemple, filtrer par usine).

Le résultat est une Selection_Rule au format JSON, qui sera utilisée par Analysis_Engine avec le fichier de données réel et le Mapping_File pour exécuter l’analyse de manière déterministe.

LA STRUCTURE DE LA SELECTION_RULE : UNE RECETTE PRÉCISE POUR L’ANALYSE

La Selection_Rule suit un format JSON strict. Voici un exemple de sortie réussie :

{
  "status": "success",
  "parentinstructionsummary": "Summarize improvement potentials for chapter 1.4 Failure Prevention System in plant AbcP.",
  "selection_rule": {
    "analysistype": "textsummary",
    "targetselectionrules": {
      "data_category": ["potential"],
      "aggregation_allowed": ["summary"],
      "concept_execution": null,
      "chapter_id": ["1.4"]
    },
    "row_filters": {
      "Plant": ["AbcP"]
    }
  },
  "warnings": []
}

Si la tâche n’est pas claire, Analysis_Planner retourne une erreur :

{
  "status": "error",
  "parentinstructionsummary": "",
  "selection_rule": {
    "analysis_type": null,
    "targetselectionrules": {
      "data_category": [],
      "aggregation_allowed": [],
      "concept_execution": null,
      "chapter_id": null
    },
    "row_filters": {}
  },
  "warnings": [
    "The analysis task is not clearly understood."
  ]
}

Les champs clés de la Selection_Rule sont :

  • analysis_type : Définit le type d’analyse (« numericmean » pour les moyennes numériques, « textsummary » pour les résumés textuels).
  • targetselectionrules : Spécifie les catégories de données à analyser et les règles d’agrégation.
  • row_filters : Définit les filtres à appliquer aux lignes du jeu de données (par exemple, filtrer par usine ou par flux de valeur).

LES CATÉGORIES SÉMANTIQUES : UNE COUCHE D’ABSTRACTION POUR SIMPLIFIER L’ANALYSE

Le Mapping_File définit les catégories sémantiques utilisées pour filtrer les lignes et sélectionner les colonnes à analyser. Par exemple :

Catégories de filtres de lignes (pour row_filters uniquement) :

  • VS_Nr : Identifiant unique du flux de valeur. Utilisé pour filtrer par numéro de flux de valeur.
  • Value Stream : Nom du flux de valeur. Utilisé pour filtrer par nom de flux de valeur.

Catégories de contenu cible (pour targetselectionrules.data_category) :

  • chapter_score : Score de maturité numérique. Utilisé pour les calculs de maturité, l’analyse des scores et les moyennes de maturité.
  • strength : Déclarations des évaluateurs décrivant les forces.
  • potential : Potentiels d’amélioration identifiés.
  • recommendation : Recommandations des évaluateurs.
  • remark : Remarques des évaluateurs.

Attributs de sélection cible (à l’intérieur de targetselectionrules) :

  • data_category : Définit quelle catégorie de contenu cible est nécessaire.
  • aggregation_allowed : Spécifie le type d’agrégation autorisé (« mean » pour les moyennes numériques, « summary » pour les résumés textuels).
  • chapter_id : Identifiant du chapitre à analyser.

Cette couche d’abstraction sémantique est cruciale car le jeu de données d’évaluation contient plus de 800 colonnes. Sélectionner les bonnes colonnes manuellement serait impossible et source d’erreurs.

LES RÈGLES POUR L’ANALYSIS_ENGINE : EXÉCUTER LES CALCULS DE MANIÈRE PRÉCISE

Analysis_Engine est un exécuteur d’analyses déterministe basé sur pandas. Il reçoit trois entrées :

  • document : Le fichier Excel contenant les données d’évaluation.
  • Mapping_File : Le fichier Excel décrivant les colonnes du document.
  • Selection_Rule : Un objet JSON définissant quelles colonnes sélectionner, quels filtres appliquer et quel type d’analyse effectuer.

Analysis_Engine doit exécuter le script Python déterministe suivant sans réinterpréter la demande originale, sans inférer de colonnes supplémentaires, sans modifier la Selection_Rule et sans générer une nouvelle approche d’analyse. Il ne fait qu’exécuter le script.

Voici les règles pour Selection_Rule :

Pour analysistype = "numericmean" :

  • Calculer les moyennes arithmétiques pour toutes les colonnes numériques sélectionnées.

Pour analysistype = "textsummary" :

  • Collecter les entrées de texte non vides de toutes les colonnes de texte sélectionnées.

Pour targetselectionrules :

  • Sélectionner les colonnes cibles en faisant correspondre les attributs du Mapping_File.
  • Une valeur de règle null signifie : ne pas filtrer par cet attribut.
  • Une liste signifie : conserver les lignes où l’attribut du Mapping_File est dans la liste.

Pour row_filters :

  • Appliquer les filtres de lignes au document.
  • Les clés sont des valeurs de data_category du Mapping_File, comme « Plant », « Region », « Production Principle », « Season ».
  • Les valeurs sont des listes de valeurs acceptées.

LE SCRIPT PYTHON DÉTERMINISTE : COMMENT ÇA MARCHE EN DÉTAIL

Le script Python utilisé par Analysis_Engine suit ces étapes :

1. Charger les fichiers Excel :

mappingdf = pd.readexcel(Mapping_File)
datadf = pd.readexcel(document)

mappingdf = stripcolumnnames(mappingdf)
datadf = stripcolumnnames(datadf)

2. Filtrer les colonnes cibles selon targetselectionrules :

targetmapping = mappingdf.copy()

for attr, rulevalue in targetselection_rules.items():
    values = normalizerulevalue(rule_value)
    values = normalizelistfor_matching(values)

    if values is None:
        continue

    targetmapping = targetmapping[
        target_mapping[attr]
        .apply(normalizeformatching)
        .isin(values)
    ]

selectedtargetcolumns = (
    targetmapping["sourcecolumn_name"]
    .dropna()
    .tolist()
)

3. Filtrer les lignes selon row_filters :

filtereddf = datadf.copy()

for filtercategory, filtervalues in row_filters.items():
    filtermapping = mappingdf[
        mappingdf["datacategory"]
        .apply(normalizeformatching)
        == normalizeformatching(filter_category)
    ]

    filtercol = filtermapping["sourcecolumnname"].iloc[0]

    filtereddf = filtereddf[
        filtereddf[filtercol]
        .apply(normalizeformatching)
        .isin(filter_values)
    ]

4. Exécuter l’analyse selon analysis_type :

Pour analysistype = "numericmean" :

if analysistype == "numericmean":
    numeric_result = {}

    for col in availabletargetcolumns:
        series = pd.tonumeric(filtereddf[col], errors="coerce")
        valid_count = int(series.notna().sum())

        numeric_result[col] = {
            "mean": float(series.mean()) if valid_count > 0 else None,
            "validcount": validcount
        }

    result["result"] = numeric_result

Pour analysistype = "textsummary" :

elif analysistype == "textsummary":
    text_result = {}

    for col in availabletargetcolumns:
        values = [
            cleantextvalue(v)
            for v in filtered_df[col].tolist()
        ]

        values = [v for v in values if v is not None]

        text_result[col] = {
            "entries": values,
            "entry_count": len(values)
        }

    result["result"] = text_result

5. Retourner le résultat au format JSON :

print(json.dumps(result, indent=2, ensure_ascii=False))

EXEMPLE CONCRET : ANALYSER LES POTENTIELS D’AMÉLIORATION D’UN SYSTÈME DE PRÉVENTION DES DÉFAILLANCES

Prenons un exemple concret pour illustrer le processus. La demande est : « Résume les potentiels d’amélioration pour le chapitre 1.4 Système de Prévention des Défaillances dans l’usine AbcP. »

Voici comment Analysis_Planner génère la Selection_Rule :

{
  "status": "success",
  "parentinstructionsummary": "Summarize improvement potentials for chapter 1.4 Failure Prevention System in plant AbcP.",
  "selection_rule": {
    "analysistype": "textsummary",
    "targetselectionrules": {
      "data_category": ["potential"],
      "aggregation_allowed": ["summary"],
      "concept_execution": null,
      "chapter_id": ["1.4"]
    },
    "row_filters": {
      "Plant": ["AbcP"]
    }
  },
  "warnings": []
}

Les colonnes cibles sélectionnées sont :

["1.4 CON L2 Improvement potentials", "1.4 CON L3 Improvement potentials", "1.4 EXE L2 Improvement potentials", "1.4 EXE L3 Improvement potentials"]

Après application des filtres et nettoyage des données, Analysis_Engine retourne le résultat suivant :

{
  "entry_count": 6,
  "entries": [
    "Root causes are not systematically tracked.",
    "Escalation rules for recurring failures are unclear.",
    "Lessons learned are not transferred between shifts.",
    "Preventive maintenance findings are not integrated into CIP activities.",
    "Failure trends are visualized inconsistently.",
    "Problem-solving activities focus mainly on symptoms instead of root causes."
  ]
}
Les résultats montrent que le système de prévention des défaillances est actuellement plus réactif que préventif. La plupart des lacunes concernent la gestion systématique des causes racines et l’apprentissage organisationnel entre les équipes et les quarts de travail.

Les améliorations les plus impactantes viendraient probablement du renforcement des routines d’escalade, de l’intégration des résultats de maintenance préventive dans les activités CIP, et de l’établissement de mécanismes d’apprentissage cohérents entre les quarts.

POURQUOI CETTE ARCHITECTURE HYBRIDE CHANGE LA DONNE POUR LES ENTREPRISES

Cette approche hybride combine le meilleur des deux mondes :

  • La précision des analyses déterministes : Grâce à des règles strictes et à l’exécution de code Python, les résultats sont toujours fiables et reproductibles.
  • La flexibilité des LLM : Les sous-agents spécialisés peuvent interpréter des demandes complexes en langage naturel et générer des recommandations pertinentes.

Les entreprises qui adoptent cette architecture peuvent éviter les pièges des analyses fausses mais plausibles. Elles bénéficient d’un système où la partie critique (l’analyse des données) est protégée contre les erreurs, tandis que la partie créative (l’interprétation et la recommandation) reste fluide et naturelle.

Les systèmes d’IA en entreprise doivent allier la puissance des LLM pour l’interaction et la précision des calculs déterministes pour les données. C’est la seule façon de garantir des résultats fiables.

Cette architecture est particulièrement adaptée aux secteurs où la précision des données est cruciale, comme l’industrie, la santé ou la finance. Elle montre que l’IA ne doit pas être une boîte noire, mais un outil transparent et maîtrisable.

Sources :
  • Towards Data Science

L'indépendance de CLODCO est votre garantie.

Pour que l'actualité de l'IA reste sans filtre et sans concession, votre soutien est indispensable. Votre contribution est le seul moteur de notre liberté éditoriale.

Soutenir CLODCO