Traçage manuel et personnalisé
Le traçage automatique instrumente plus de 30 frameworks en un seul appel. Utilisez le traçage manuel lorsque vous devez instrumenter du code que la journalisation automatique ne couvre pas — logique d'agent personnalisée, frameworks propriétaires ou tout chemin d'exécution que vous souhaitez observer précisément. Les mêmes APIs fonctionnent que votre agent s'exécute sur Databricks ou sur une infrastructure externe.
Quelle méthode ?
Méthode | Cas d'utilisation | Parent-enfant automatique | Gestion des exceptions |
|---|---|---|---|
Traçage d’une fonction Python entière | Oui | Automatic | |
Traçage d'un bloc de code dans une fonction | Oui | Automatic | |
Suivi des fonctions TypeScript ou JavaScript | Oui | Automatic | |
ID de trace personnalisés, intégration avec un système d’observabilité externe | Non — manuel | Manuel |
Prérequis
- Python
- Node.js
%pip install --upgrade "mlflow[databricks]>=3.1.0"
dbutils.library.restartPython()
npm install mlflow-tracing
Nécessite Node.js 14 ou une version ultérieure. Pour le traçage OpenAI automatique, installez également :
npm install mlflow-openai
Le décorateur @mlflow.trace
Le décorateur @mlflow.trace crée une étendue pour toute fonction Python. Il capture automatiquement le nom de la fonction, les entrées, les sorties et le temps d’exécution, et gère les relations parent-enfant ainsi que l’enregistrement des exceptions sans code supplémentaire.
import mlflow
@mlflow.trace(span_type="func", attributes={"key": "value"})
def add_1(x):
return x + 1
@mlflow.trace(span_type="func", attributes={"key1": "value1"})
def minus_1(x):
return x - 1
@mlflow.trace(name="Trace Test")
def trace_test(x):
step1 = add_1(x)
return minus_1(step1)
trace_test(4)

Lorsqu'une trace contient plusieurs portées portant le même nom, MLflow ajoute un suffixe à incrémentation automatique — _1, _2, etc.
Personnaliser les étendues
Le décorateur accepte trois arguments optionnels :
name— remplace le nom de portée default (le nom de la fonction)span_type— définit le type d'étendue ; utilisez un type d'étendue intégré ou une chaîne personnaliséeattributes— ajoute des métadonnées de type clé-valeur à l'étendue
Pour mettre à jour les attributs de manière dynamique depuis l’intérieur de la fonction, appelez mlflow.get_current_active_span():
from mlflow.entities import SpanType
@mlflow.trace(span_type=SpanType.LLM)
def invoke(prompt: str):
model_id = "gpt-4o-mini"
span = mlflow.get_current_active_span()
span.set_attributes({"model": model_id})
return client.invoke(messages=[{"role": "user", "content": prompt}], model=model_id)
Utiliser avec d’autres décorateurs
Placez @mlflow.trace comme décorateur le plus externe . S’il n’est pas le premier, il risque de manquer les modifications apportées par les décorateurs internes et de produire des traces incomplètes.
# Correct: @mlflow.trace is outermost
@mlflow.trace(name="my_function")
@other_decorator
def my_function(x, y):
return x + y
Ajouter des tags de trace et des aperçus d'interface utilisateur
Utilisez mlflow.update_current_trace() dans une fonction tracée pour personnaliser les colonnes d’aperçu Request / Response dans l’interface utilisateur des traces. Le même appel peut joindre des tags ; pour le flux de travail complet sur les tags et les métadonnées, consultez Enrichissement des traces : tags, contexte et retours d’expérience.
@mlflow.trace(name="Summarization Pipeline")
def summarize_document(document_content: str, user_instructions: str):
mlflow.update_current_trace(tags={"environment": "production"})
request_p = f"Doc: {document_content[:30]}... Instr: {user_instructions[:30]}..."
mlflow.update_current_trace(request_preview=request_p)
summary = generate_summary(document_content, user_instructions)
mlflow.update_current_trace(response_preview=f"Summary: {summary[:50]}...")
return summary
Gestion des exceptions
Lorsqu’une exception est levée à l’intérieur d’une fonction tracée, la portée est automatiquement marquée comme ayant échoué et les détails de l’exception sont enregistrés dans l’onglet Events de la tab.
Multi-threading
MLflow tracing is thread-safe and isolates traces per thread by default. To create one trace that spans multiple threads, copy the execution context from the main thread into each worker:
import contextvars
from concurrent.futures import ThreadPoolExecutor, as_completed
import mlflow
import openai
client = openai.OpenAI()
mlflow.openai.autolog()
@mlflow.trace
def worker(question: str) -> str:
messages = [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": question},
]
response = client.chat.completions.create(
model="gpt-4o-mini", messages=messages, temperature=0.1, max_tokens=100
)
return response.choices[0].message.content
@mlflow.trace
def main(questions: list[str]) -> list[str]:
results = []
with ThreadPoolExecutor(max_workers=2) as executor:
futures = []
for question in questions:
ctx = contextvars.copy_context() # copy context in main thread
futures.append(executor.submit(ctx.run, worker, question)) # run in copy
for future in as_completed(futures):
results.append(future.result())
return results
main(["What is the capital of France?", "What is the capital of Germany?"])

asyncio les tâches héritent automatiquement du contexte — aucune copie manuelle n’est requise pour le code async/await.
Sorties de streaming
Le décorateur prend en charge les fonctions de génération et de génération asynchrone (MLflow 2.20.2+). Par default, MLflow collecte toutes les valeurs produites sous forme de liste dans la sortie de la portée. Passez un output_reducer pour agréger les blocs de Stream en une seule valeur ; le réducteur reçoit la liste complète une fois l'itération terminée :
@mlflow.trace(output_reducer=lambda chunks: "".join(chunks))
def stream_text():
for word in ["Hello", " ", "World", "!"]:
yield word
# Span output: "Hello World!"
Les segments bruts restent visibles dans l’onglet Events de l’étendue à des fins de debugging, que vous utilisiez ou non un réducteur. Pour les Stream de SDK de fournisseur dont les segments ne sont pas des chaînes simples, tels que les objets ChatCompletionChunk d’OpenAI, écrivez un réducteur qui cumule les deltas en un seul objet de réponse.
Pour OpenAI en production, privilégiez le traçage automatique pour OpenAI, qui gère le streaming automatiquement.
Types de fonctions pris en charge :
Type de fonction | Pris en charge |
|---|---|
Synchroniser | Toutes les versions |
Asynchrone | MLflow 2.16.0+ |
Générateur (synchrone ou asynchrone) | MLflow 2.20.2+ |
Le gestionnaire de contexte mlflow.start_span()
Utilisez mlflow.start_span() pour tracer n’importe quel bloc de code au sein d’une fonction. À l'instar du décorateur, il gère automatiquement les relations parents-enfants et l'enregistrement des exceptions. Contrairement au décorateur, vous définissez le nom, les entrées et les sorties de la portée par le biais de l'objet LiveSpan qu'elle renvoie.
import mlflow
with mlflow.start_span(name="my_span") as span:
x, y = 1, 2
span.set_inputs({"x": x, "y": y})
z = x + y
span.set_outputs(z)
Événements de portée
Les objets SpanEvent enregistrent des occurrences spécifiques au cours de la durée de vie d’un intervalle (avec le timestamp actuel, un timestamp spécifique en nanosecondes ou à partir d’une exception) :
from mlflow.entities import SpanEvent, SpanType
import time
with mlflow.start_span(name="pipeline_step", span_type=SpanType.CHAIN) as span:
span.add_event(SpanEvent(
name="validation_completed",
attributes={"records_validated": 1000, "errors_found": 3},
))
span.add_event(SpanEvent(
name="data_checkpoint",
timestamp=int(time.time() * 1e9),
attributes={"checkpoint_id": "ckpt_123"},
))
try:
raise ValueError("Invalid input format")
except Exception as e:
# SpanEvent.from_exception captures exception.message, exception.type, exception.stacktrace
mlflow.get_current_active_span().add_event(SpanEvent.from_exception(e))
Statut de l'étendue
SpanStatus indique si un intervalle a réussi ou échoué. Le gestionnaire de contexte remplace le statut à la sortie (OK en cas de sortie propre, ERROR en cas d’exception). Veillez donc à le définir avant la fermeture du bloc with si vous avez besoin d’un statut personnalisé :
from mlflow.entities import SpanStatus, SpanStatusCode, SpanType
with mlflow.start_span(name="my_span", span_type=SpanType.CHAIN) as span:
span.set_status(SpanStatus(SpanStatusCode.OK))
# String shortcuts also work: span.set_status("OK") or span.set_status("ERROR")
État d’une query à partir d’une étendue terminée :
trace = mlflow.get_trace(mlflow.get_last_active_trace_id())
for span in trace.data.spans:
print(span.status.status_code)
Portées RETRIEVER
Utilisez SpanType.RETRIEVER lorsque votre étendue récupère des documents à partir d'un magasin de données. Les étendues RETRIEVER doivent générer une liste de Document objets afin que l'interface utilisateur les affiche correctement :
from mlflow.entities import Document, SpanType
@mlflow.trace(span_type=SpanType.RETRIEVER)
def retrieve_documents(query: str):
span = mlflow.get_current_active_span()
documents = [
Document(
page_content="The content of the document...",
metadata={"doc_uri": "path/to/document.md", "relevance_score": 0.95},
id="doc_123",
),
Document(
page_content="Another relevant section...",
metadata={"doc_uri": "path/to/other.md", "relevance_score": 0.87},
),
]
span.set_outputs(documents)
return [doc.to_dict() for doc in documents]
retrieve_documents(query="What is ML?")
Node.js / TypeScript
Le package npm mlflow-tracing apporte le traçage MLflow aux agents TypeScript et JavaScript. L'API reflète l'approche de Python : une API de wrapping de fonction (équivalente au décorateur), une API de traçage de bloc (équivalente à start_span) et un décorateur de méthode de classe pour TypeScript 5.0+.
Configurer
import * as mlflow from 'mlflow-tracing';
mlflow.init({
trackingUri: 'databricks',
experimentId: '<your-experiment-id>',
});
Recherchez l’identifiant d’expérimentation dans votre Workspace Databricks sous AI/ML > Experimentation > GenAI apps & agents en cliquant sur l’icône . Configurez les informations d’identification avec des variables d’environnement :
export DATABRICKS_TOKEN=<personal-access-token>
export DATABRICKS_HOST=https://<workspace>.cloud.databricks.com
Tracer une fonction
Enveloppez n'importe quelle fonction avec mlflow.trace() pour créer une version tracée. MLflow capture automatiquement les entrées, les sorties, les exceptions et la latence. Les appels tracés imbriqués produisent une trace à plusieurs portées reflétant la hiérarchie des appels.
const getWeather = async (city: string) => `The weather in ${city} is sunny`;
const tracedGetWeather = mlflow.trace(getWeather, { name: 'get-weather' });
const result = await tracedGetWeather('San Francisco');
Décorateur de méthode de classe (TypeScript 5.0+)
class MyAgent {
@mlflow.trace({ spanType: mlflow.SpanType.LLM })
generateText(prompt: string) {
return "It's sunny in Seattle!";
}
}
Tracer un bloc de code
Utilisez mlflow.withSpan() pour tracer un bloc de code — l'équivalent TypeScript de mlflow.start_span():
const result = await mlflow.withSpan(async (span: mlflow.Span) => "It's sunny in Seattle!", {
name: 'generateText',
spanType: mlflow.SpanType.TOOL,
inputs: { prompt: question },
});
Traçage automatique pour OpenAI
Enveloppez le client OpenAI avec tracedOpenAI pour tracer automatiquement tous les appels :
import { OpenAI } from 'openai';
import { tracedOpenAI } from 'mlflow-openai';
const client = tracedOpenAI(new OpenAI());
const response = await client.chat.completions.create({
model: 'gpt-4o-mini',
messages: [{ role: 'user', content: "What's the weather in Seattle?" }],
});
Pour obtenir un exemple complet et fonctionnel, consultez l’ exemple full-stack en TypeScript sur GitHub.
Combiner le traçage automatique et manuel
Le traçage automatique et le traçage manuel se conjuguent. Activez autolog() pour chaque framework utilisé par votre agent et MLflow capture ces appels en une seule trace ; ajoutez @mlflow.trace pour les regrouper sous une seule portée parente ou pour instrumenter vos propres fonctions (prétraitement/post-traitement, logique métier, routage) que le journal automatique ne détecte pas.
Tracez plusieurs frameworks en une seule trace
Activez le log automatique pour chaque framework et MLflow associe leurs appels en une seule trace cohérente. Utilisez cette option lorsque votre agent associe des appels LLM directs à une couche d'orchestration :
import mlflow
mlflow.openai.autolog()
mlflow.langchain.autolog()
# All OpenAI and LangChain calls in the same execution appear in one trace
Pour regrouper les appels de plusieurs frameworks sous une seule étendue parente, enveloppez le flux de travail avec @mlflow.trace:
import mlflow
import openai
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
mlflow.openai.autolog()
mlflow.langchain.autolog()
client = openai.OpenAI()
@mlflow.trace
def multi_provider_workflow(query: str):
# Direct OpenAI call — auto-traced as a child span
topics = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": "Extract key topics from the query."},
{"role": "user", "content": query},
],
).choices[0].message.content
# LangChain chain — also auto-traced as a child span
chain = ChatPromptTemplate.from_template(
"Topics: {topics}\nRespond to: {query}"
) | ChatOpenAI(model="gpt-4o-mini")
return chain.invoke({"topics": topics, "query": query})
multi_provider_workflow("Explain quantum computing")
Ajouter des étendues manuelles en parallèle du log automatique
Ajoutez @mlflow.trace à vos propres fonctions pour capturer la logique que le log automatique ne couvre pas. MLflow Merge ces portées avec celles capturées automatiquement en une seule trace :
import mlflow
import openai
mlflow.openai.autolog()
client = openai.OpenAI()
@mlflow.trace
def run(question):
messages = build_messages(question)
response = client.chat.completions.create( # auto-traced by autolog
model="gpt-4o-mini", max_tokens=100, messages=messages,
)
return parse_response(response)
@mlflow.trace
def build_messages(question):
return [
{"role": "system", "content": "You are a helpful chatbot."},
{"role": "user", "content": question},
]
@mlflow.trace
def parse_response(response):
return response.choices[0].message.content
run("What is MLflow?")
Cela produit une trace : une portée parente run avec des enfants build_messages et parse_response, ainsi que la portée OpenAI capturée automatiquement.

Déployer en dehors de Databricks
Le traçage d'un agent déployé en dehors de Databricks utilise la même instrumentation. Définissez les variables d'environnement suivantes avant de lancer le processus de l'agent, puis instrumentez votre code à l'aide de l'une des méthodes ci-dessus :
export DATABRICKS_HOST="https://your-workspace.cloud.databricks.com"
export DATABRICKS_TOKEN="your-databricks-token"
export MLFLOW_TRACKING_URI=databricks
export MLFLOW_EXPERIMENT_NAME="/Shared/production-genai-agent"
Pour les déploiements de production, préférez le package léger mlflow-tracing (pip install mlflow-tracing) au package complet mlflow[databricks]. Pour la configuration du stockage Docker, Kubernetes et UC, consultez Agents de trace déployés en dehors de Databricks.
Avancé : API client bas niveau
L’API MlflowClient vous offre un contrôle direct sur chaque aspect du cycle de vie de la trace. La plupart des agents n’en ont pas besoin ; utilisez plutôt le décorateur ou le gestionnaire de contexte. Optez pour l’API client lorsque vous avez besoin de schémas d’ID de trace personnalisés ou d’une intégration avec un système d’observabilité existant.
Les APIs clientes ne sont pas interopérables avec le décorateur ou mlflow.start_span(). Utilisez un seul style de manière cohérente au sein d'une trace donnée.
Cycle de vie
Chaque appel à start_trace ou à start_span doit correspondre à un appel à end_trace ou à end_span. Les portées non fermées produisent des traces incomplètes.
Identifiant | Description | Utilisation |
|---|---|---|
| Identifiant unique de trace | Link tous les spans de la trace |
| Identifiant de span unique | Identifie la portée à terminer |
| De l’étendue parente | Crée la hiérarchie parent-enfant |
Utilisation de base
from mlflow import MlflowClient
client = MlflowClient()
root_span = client.start_trace(
name="my_agent_flow",
inputs={"user_id": "123", "action": "generate_report"},
attributes={"environment": "production", "version": "1.0.0"},
)
request_id = root_span.request_id
data_span = client.start_span(
name="fetch_user_data",
request_id=request_id,
parent_id=root_span.span_id,
inputs={"user_id": "123"},
attributes={"database": "users_db"},
)
client.end_span(
request_id=data_span.request_id,
span_id=data_span.span_id,
outputs={"record_count": 42},
status="OK",
)
client.end_trace(
request_id=request_id,
outputs={"report_url": "https://example.com/report/123"},
status="OK",
)
Gestion des erreurs
Toujours fermer les étendues même en l'absence d'exceptions. Un gestionnaire de contexte réutilisable rend cette opération sûre et concise :
from contextlib import contextmanager
@contextmanager
def traced_span(client, name, request_id, parent_id=None, **kwargs):
span = client.start_span(name=name, request_id=request_id, parent_id=parent_id, **kwargs)
try:
yield span
except Exception as e:
client.end_span(request_id=span.request_id, span_id=span.span_id,
status="ERROR", attributes={"error": str(e)})
raise
else:
client.end_span(request_id=span.request_id, span_id=span.span_id, status="OK")
# Usage
with traced_span(client, "my_operation", request_id, parent_id) as span:
result = perform_operation()
Principaux écueils
- Oubli de clôturer les portées — utilisez toujours try/finally ou le modèle de gestionnaire de contexte ci-dessus.
- IDs parents incorrects — vérifiez que vous transmettez le bon
span_iden tant queparent_id. - IDs de trace codés en dur — générez toujours des ID uniques.
- Thread safety — les APIs client ne sont pas thread-safe par default ; gérez la concurrence de manière explicite.
- Utilisation de
mlflow.log_metric()— ceci écrit dans une exécution MLflow, et non dans le span actuel. Utilisezspan.set_attribute()ouspan.set_attributes()à la place.
Custom OpenTelemetry instrumentation
Une instrumentation OTel personnalisée envoyant des traces à Databricks utilise l’ aperçu du traçage OTel . Assurez-vous que cet aperçu est activé dans votre Workspace avant de poursuivre.
Si votre agent utilise directement le SDK OTel plutôt qu’une intégration pré-construite, définissez les attributs de portée décrits dans cette section afin que MLflow restitue correctement les types de portée, les entrées, les sorties et les nombres de tokens. Les intégrations pré-construites définissent ces attributs automatiquement.
Les correspondances d’attributs OTel pour MLflow managé sur Databricks diffèrent de celles d’OSS MLflow. Pour la correspondance des attributs OSS, consultez la documentation MLflow.
Conditions requises
Cette section nécessite une expérimentation prise en charge par Unity Catalog avec un emplacement de trace OTel et la préversion du traçage OTel activée dans votre workspace. Voir Exigences.
Définir le type d’étendue
Définissez gen_ai.operation.name pour identifier le type d'opération. MLflow lit cet attribut et affiche le type d'intervalle MLflow correspondant dans l'interface utilisateur de suivi. La valeur respecte la convention sémantique GenAI OpenTelemetry.
Valeur de | Type d'étendue MLflow |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
span.set_attribute("gen_ai.operation.name", "chat")
Définir les entrées et les sorties
Définissez gen_ai.input.messages et gen_ai.output.messages sur chaque portée qui doit afficher les entrées et les sorties. Les définir sur la racine de la portée permet également de remplir les aperçus de requêtes et de réponses au niveau de la trace.
Attribut OTel | Attribut MLflow |
|---|---|
|
|
|
|
Les valeurs peuvent être des chaînes simples ou des chaînes sérialisées au format JSON. Les tableaux JSON d'objets de message avec les champs role et content permettent un rendu plus riche dans l'interface utilisateur de MLflow (bulles étiquetées « User » et « Assistant ») :
import json
# Plain string — displays as-is in the UI
span.set_attribute("gen_ai.input.messages", "What is the weather today?")
# JSON message array — renders with role labels in the UI
span.set_attribute("gen_ai.input.messages", json.dumps([
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "What is the weather today?"}
]))
span.set_attribute("gen_ai.output.messages", json.dumps([
{"role": "assistant", "content": "It is sunny and 72°F in San Francisco."}
]))
Définir l'utilisation des jetons
Définissez gen_ai.usage.input_tokens et gen_ai.usage.output_tokens sur le root span pour afficher les comptes de jetons dans le résumé des traces de l'interface utilisateur. MLflow lit ces valeurs à partir du root span, car il agrège les comptes au niveau de la trace.
Attribut OTel | Champ de jeton MLflow |
|---|---|
| Nombre de jetons d'entrée |
| Nombre de jetons de sortie |
(non défini — calculé automatiquement) | Nombre total de jetons |
root.set_attribute("gen_ai.usage.input_tokens", 150)
root.set_attribute("gen_ai.usage.output_tokens", 42)
Définir la session et l'utilisateur
Définissez session.id et user.id pour associer les traces à une session ou à un utilisateur spécifique. MLflow les lit à partir de la portée racine et les affiche sous forme de métadonnées au niveau de la trace. Le paramétrage de session.id active le tab de session dans l’interface utilisateur de MLflow.
Attribut OTel | Champ de métadonnées MLflow |
|---|---|
| Identifiant de session ou de conversation |
| Identifiant d'utilisateur final d'agent |
span.set_attribute("session.id", "conversation-123")
span.set_attribute("user.id", "user-456")
Exemple complet : un agent Python avec une étendue enfant LLM
L’exemple suivant rassemble les quatre catégories d’attributs dans un agent simple doté d’un span enfant LLM. Cet exemple suppose que vous avez déjà configuré l’exportateur OTLP pour envoyer des traces à Databricks.
import json
from opentelemetry import trace
tracer = trace.get_tracer("my-agent")
def run_agent(query: str) -> str:
with tracer.start_as_current_span("agent-run") as root:
# Child LLM span — set gen_ai attributes for this individual call
with tracer.start_as_current_span("chat") as llm:
llm.set_attribute("gen_ai.operation.name", "chat")
messages = [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": query}
]
response = call_llm(messages)
llm.set_attribute("gen_ai.input.messages", json.dumps(messages))
llm.set_attribute("gen_ai.output.messages", json.dumps([
{"role": "assistant", "content": response}
]))
llm.set_attribute("gen_ai.usage.input_tokens", 150)
llm.set_attribute("gen_ai.usage.output_tokens", 42)
# Root span — MLflow reads inputs, outputs, token usage, and session ID
# from the root span to populate the trace summary in the UI.
root.set_attribute("gen_ai.operation.name", "chat")
root.set_attribute("session.id", "conversation-123")
root.set_attribute("user.id", "user-456")
root.set_attribute("gen_ai.input.messages", json.dumps([
{"role": "user", "content": query}
]))
root.set_attribute("gen_ai.output.messages", json.dumps([
{"role": "assistant", "content": response}
]))
root.set_attribute("gen_ai.usage.input_tokens", 150)
root.set_attribute("gen_ai.usage.output_tokens", 42)
return response
Vérifier dans l'interface utilisateur MLflow
Après avoir appelé run_agent(), ouvrez l'onglet Traces de votre expérimentation MLflow. Une trace correctement instrumentée indique :
- Types d’étendue : chaque étendue affiche son libellé de type (par exemple,
chat) au lieu deUNKNOWN. - Requête et réponse : La portée racine affiche les messages d’entrée et de sortie.
- Utilisation des jetons : le récapitulatif des traces affiche les nombres de jetons d'entrée, de sortie et le total.
- Session et utilisateur : la trace apparaît dans la tab de session sous l'identifiant de session spécifié, et l'ID utilisateur apparaît dans les métadonnées de la trace.

Rechercher des traces par attributs de span OTel
Une fois les traces ingérées dans Unity Catalog — que ce soit à partir de Langfuse ou d’un agent instrumenté OTel personnalisé —, utilisez le préfixe span.attributes.* dans mlflow.search_traces() pour filtrer par les valeurs d’attribut OTel que vous avez définies. Le nom de l’attribut après le préfixe est le même que celui transmis à span.set_attribute().
import mlflow
# experiment_id is visible in the MLflow UI URL and experiment details panel
mlflow.set_experiment(experiment_id="<experiment-id>")
# Find traces from a specific session (set using session.id)
traces = mlflow.search_traces(
filter_string="span.attributes.session.id = 'conversation-123'"
)
# Find traces from a specific user (set using user.id)
traces = mlflow.search_traces(
filter_string="span.attributes.user.id = 'user-456'"
)
# Find traces from a specific model (set using gen_ai.request.model)
traces = mlflow.search_traces(
filter_string="span.attributes.gen_ai.request.model LIKE '%gpt%'"
)
# Find traces by operation type (set using gen_ai.operation.name)
traces = mlflow.search_traces(
filter_string="span.attributes.gen_ai.operation.name = 'chat'"
)
# Find high-token traces (set using gen_ai.usage.input_tokens)
traces = mlflow.search_traces(
filter_string="span.attributes.gen_ai.usage.input_tokens > 1000"
)
Pour connaître la syntaxe complète de filter_string, y compris les opérateurs et comparateurs pris en charge, consultez Accès programmatique aux traces.
Limitations
Les attributs de portée OTel personnalisés ne sont pas affichés en tant qu'étiquettes de trace MLflow. Les attributs définis avec span.set_attribute() en dehors des correspondances OTel vers MLflow reconnues n'apparaissent pas dans :
- La colonne Tags ou la vue unifiée des traces dans l’interface utilisateur MLflow.
- La table Unity Catalog
_traces_unified. - Le champ
tagsrenvoyé parmlflow.search_traces().
Ces attributs sont conservés sur l’étendue sous-jacente. Elles restent visibles dans l’onglet Attributes tab de l’interface utilisateur des traces et peuvent être interrogées via le champ <prefix>_otel_spans.attributes de la table des étendues OTel.
Pour joindre des tags interrogeables qui apparaissent dans la vue unifiée des traces, utilisez les API de tag MLflow. Voir Enrichir les traces : tags, contexte et commentaires.
Référence du modèle de données de trace
Les attributs d’étendue, les types d’étendue et les concepts de cycle de vie ci-dessous s’appliquent à toute étendue que vous créez, que ce soit par le biais d’un décorateur, d’un gestionnaire de contexte ou du client de bas niveau.
Attributs de portée
Les attributs sont des paires clé-valeur qui fournissent des insight sur la configuration et le contexte d'exécution d'une opération.
Vous pouvez ajouter des attributs spécifiques à la plate-forme pour enrichir l’observabilité. Par exemple, vous pouvez ajouter les objets Unity Catalog touchés par la portée, l’ endpoint de serveur de modèle ou la ressource de compute.
Par exemple, définissez des attributs sur une étendue qui encapsule un appel LLM :
span.set_attributes({
"ai.model.name": "claude-3-5-sonnet-20241022",
"ai.model.version": "2024-10-22",
"ai.model.provider": "anthropic",
"ai.model.temperature": 0.7,
"ai.model.max_tokens": 1000,
})
Types d’étendue
MLflow fournit des valeurs prédéfinies SpanType pour les opérations courantes. Pour des cas spécialisés, passez une valeur de chaîne personnalisée comme type de portée.
Type | Description |
|---|---|
| Query vers un modèle de chat (interaction LLM spécialisée) |
| Chaîne d'opérations |
| Opération d'agent autonome |
| Exécution d’outils (généralement par des agents), telles que des search queries |
| Opération d'intégration de texte |
| Opération de récupération de contexte telle que des queries de base de données vectorielle |
| Opération de parsing transformant le texte en format structuré |
| Opération de réévaluation ordonnant les contextes par pertinence |
| Opération mémoire persistant le contexte dans le stockage à long terme |
| default type used when no other type is specified |
Vous attribuez un type d’étendue lorsque vous créez l’étendue. Voir Personnaliser les étendues pour savoir comment définir span_type sur le décorateur, ou le gestionnaire de contexte pour un bloc d’étendue.
Traces et étendues actives ou terminées
Une trace active est une trace en cours d’écriture par MLflow, par exemple pendant l’exécution d’une fonction décorée avec @mlflow.trace. Une fois que la fonction décorée s’est terminée, la trace est terminée , mais vous pouvez toujours l’annoter avec de nouvelles données.
Les portées suivent le même cycle de vie. Une portée active, représentée par LiveSpan, est produite par une fonction décorée ou un gestionnaire de contexte de portée. Une fois que la fonction se termine ou que le gestionnaire de contexte se ferme, la portée est terminée et devient un élément Span immuable.
Pour travailler avec des traces et des étendues actives ou récentes, utilisez ces méthodes :
mlflow.get_active_trace_id(): renvoie l’identifiant de la trace actuellement active.mlflow.get_last_active_trace_id(): renvoie l'identifiant de la trace terminée la plus récente.mlflow.get_current_active_span(): renvoie la portée active afin que vous puissiez la modifier.
Ressources supplémentaires
- Automatic tracing and integrations — Instrumenter un framework pris en charge avec une seule ligne de code
- Observer et détecter les problèmes — Afficher et analyser vos traces collectées
- Stocker les traces OpenTelemetry dans Unity Catalog — Stockage de traces Unity Catalog gouverné pour la production
- Enrichir les traces : tags, contexte et retours d'information — Associer des tags, des ID de session utilisateur et des retours d'information utilisateur aux traces
- Évaluez la qualité de l’agent : exécutez des évaluations sur vos traces
Étape suivante : Enrichir les traces : tags, contexte et retours d'information