Brief IA

LLMs Disrupt: A Recovery Layer for Support

🔬 Research·Tom Levy·

LLMs Disrupt: A Recovery Layer for Support

LLMs Disrupt: A Recovery Layer for Support
Key Takeaways
1Large language models (LLMs) disrupt agent pipelines due to their technical limitations.
2A retrieval layer has been developed to classify failures and adapt payloads between models.
3This solution preserves execution state and maintains schema integrity during exchanges between providers.
💡Why it mattersThis innovation could stabilize systems using LLMs, avoiding costly interruptions and data errors.
Le brief IA que lisent les pros

Le brief IA que les pros lisent chaque soir

Les 7 actus IA du jour, décryptées en 5 min. Gratuit.

Inclus dès l'inscription : notre sélection des meilleurs guides & comparatifs IA.

Choisis ton rythme

Gratuit · Pas de spam · Désabonnement en 1 clic

📄
Full Analysis

Les LLM perturbent : une couche de récupération en renfort

Les modèles de langage de grande taille

Les LLM (Large Language Models) peuvent perturber les pipelines d'agents. J'ai construit une couche de récupération manquante pour préserver l'intégrité du schéma lors des basculements.

Ne vous contentez pas de mettre vos agents en pause. Ils endommagent votre structure de données si vous changez de modèle sans modifier la charge utile.

Un routeur de secours basique affiche un taux de complétion de 100% sur votre tableau de bord, mais réduit l'intégrité du schéma à 0%. Le pipeline se termine, mais la sortie est corrompue.

Pour corriger cela, le moteur détecte l'erreur, reconstruit la charge utile pour le modèle de secours et sauvegarde les progrès de l'agent avant le basculement. Les benchmarks ci-dessous fonctionnent sur Python 3.12 sans dépendances externes.

Le moment où tout a échoué

Je construisais un pipeline à trois agents pour EmiTechLogic : un Planificateur, un Exécuteur et un Validateur fonctionnant séquentiellement, chacun alimentant la sortie JSON structurée au suivant. Le pipeline fonctionnait bien en test. Charges légères, réponses propres, aucune surprise.

Puis je l'ai exécuté dans des conditions réalistes.

La première étape, le Planificateur, s'est terminée. La deuxième étape, l'Exécuteur, a atteint une limite de taux 429 en cours de route. Ma boucle de réessai basique a détecté l'erreur, a basculé vers un modèle de secours et a continué à fonctionner. Le pipeline a signalé une complétion de 100%. Aucune exception n'a été levée. Aucun journal d'erreurs.

Mais lorsque j'ai vérifié la sortie en aval, la clé de confiance manquait. Le champ de résultat était juste une chaîne : « incomplet – incompatibilité de schéma lors du basculement ». Le Validateur a reçu une entrée structurellement corrompue et n'avait aucun moyen de le savoir. Le pipeline s'est terminé sur le papier, mais les données étaient inutilisables.

C'est le mode de défaillance dont cet article parle. Pas le 429 lui-même, ni la boucle de réessai. Le problème est ce qui se passe lorsque vous remettez un modèle de secours une charge utile inchangée formatée pour un moteur complètement différent.

Pourquoi cette défaillance est-elle si difficile à voir

Les tableaux de bord de surveillance standard cachent ce bogue car ils ne suivent que l'achèvement du processus. Ils vérifient si l'API a renvoyé un 200 et si le fil s'est terminé proprement. Si le script se termine, le tableau de bord devient vert. Pour les systèmes multi-agents, le temps de fonctionnement est la mauvaise métrique.

La métrique qui compte est l'intégrité du schéma. Un pipeline qui se termine silencieusement avec des champs corrompus est souvent pire qu'un crash brutal. Un crash force une correction immédiate, tandis que la corruption silencieuse des données s'insinue directement dans votre base de données sans être remarquée.

Ces agents sont étroitement couplés. L'Exécuteur s'attend à ce que les clés JSON exactes du Planificateur soient présentes, et le Validateur s'attend aux clés de l'Exécuteur. Lorsqu'un changement de modèle casse la structure à l'étape deux, cette étape ne lève pas d'erreur. Elle passe simplement les données malformées en aval, ruinant la sortie finale quelque part en aval où vous ne regardez pas.

La limitation de taux n'est pas un problème d'infrastructure réseau basique. C'est un problème d'intégrité des données.

L'anatomie d'un échec silencieux du pipeline

Le mécanisme de défaillance est silencieux mais destructeur.

Les contrats API sont complètement incohérents entre les différents niveaux de modèle. Un modèle premium impose un mode JSON strict et utilise un tableau de prompt système dédié. Un niveau de secours moins cher peut ne pas prendre en charge un champ système isolé, vous obligeant à fusionner les instructions directement dans le texte utilisateur. Il ne garantit également que rarement des sorties JSON structurées.

Lorsqu'un routeur basique détecte un 429 et change l'ID du modèle, il transfère la charge utile de la demande originale sans changement. Le modèle de secours reçoit une configuration qu'il ne peut pas analyser. La requête réseau réussit parce que l'API a techniquement renvoyé du texte. Aucune exception n'est levée. Le pipeline continue de fonctionner, mais la structure des données est déjà ruinée. L'agent suivant reçoit simplement du texte brut ou des clés manquantes au lieu d'un JSON valide.

Construire une couche de récupération qui comprend réellement le contexte

J'ai divisé la logique en quatre parties. Chacune a un seul travail et rien d'autre.

La première réalisation : toutes les défaillances ne sont pas les mêmes.

Un routeur basique traite chaque erreur API comme un déclencheur pour changer ou réessayer. Cette logique échoue instantanément en cas de dépassement de contexte ou de problèmes de facturation.

Vous devez séparer les causes profondes. Un 429 signifie que le modèle est temporairement limité, donc vous changez et réessayez ailleurs. Un dépassement de contexte signifie que le prompt lui-même est trop grand, donc un réessai est juste une perte de jetons car la charge utile doit d'abord être réduite. Une baisse de quota de facturation signifie que l'ensemble du fournisseur est hors service pour la session, donc brûler des réessais contre cela est inutile.

Le détecteur gère cela en analysant la chaîne d'erreur brute par rapport à des listes de motifs spécifiques. Au lieu d'un crash générique, il renvoie un ThrottleEvent typé contenant un code de raison clair et une fenêtre de retour liée à l'erreur spécifique.

Normaliser les charges utiles : comment arrêter la corruption du schéma

Le registre de modèles et la méthode adapt_payload() séparent la Stratégie B de la Stratégie A.

Le registre contient un ModelProfile pour chaque moteur. Ce profil définit explicitement les capacités cibles, y compris le support des prompts système natifs, les indicateurs de mode JSON, les structures de schéma et les modèles de formatage spécifiques.

Lorsqu'un basculement se produit, le routeur appelle adapt_payload() pour la nouvelle cible. L'adaptateur construit un dictionnaire de demande complètement neuf au lieu de transférer l'ancien. Si le modèle de secours ne dispose pas d'un champ de prompt système dédié, l'adaptateur injecte ces instructions directement dans le premier message utilisateur. Il n'applique la clé response_format ou les schémas structurels que si le modèle cible les prend en charge nativement.

Maintenir le pipeline en vie lors d'un basculement

Le state preserver empêche la perte de contexte lors d'un basculement en cours de tâche.

Lorsque l'Exécuteur atteint un 429 et que le routeur change de modèles, le moteur de secours commence à froid. Il voit l'historique des messages bruts mais n'a aucune idée que le Planificateur a déjà fonctionné, où il se trouve dans la séquence d'exécution, ou quel schéma il doit retourner.

Le state preserver corrige cela en prenant un instantané de l'ensemble du contexte d'exécution au moment où l'événement de limitation se déclenche, juste avant le basculement. Il enregistre l'historique des messages, le prompt système, les index d'étape, les sorties partielles existantes et le schéma cible.

Après le basculement, build_resume_message() transforme cet instantané en un bloc de texte structuré et l'ajoute au tableau des messages. Le modèle de secours reçoit le contexte directement :

[RESUME] Tâche 'pipeline_run_3' interrompue à l'étape 2/3 (Exécuter les étapes planifiées).
Modèle précédent : model_a.
Progrès : 67% complet.
Sortie partielle jusqu'à présent :
"result": "Étape du pipeline terminée avec une analyse structurée complète.",
"confidence": 0.94,
"metadata": {"tokens_used": 312, "model_tier": "primary"}
Continuer à partir de là où le modèle précédent s'est arrêté.
Schéma de sortie requis : {"type": "object", "required": ["result", "confidence"]}

Le modèle de secours sait maintenant exactement où il en est, ce qui est arrivé avant et ce qu'il doit produire. C'est ce que reflète le taux de préservation d'état de 100% dans le benchmark.

Le routeur coordonne le détecteur, le registre et le state preserver. Tout fonctionne à l'intérieur d'une boucle de réessai limitée, exécutant ces étapes dans l'ordre à chaque tentative :

  • Topologie opérationnelle d'une matrice de routage d'exécution asynchrone, mettant en évidence les pipelines d'adaptation de charge utile, les séquences de basculement de fournisseur multi-niveaux et les flux de travail de récupération d'état automatisés lors d'événements de limitation en amont.

Deux valeurs de configuration sont les plus importantes ici.

  • max_swaps limite le nombre de fois qu'un seul appel peut changer de modèles. Sans cette limite, des limitations consécutives à travers plusieurs fournisseurs boucleraient indéfiniment jusqu'à ce que max_retries soit épuisé.

  • swap_delay_seconds ajoute une petite pause de 0.05 secondes avant de frapper le nouveau modèle. Cette fenêtre est suffisamment petite pour ne pas nuire à la latence, mais assez grande pour éviter de surcharger un fournisseur qui a déjà des difficultés. La limite max_swaps et la pause swap_delay_seconds mettent en œuvre une version légère des motifs de bulkhead et de throttling décrits par Nygard.

Le pipeline à trois agents

Le WorkflowOrchestrator exécute trois étapes séquentielles : Planificateur, Exécuteur et Validateur. Chaque étape nécessite son propre prompt système, message utilisateur et schéma de sortie attendu. La sortie d'une étape alimente directement la suivante, construisant un historique de messages croissant.

  • Lignée des données et topologie des intercepteurs d'un flux de travail agentique multi-étapes, mettant en évidence les couches de routage middleware découplées et la convergence de l'accumulateur d'état centralisé.

Brief IA — L'actualité IA en français

L'essentiel de l'actualité de l'intelligence artificielle, décrypté et expliqué chaque jour.