Le traçage distribué suit une requête d’IA en transportant une identité de trace partagée à travers les frontières entre services et en enregistrant chaque opération participante sous forme de span lié causalement.
Une requête d’IA auto-hébergée peut traverser un proxy inverse, un service d’agent, un magasin vectoriel, un moteur de modèles, une file de travaux, un service de stockage et un point de terminaison d’outil avant que l’utilisateur ne voie une réponse. Ces composants peuvent s’exécuter dans différents conteneurs ou sur différentes machines et écrire des journaux indépendants ; la proximité des horodatages ne suffit donc pas à prouver quelles opérations appartiennent à une même requête. Le traçage distribué fait voyager l’identité de la requête avec le travail, au lieu de la reconstituer plus tard par déduction.
Une trace donne une identité commune à une requête de bout en bout
Une trace représente le parcours complet d’une requête, tandis que chaque span enregistre une opération délimitée, comme la récupération, le réordonnancement, l’inférence du modèle, un appel d’outil ou la sérialisation de la réponse. Lorsque ces spans portent un même identifiant de trace, un backend peut regrouper le travail de services distincts sans supposer que des événements proches dans le temps sont liés causalement.
L’unité utile n’est donc pas une simple liste de durées, mais un arbre de requête connecté. Lorsqu’un identifiant de trace traverse les frontières entre services, les opérations chronométrées de nombreux processus peuvent être reconstituées comme une seule requête, plutôt que comme des entrées de journal sans lien.
Dans une pile d’IA domestique, le span racine peut commencer au niveau de l’API destinée à l’utilisateur, puis se diviser entre la récupération, les autorisations, le traitement du modèle et les outils. La trace indique quelles opérations appartenaient à cette requête avant même que l’on cherche à comprendre pourquoi elle était lente.
Le contexte doit être injecté et extrait à chaque frontière entre services
La continuité de la trace dépend de chaque appelant, qui doit injecter le contexte actuel dans le support sortant, et de chaque récepteur, qui doit extraire ce contexte avant de créer son propre span. Si un proxy, une bibliothèque cliente ou un service démarre à la place une nouvelle trace, le parcours de bout en bout est interrompu, même si la requête sous-jacente aboutit.
Le mécanisme de propagation transporte des identifiants et l’état d’échantillonnage, et non les données métier de l’utilisateur. Le cycle d’injection et d’extraction permet à des services hétérogènes de conserver la même identité de requête lorsque le travail traverse des frontières entre processus et réseaux.
Cela est important dans une pile auto-hébergée mixte, car le proxy inverse, l’agent Python, la base de données vectorielle et le service d’outils en Rust ou en Go n’ont pas besoin d’utiliser une seule et même bibliothèque de traçage, tant que leur format de propagation reste interopérable.
L’absence de propagation constitue donc un problème de qualité des données, et non la preuve que le service en aval s’est exécuté indépendamment. Les traces interrompues doivent être diagnostiquées à la frontière où l’identité a été perdue.
Les relations parent-enfant et les liens entre spans préservent différentes formes de causalité
Le travail synchrone direct forme généralement une chaîne parent-enfant, car une opération démarre la suivante et attend son résultat, tandis que les flux parallèles et asynchrones peuvent présenter une relation plus complexe. Un modèle de trace doit préserver la causalité sans forcer chaque opération en aval à entrer dans une pile d’appels artificielle.
Les relations parent-enfant sont utiles lorsqu’un appel de service est directement imbriqué, tandis que les liens entre spans pour les relations non hiérarchiques peuvent relier un travail déclenché par une activité précédente, mais qui n’est pas proprement imbriqué sous un parent actif unique.
Une requête d’IA domestique peut lancer en parallèle la récupération et les vérifications d’autorisation, puis attendre les deux avant la génération par le modèle. La trace doit préserver cette structure parallèle, plutôt que de laisser entendre que le span démarré en premier a provoqué l’autre.
Les files ne permettent de suivre la trace d’une requête que si le contexte voyage avec le message
Une file asynchrone interrompt la pile d’appels directe au sein du processus, mais le travail mis en file peut rester associé à la requête d’origine lorsque le contexte de trace est placé dans les métadonnées du message. Le consommateur utilise ensuite ce contexte pour créer le span suivant ou un lien explicite lorsque le traitement commence plus tard.
Cette distinction devient importante pour les tâches d’OCR, de génération d’embeddings, d’analyse d’images de caméra ou de notification qu’un serveur domestique déplace volontairement hors du parcours interactif de la requête. Lors d’un transfert par bus de messages, la propagation explicite préserve l’identité de la trace, même si l’état local au thread et la pile d’appels directe ne sont plus conservés.
L’explication existante de ZimaSpace sur les files de travaux d’IA domestique distinctes explique pourquoi le travail asynchrone est isolé sur le plan opérationnel ; le traçage distribué fournit l’identité qui relie encore ce travail isolé à la requête qui l’a déclenché.
Sans cette identité, une étape d’arrière-plan lente peut sembler être une tâche sans rapport, et l’opérateur risque de ne pas voir qu’elle constitue la véritable continuation de la requête de l’utilisateur.
La trace reconstituée révèle le chemin critique et ses lacunes
Après réception des spans par un backend de traçage, leurs identifiants, horodatages, relations parentales, statuts et métadonnées de service peuvent être assemblés pour afficher une requête de bout en bout. Le span le plus long n’est pas automatiquement la cause du délai visible par l’utilisateur, car des opérations parallèles peuvent se chevaucher ; la question utile est donc de savoir quelle chaîne de dépendances contrôle l’achèvement.
Lorsque la propagation du contexte est absente, les traces deviennent discontinues ; un diagramme temporel cohérent n’est donc jamais plus complet que l’instrumentation qui l’a produit.
L’échantillonnage introduit une autre limite : une requête non échantillonnée ne peut pas fournir ultérieurement des preuves complètes pour ses spans, et un service partiellement instrumenté peut laisser des zones aveugles dans une trace par ailleurs valide. Le traçage distribué améliore donc la visibilité causale, mais il ne crée pas de télémétrie pour les opérations qui n’ont jamais été enregistrées.
Le mécanisme est efficace lorsqu’une même requête utilisateur peut être suivie sur le parcours auto-hébergé réel, sans transformer les journaux de chaque service en une base de données commune ni prétendre que le temps suffit à prouver la causalité.
Centre Tech & IA
Plus à lire

État d’exécution vs état persistant dans Home Assistant : que doit survivre à un redémarrage ?
Home Assistant ne conserve pas chaque valeur en temps réel ; la configuration, les registres, certains états restaurés, l’historique et les données de déploiement...

Comment Home Assistant authentifie-t-il les sessions locales et distantes ?
Les sessions Home Assistant locales et distantes utilisent le même modèle d’identité côté serveur ; l’accès à distance modifie le chemin et la limite...

Pourquoi les requêtes d’historique de Home Assistant peuvent-elles ralentir à mesure que les données de l’enregistreur augmentent ?
L’augmentation du nombre d’enregistrements peut accroître le coût des requêtes d’historique lorsque la plage demandée concerne davantage de lignes, que les défauts de cache...

