2026-07-31T18:48:42.461Z

Observabilité des LLM avec MLflow : prouver que la trace est devenue une preuve exploitable

Auditez dans MLflow 3.14.0 l’échantillonnage, l’admission dans la file asynchrone, l’expiration des nouvelles tentatives, la persistance côté backend, l’intégrité et la fraîcheur des traces ainsi que les résultats vérifiés de l’agent.

L’observabilité MLflow LLM est utile pour les opérations d’agent uniquement lorsqu’une trace devient une preuve durable et consultable. Un manipulateur terminé n’en est pas la preuve. Avec la journalisation asynchrone, l’application peut se terminer avant que la trace n’atteigne le backend de suivi ; une file d’attente complète peut supprimer de nouvelles traces ; une fenêtre de réessai expirée peut annuler les échecs d’écriture ; et l’échantillonnage au niveau des traces peut volontairement omettre une trace entière. Le principe pratique est un reçu en cinq étapes : 1. La demande était éligible à la recherche ; 2. la trace était admise sur le chemin d’exportation asynchrone ; 3. le backend configuré l’a stocké ; 4. Une recherche en arrière plan a trouvé une nouvelle trace avec les travées requises ; 5. Un contrôle déterministe distinct a vérifié le résultat demandé. Les étapes un à quatre établissent une couverture d’observation. La cinquième étape établit que l’agent a livré ce que l’utilisateur demandait. Ne les fusionnez pas en un seul statut vert. Cet article teste cette frontière par rapport à MLflow 3.14.0, la version actuelle de PyPI, lors de la vérification du 30 juillet 2026. L’expérience utilise un backend local de suivi SQLite et des attributs sans contenu ; Il n’envoie pas d’invites, de réponses, de crédants ou de données clients. Une trace peut disparaître après le retour du gestionnaire Le Guide de traçage de production de MLflow recommande la journalisation asynchrone des traces pour les charges de travail en production. Il documente trois limites opérationnelles qui comptent avant qu’une trace puisse soutenir une décision d’incident. Premièrement, la journalisation asynchrone est activée par défaut pour les charges de travail non portables de MLflow open source et Databricks. Les notebooks Databricks utilisent un code par défaut différent. Un audit nécessite donc le Mode d’exécution efficace , et non une hypothèse copiée d’un autre environnement. Deuxièmement, MLFLOW ASYNC TRACE LOGGING MAX QUEUE SIZE est par défaut à 1 000. La documentation est explicite : lorsque la file est pleine, de nouvelles traces sont rejetées. Une réponse d’application réussie peut coexister avec des preuves d’observabilité manquantes car l’exécution de la requête et l’admission de trace sont des événements distincts. Troisièmement, les échecs d’écriture de trace ne sont réessayés qu’à l’intérieur de MLFLOW ASYNC TRACE LOGGING RETRY TIMEOUT , documentés avec un défaut de 500 secondes. Après cette fenêtre, la trace est supprimée. Augmenter le temps d’attente peut améliorer la résilience lors d’une courte interruption de suivi, mais cela prolonge aussi la pression mémoire et le travail de récupération. Ce n’est pas une garantie de durabilité. Le sampling est encore différent. MLFLOW TRACE SAMPLING RATIO sélectionne des traces entières : les portées d’une trace sélectionnée restent ensemble, tandis qu’une trace non sélectionnée est intentionnellement absente. C’est un résultat politique, pas un échec des exportateurs. Votre logique de santé devrait dire deliberately unobserved , pas trace lost , lorsque la décision d’échantillonnage est connue. Ces distinctions modifient l’alerte. Une demande intentionnellement non échantillonnée devrait affecter les calculs de couverture. Le débordement de file d’attente ou l’épuisement des tentatives est un incident d’observabilité. Une panne en arrière plan peut rendre le verdict incertain. Traiter les trois comme « aucune trace » cache à la fois la cause et la prochaine action sûre. Prouvez la persistance avec un test canari, pas avec la fin du processus MLflow 3.14.0 expose des contrôles de persistance qui permettent à un test de distinguer le travail en attente en arrière plan des preuves backend interrogables : mlflow.flush trace async logging() se dévide en attendant les écritures de trace ; mlflow.get trace(trace id, flush=True) se rince et réessaie lorsque la trace n’est pas trouvée ; mlflow.search traces(..., flush=True) rougit avant de chercher. Le comportement pertinent de l’API est documenté dans le Référence MLflow Python. L’option flush est particulièrement utile lors des tests, des sondes de déploiement, des missions éphémères et des canaris contrôlés. Vider chaque requête de production annulerait une grande partie de l’avantage de latence du journal asynchrone. Voici un canari minimaliste sans contenu : Exécutez cela sur la même URI de suivi, identifiants, chemin réseau, emplacement de l’expérience et combinaison de paquet que celui utilisé par le travailleur en qui vous souhaitez avoir confiance. Un canari contre le magasin de fichiers local d’un développeur ne dit rien sur un conteneur de production pointant vers un serveur de suivi distant. Dans l’expérience enregistrée MLflow 3.14.0, la différence était visible. Immédiatement après la fin de la travée, get trace(..., flush=False) n’a pas donné de trace et search traces(..., flush=False) n’a donné aucun résultat. Après flush trace async logging() , la récupération réussissait, la recherche renvoyait une trace, et ce résultat contenait l’identifiant de la trace canari. C’est une observation, pas un benchmark universel de latence. Un backend rapide peut persister avant la première requête ; Un backend lent ou en difficulté peut prendre plus de temps. La règle durable est l’affirmation après une rinçage contrôlée, et non le compte exact avant flush. Pour un service de longue durée, programmez le canari à un tarif suffisamment bon marché pour être conservé à 100 % d’échantillonnage. Bilan : l’identité du travailleur et du déploiement ; l’empreinte URI de suivi efficace, jamais l’identifiant ; identifiant la trace et l’expérience ou la localisation ; temps d’enqueue, temps de fin de vidange et temps de recherche ; les noms racines et enfants requis ; une date limite de fraîcheur ; le résultat d’un contrôle de destination séparé. Ces champs permettent à un opérateur de distinguer un travailleur qui n’a jamais créé la portée d’un exportateur qui ne pouvait pas la maintenir. Orientez huit états sans produire de faux vert Un audit utile nécessite plus que found: true . Le calendrier suivant de huit cas donne à chaque limite de défaillance un verdict différent. Preuves Verdict Décision de l’opérateur La politique d’échantillonnage excluait la demande deliberately unobserved Recalculer la couverture ou augmenter l’échantillonnage pour les trajectoires critiques La file d’attente a rejeté une nouvelle trace discarded queue full Réduire la pression, augmenter la capacité limitée ou augmenter la taille des exportateurs Les essais d’exportation ont épuisé leur temps d’arrêt discarded retry expired Étudier le backend ou le réseau ; Les preuves ne sont pas disponibles Le travail local s’est terminé mais le stockage en backend n’est pas encore prouvé backend persistence unproven Flushez une sonde et interrogez le backend configuré La trace stockée est plus ancienne que la date limite de preuve stale evidence Refaire le canari ; Ne pas réutiliser le vieux vert La trace est récente mais un outil ou une plage de destination requise sont absents incomplete trace Fixez l’instrumentation avant de l’utiliser pour le diagnostic La trace est complète mais le livrable n’est pas vérifié observed outcome unverified Vérifiez directement la destination ou l’artefact La trace est fraîche, complète, et le reçu du résultat est passé verified Admettez ces preuves à la décision de santé La priorité compte. Si une demande a été délibérément non échantillonnée, il n’y a aucune raison de diagnostiquer une admission en file d’attente pour cette demande. Si la persistance n’est pas prouvée, la complétude de l’enveloppe est inconnaissable. Si la trace est complète mais que l’artefact externe manque, le résultat est un faux succès, et non une victoire instrumentationnelle. L’audit exécutable accompagnant cet article a rejoué exactement un cas pour chaque verdict et n’a permis que verified de devenir vert. Il vérifiait également les signatures de fonctions MLflow 3.14.0 et stockait un canari dans un backend SQLite frais. Ce dispositif est volontairement petit : sa valeur est la limite de décision, pas le réalisme du test de charge. Une trace complète et une tâche terminée constituent des preuves distinctes Le traçage MLflow peut capturer des entrées, sorties, métadonnées, appels de modèles, récupérations, appels d’outils et autres étapes intermédiaires. Son Aperçu du traçage présente ces traces comme preuves pour le débogage, le suivi, l’évaluation, le retour d’information et la collecte de jeux de données. Ces preuves peuvent expliquer Comment s’est comportée la course . Il ne peut pas prouver de manière générique que toutes les promesses extérieures ont été tenues. Un champ d’outil avec un statut réussi peut indiquer qu’un appel API a été retourné. Cela ne prouve pas nécessairement que le fichier demandé existe sur le chemin convenu, qu’une pull request contient le diff souhaité, qu’un message est arrivé au destinataire correct, ou qu’un rapport programmé contient des données actuelles. Définissez la réception issue du contrat de tâche : pour un fichier, vérifier le chemin, le type, le plancher de taille, la somme de contrôle ou le prédicat de contenu ; pour un déploiement, vérifier la révision de la cible et une sonde d’acceptation en temps real ; pour un message, vérifier l’identité de destination et la réception du fournisseur ; Pour une mutation dans la base de données, vérifier l’état de ligne et la clé d’idempotence prévus ; pour une exécution programmée, vérifiez sa fenêtre attendue et la fraîcheur de sa sortie. Associez le reçu à la trace avec un ID d’opération ou de demande sans contenu. Gardez les secrets et le contenu brut des prompts hors de la clé de jointure. Si la destination ne peut pas être interrogée en toute sécurité, classez le résultat comme unknown et demandez l’autorité ou la preuve manquante. Cela limite aussi ce que le canari prouve. Une trace flushée vérifie un chemin à un instant. Il ne mesure pas chaque travailleur, ne garantit pas la capacité future de la file d’attente, ne reconstruit pas les traces échantillonnées, ne teste pas la rétention des sauvegardes, ni ne prouve un résultat utilisateur. Les tests de charge, les contrôles de disponibilité en arrière plan, les exercices de rétention et les sondes spécifiques au résultat restent séparés. Le choix opérationnel par défaut Utilisez la journalisation asynchrone pour la latence de production, mais payez explicitement la dette de durabilité : 1. épinglez le package MLflow et enregistrez la configuration asynchrone, la file d’attente, la réévaluation et l’échantillonnage ; 2. conserver un canari à faible taux et échantillonné à 100 % pour chaque voie de travail critique ; 3. le vidage et la fouille uniquement à l’intérieur des sondes, tests, gestion d’arrêt ou autres points de vérification délimités ; 4. exiger une nouvelle recherche en arrière plan ainsi qu’une couverture de portée attendue avant d’admettre des traces ; 5. vérifier la destination de la tâche séparément ; 6. Alertez vous différemment pour un échantillonnage délibéré, des pertes d’exportateurs, des preuves obsolètes, des traces incomplètes et un faux succès. Cette politique rend l’observabilité MLflow utile sans prétendre qu’il s’agit d’un oracle de résultats. Sidewisp est actuellement en préversion privée. Il est conçu comme une couche de santé aux côtés des systèmes d’exécution des agents et d’observabilité, avec la fraîcheur, l’incertitude et la vérification des résultats des preuves gardées explicites. Sidewisp ne propose actuellement pas de suivi MLflow ni de récupération automatisée.