
Arrêtez d’utiliser les LLM comme des résolveurs de problèmes géants
sur une fonctionnalité où j’ai dû transformer 100 fichiers PDF de conformité désordonnés en règles JSON structurées.
L’approche par force brute était évidente : donner à l’agent le texte source, expliquer la tâche, fournir des exemples et lui demander de générer les règles. Comme c’était le fruit le plus facile à trouver, je l’ai essayé en premier.
En un coup d’œil, le résultat semblait correct. La sortie JSON était valide et correspondait à ce que j’attendais.
Mais alors que j’échantillonnais manuellement les résultats pour vérifier leur exactitude, des fissures sont apparues. Certaines règles étaient trop larges, d’autres n’étaient pas respectées. Certaines règles n’ont pas réussi à préserver les nuances du texte original. J’ai essayé d’utiliser un autre agent pour détecter et corriger les erreurs, mais avec un corpus aussi énorme, il était impossible de vérifier le résultat en toute confiance.
C’était la partie frustrante. Les erreurs n’étaient pas évidentes. C’était une mise en œuvre beaucoup trop fragile pour être mise à l’échelle.
Bien que je ne puisse pas partager les détails exacts de la mise en œuvre, je peux partager les leçons d’architecture que j’ai apprises et la manière dont je les ai finalement mises en œuvre. Espérons que ces informations seront utiles si vous construisez des systèmes d’IA qui doivent évoluer, rester fiables et gérer des données désordonnées. Et si vous avez de meilleures façons de faire les choses, contactez-nous pour discuter!
Bon, allons-y.
Le problème
Les 100 fichiers PDF avec lesquels j’ai travaillé avaient déjà été analysés et fragmentés avant de me parvenir. Mais le contenu brut était toujours désordonné. Il y avait des puces, des tableaux, des artefacts OCR, des sections traduites, des titres semi-structurés, des pieds de page, des en-têtes, un formatage incohérent et des bizarreries spécifiques au document.
J’ai choisi de faire appel à un agent car décider de ce qui comptait nécessitait un jugement sémantique. Les documents ne suivaient pas un modèle cohérent, de sorte que leur pertinence ne pouvait pas être déterminée uniquement au moyen de règles simples.
Il fallait comprendre le contexte environnant. Rien de tout cela n’était difficile lorsqu’il était réalisé sur un petit morceau de données. Le défi consistait à réaliser cela de manière fiable et à grande échelle.
Ces règles ont ensuite été traitées par un autre système en aval pour être évaluées de manière déterministe.
Ce qui a finalement fonctionné
Après quelques expériences, j’ai réalisé que la plus grande amélioration ne venait pas d’une meilleure invite, d’un nouvel outil, d’un serveur MCP ou d’un ensemble d’agents plus sophistiqués.
Cela venait du changement de forme du problème.
Au lieu d’essayer de rendre l’agent plus intelligent, j’ai réduit son travail.
Le premier changement a été de préparer les données sources à l’avance. Au lieu de demander à l’agent d’interroger une base de données, de récupérer des enregistrements, de décider si elle disposait des bonnes entrées, puis d’effectuer l’extraction, je lui ai donné un point de départ plus contrôlé.
Dans mon cas, cela signifiait stocker temporairement les données brutes pertinentes localement.
Cela n’est peut-être pas toujours pratique. Mais le principe sous-jacent est de réduire le degré d’incertitude de récupération que l’agent doit gérer. Si le travail de l’agent consiste à raisonner sur le contenu, ne lui confiez pas également la responsabilité de déterminer s’il a trouvé le bon contenu.
Une autre option serait de préparer la requête à l’avance.
J’ai également utilisé un script pour supprimer les métadonnées et les champs inutiles avant de transmettre le contenu brut à l’agent. Moins de contexte non pertinent signifiait moins de distractions, moins de chances pour l’agent de s’accrocher à de mauvais détails et une tâche de raisonnement plus claire dans l’ensemble.
Mais le changement le plus important concerne l’unité de travail.
Au lieu de tout traiter en même temps, j’ai fait les choses de manière itérative et traité un document à la fois.
Cela a rendu chaque tâche plus petite, plus facile à inspecter, plus facile à réessayer et plus facile à auditer. J’ai créé cinq sous-agents pour traiter les documents en parallèle, chaque agent enregistrant sa progression dans un fichier.
Si un document échouait, je ne pouvais réessayer que ce document. Si une sortie présentait des problèmes de formatage, je pourrais résoudre ce cas spécifique sans réexécuter l’ensemble du lot. Si le pipeline s’arrêtait à mi-chemin, la progression mise en cache signifiait qu’il pouvait reprendre à partir du dernier point de contrôle réussi.
C’est également là que la séparation des responsabilités est devenue plus claire.
L’agent s’est chargé du travail sémantique : comprendre le contenu, identifier les parties pertinentes et écrire la sortie JSON.
Le code environnant gérait les parties mécaniques : paralléliser les tâches, appliquer le schéma, générer des identifiants, écrire des fichiers, mettre en cache la progression, valider les références et vérifier si la sortie pouvait être retracée jusqu’à la source d’origine.
J’ai également demandé à un orchestrateur de surveiller l’avancement du scénario.
Rendre le résultat vérifiable
Une décision de conception utile consistait à ajouter des ID de référence à chaque règle générée. Cela signifiait que chaque élément de sortie renvoyait à une source spécifique.
Cela a rendu le résultat plus facile à auditer. Au lieu de demander : « Cette règle générée semble-t-elle correcte ? », je pourrais poser des questions plus précises telles que : le bloc source référencé existe-t-il ? Le texte source cité est-il réellement présent dans ce morceau ?
Je pourrais également demander à un autre agent d’effectuer des audits de manière sélective sur des documents plus volumineux et plus complexes afin de garantir que les nuances importantes soient préservées.
En plus de cela, j’ai fait une version allégée d’evals. J’ai exécuté un petit lot de documents bruts dans le flux de travail et j’ai examiné manuellement les résultats pour en vérifier la couverture et l’exactitude. Un ensemble de données complet n’était pas pratique pour l’étendue de cette tâche, mais j’avais quand même besoin d’un moyen de me prouver que le flux de travail fonctionnait.
Mon objectif n’était pas de créer une référence parfaite, mais de rendre le système suffisamment auditable pour que je puisse inspecter les sorties, détecter les échecs et itérer vers une barre de précision plus élevée.
Si vous avez des idées sur la façon dont j’aurais pu faire mieux, faites-le-moi savoir !
Mon plus gros point à retenir
Le modèle qui a fonctionné était d’arrêter de traiter le LLM comme un système dans son ensemble.
Le système est devenu plus fiable, non pas parce que l’agent est devenu parfait, mais parce que le flux de travail a rendu ses sorties plus faciles à tracer, à valider et à récupérer.
Par coïncidence, je construisais cela peu de temps avant d’assister à la conférence inaugurale AI Engineer Singapore, qui s’est tenue du 15 au 17 mai 2026.
Le dernier jour, JJ Geewax, directeur de l’IA appliquée chez Google DeepMind, a partagé un cadrage qui capture ce que j’avais appris à mes dépens : nous devons arrêter d’utiliser les LLM comme des résolveurs de problèmes géants.
Cela m’a interpellé parce que c’est un piège très facile dans lequel tomber. Il est facile de simplement donner au modèle les données, le schéma, les règles métier, les cas extrêmes et la responsabilité de se vérifier. Soyez ensuite frustré lorsque le résultat est incohérent.
Mais pour des systèmes de production fiables, le meilleur modèle est généralement un modèle hybride. Laissez l’agent gérer les parties qui nécessitent un jugement sémantique et laissez le code gérer les parties qui nécessitent une structure, une validation et un contrôle.
Je partagerai plus de réflexions sur AI Engineer Singapore et sur les ateliers auxquels j’ai assisté. L’extrait YouTube du discours de JJ ici.
C’est tout de moi. J’espère que cela vous a aidé, et à bientôt dans le prochain article 🙂



