Concepts
Une poignée de mots porte tout le modèle de données. Le reste de la documentation suppose que vous les connaissez, alors cette page définit chacun d’eux et dit à quoi il sert.
Span
Un span est une unité de travail. Il a un nom, un type, une heure de début, en général une heure de fin, et un statut. Il peut porter ce qui est entré, ce qui est sorti, le nombre de tokens employés, ce qu’il a coûté, et une erreur s’il a échoué.
Gardez le nom à faible cardinalité. search_docs est un nom ;
search_docs(query=hello) est un nom et une valeur collés
ensemble, et cela rend le regroupement par nom inutile dès que vous avez
deux exécutions.
Trace
Une trace est l’ensemble des spans d’une exécution, réunis par un
identifiant de trace de 128 bits. À l’intérieur de la trace,
parent_span_id donne sa forme à l’arbre : un appel d’outil fait
dans une étape de modèle est un enfant de cette étape, si bien que
l’imbrication à l’écran est celle qui a vraiment eu lieu.
Les identifiants ont la forme OpenTelemetry : 32 caractères hexadécimaux minuscules pour une trace et 16 pour un span. Ce n’est pas de la décoration. C’est ce qui permet à une trace commencée dans votre couche web et finie dans votre agent de rester une seule trace des deux côtés, et ce qui permet à mcpd de se poser à côté de tout ce qui lit déjà votre télémétrie.
Un span dont le parent vient d’un système de traçage étranger le porte dans
external_parent_span_id à la place. mcpd garde cette valeur
pour la corrélation mais ne bâtit jamais son arbre dessus, parce qu’un
identifiant de parent qui nomme un span que mcpd n’a jamais reçu
accrocherait tout le sous-arbre à rien.
- agent support_agent fail
- model chat
- tool returns_policy
- model chat
- tool returns_policy
- model chat
- tool returns_policy
The model called one tool three times and never answered. That is visible in four seconds here, and invisible in a log file.
mcpd stocke aussi une projection de chaque trace : le nombre de spans, le nombre d’erreurs, le total des tokens, le coût total, combien d’appels de modèle et combien d’appels d’outil. Cette ligne est recalculée depuis les spans à chaque écriture plutôt qu’incrémentée, parce que les spans arrivent dans le désordre, font l’objet de nouvelles tentatives et sont mis à jour sur place. Un compteur dérive sous ces trois effets, et un nombre de spans visiblement faux dans la liste fait douter le lecteur de tous les autres nombres de la page.
Spans racines et spans d’événement
Un span racine est un span sans parent à l’intérieur de la trace. C’est
normalement un agent_run ou un workflow_run, et
c’est de lui que la trace tient son nom, ses étiquettes et sa corrélation.
Les étiquettes n’ont de sens que sur une racine, où elles marquent
l’exécution entière.
Un span d’événement est un point dans le temps plutôt qu’une durée : il n’a ni fin ni durée. Un chunk diffusé en est le cas courant. La distinction est stockée plutôt que déduite d’une heure de fin absente, parce qu’un span qui n’a jamais eu de fin et un span qui n’est pas encore terminé sont deux faits différents, et qu’un seul des deux est un problème.
Une trace est complète une fois que sa racine s’est terminée et qu’aucun span n’est encore ouvert. Jusque-là elle reste listée, avec le meilleur nom disponible, plutôt que cachée jusqu’à ce qu’elle finisse. L’exécution qui n’a jamais fini est souvent celle que vous êtes venu regarder.
Type de span
Le type dit ce qu’une opération est. Il décide de la façon dont le span est dessiné, des attributs qui ont un sens dessus, et de savoir si la comptabilité des coûts le regarde. mcpd définit 33 types, par familles :
| Famille | Types |
|---|---|
| Agent | agent_run |
| Modèle | model_generation, model_step,
model_inference, model_chunk |
| Outils | tool_call, client_tool_call,
provider_tool_call, mcp_tool_call |
| Workflow | workflow_run, workflow_step,
workflow_conditional, workflow_parallel,
workflow_loop, et le reste
|
| Récupération | rag_ingestion, rag_embedding,
rag_vector_operation, rag_action,
retrieval, memory_operation,
graph_action |
| Évaluation | scorer_run, scorer_step,
guardrail, processor_run |
| Autres | mapping, skill_resolution,
workspace_action, http_request,
generic |
Quatre types facturent des tokens : model_generation,
model_step, model_inference et
rag_embedding. Ce sont les spans que lit la comptabilité des
coûts. generic est toujours valide et jamais déduit, si bien
qu’un span que mcpd ne sait pas classer est étiqueté honnêtement plutôt que
deviné.
Le modèle de données
liste chaque type avec ce qu’il veut dire.
La hiérarchie du modèle
Quatre de ces types s’imbriquent les uns dans les autres, et cette imbrication est la chose la plus utile du modèle :
-
model_generationest une génération logique : tout, de la première requête à la réponse finale. -
model_stepest une étape à l’intérieur. Une génération qui appelle des outils deux fois a trois étapes. -
model_inferenceest le seul aller-retour vers le fournisseur, sans processeurs et sans exécution d’outil dedans. -
model_chunkest un chunk diffusé, enregistré comme un événement.
La raison de quatre niveaux plutôt qu’un seul, c’est que dire que l’appel de modèle a été lent n’est presque jamais vrai tel quel. Un appel depuis votre code n’est pas un aller-retour HTTP dès que des outils entrent en jeu : c’est une requête, un outil, une autre requête, un garde-fou, une autre requête. Ramenez tout cela à un seul span, et une exécution qui a passé six secondes dans votre propre boucle de nouvelles tentatives ressemble en tout point à une exécution qui a passé six secondes à attendre un fournisseur. Séparer l’inférence de l’étape et de la génération est ce qui rend la différence lisible, et le premier événement de chunk est ce qui vous donne le temps jusqu’au premier token.
Enregistrez la consommation de tokens une seule fois, sur le span qui a fait l’appel au fournisseur. La projection de la trace additionne les tokens d’entrée et de sortie de tous les spans de la trace : les mêmes comptes attachés à une génération puis de nouveau à chacune de ses étapes doubleront le total des tokens et doubleront le coût à l’écran. La hiérarchie sert au chronométrage ; les tokens appartiennent au niveau qui a réellement parlé au fournisseur.
Les six signaux
Les spans sont l’une des six choses que mcpd stocke. Les logs sont les
lignes qu’une exécution a émises. Les métriques sont des observations
numériques, sous forme de compteurs, de jauges ou d’histogrammes. Les scores
sont l’évaluation d’un span ou d’une trace par une machine. Le feedback est
celui d’une personne. Une note d’aspect est une phrase sur une
exécution terminée. Un modèle écrit la plupart d’entre elles. Le daemon écrit
les notes outcome, à partir du statut de l’exécution et d’autres
faits qu’il détient déjà.
-
Spans
What ran, nested, with timings
-
Logs
Lines the run emitted
-
Metrics
Numbers, with exemplars back to a run
-
Scores
Machine evaluation
-
Feedback
What a person thought
-
Aspect notes
A sentence a model wrote about the run
Les six portent l’identifiant de trace auquel ils appartiennent, et la plupart aussi l’identifiant de span, et les six passent par le même pipeline de masquage avant que quoi que ce soit ne soit écrit. Un secret fuit tout aussi bien par une ligne de log que par un prompt.
Un score déclare toujours son échelle : la valeur, et le minimum et le maximum entre lesquels elle se situe. Chaque SDK exige les deux à l’endroit de l’appel, parce qu’un 0.7 nu, sans échelle attachée, ne peut être comparé à rien, pas même à la sortie du même scorer la semaine dernière.
Le feedback est gardé à un endroit séparé des scores, et jamais moyenné avec
eux. Il se présente sous cinq formes : thumbs, rating,
correction, tag et comment. Une
correction est la plus précieuse des cinq, parce que c’est le seul signal qui
porte la bonne réponse.
Corrélation
La corrélation est le contexte auquel un signal appartient. C’est la différence entre un tas d’exécutions et un ensemble que vous pouvez découper.
| Champ | Ce qu’il contient |
|---|---|
project | La clé de cloisonnement. Chaque signal appartient à un seul. |
environment | Où cela s’est exécuté, par exemple production ou staging. |
service_name | Le service émetteur. |
service_version | Sa version, pour rattacher une régression à une publication. |
session_id | Une session côté utilisateur. Regroupe plusieurs traces en une conversation. |
thread_id | Un fil à l’intérieur de cette session. |
user_id | L’utilisateur final pour qui l’exécution a eu lieu. |
resource_id | Un locataire ou un espace de travail dans votre propre application. |
run_id | Votre propre identifiant pour cette exécution. |
request_id | La requête entrante qui a causé le travail. |
experiment_id | Renseigné quand une expérience a produit l’exécution. |
release | Un nom de publication ou un sha git. |
project est le seul champ obligatoire. Quand un émetteur n’en
nomme pas, le daemon classe le signal sous la valeur par défaut de
--project, si bien que rien n’est jamais stocké sans endroit où
appartenir.
Renseignez session_id même quand cela paraît redondant. Une
exécution d’agent est une trace, mais une plainte porte presque toujours sur
une conversation, et sans identifiant de session rien ne retransforme onze
traces séparées en l’échange que la personne a réellement eu.
La liste des traces filtre directement sur environment,
session_id, thread_id et user_id, à
côté du statut, du type, du nom, des étiquettes, du modèle, de la plage de
temps, de la durée minimale, du coût minimal et du score.
Retrouver une exécution les
met ensemble.
Liens
Un span a un seul parent et autant de liens que l’on veut. Un lien pointe
vers un autre span ou une autre trace et dit pourquoi :
follows_from, retry_of, replay_of, ou
ce que vous nommez vous-même.
Les liens existent parce que la parenté ne sait pas exprimer une convergence. Un traitement par lots causé par vingt requêtes a vingt liens et un seul parent. Forcer cela dans l’arbre inventerait dix-neuf sous-arbres en double, ou jetterait dix-neuf des causes.
Ensuite
- Chaque entité et chaque champ en entier : Modèle de données.
- Comment ces mots apparaissent dans le code : les SDK.
- Ce que mcpd déduit quand les spans arrivent en OTLP : OpenTelemetry.
- Transformer le vocabulaire en requête : Retrouver une exécution.