Festlegen von OpenTelemetry-Span-Attributen für MLflow

Wenn Sie Ablaufverfolgungen aus einer benutzerdefinierten OpenTelemetry-instrumentierten (OTel)-Anwendung an Azure Databricks MLflow senden, müssen Sie bestimmte Span-Attribute festlegen, um Die Ablaufverfolgungsdaten in der MLflow-Benutzeroberfläche korrekt zu rendern. Diese Seite zeigt Ihnen, welche OpenTelemetry GenAI Semantic Convention-Attribute festgelegt werden sollen.

Wenn Sie eine vordefinierte Integration wie Langfuse verwenden, legt diese Integration diese Attribute automatisch fest. Diese Seite ist für Anwendungen mit benutzerdefinierter OTel-Instrumentierung vorgesehen.

Hinweis

Die Attribute in in Azure Databricks verwaltetem MLflow unterscheiden sich von OSS (Open-Source-Software) MLflow. Die Zuordnung des OSS MLflow-Attributs finden Sie in der MLflow-Dokumentation.

Anforderungen

Bevor Sie beginnen, stellen Sie sicher, dass Sie folgendes haben:

  • Ein Azure Databricks Arbeitsbereich mit aktivierter OTel-Ablaufverfolgungsvorschau
  • Der OTLP-Exporter ist so konfiguriert, dass er Traces an Ihren Arbeitsbereich sendet. Siehe Protokollablaufverfolgungen in den Unity-Katalogtabellen.
  • Eine Anwendung, die mit dem OpenTelemetry SDK instrumentiert ist

Span-Typ festlegen

Jede Spanne in Ihrer Ablaufverfolgung benötigt eine Typbezeichnung, damit MLflow identifizieren kann, welche Art von Vorgang sie darstellt. Legen Sie gen_ai.operation.name auf einen der Werte in der folgenden Tabelle fest, indem Sie span.set_attribute("gen_ai.operation.name", "<value>") aufrufen. MLflow liest dieses Attribut aus und zeigt den entsprechenden MLflow-Span-Typ in der Trace-Benutzeroberfläche an.

OTel-Wert gen_ai.operation.name MLflow-Spannweitentyp
chat CHAT_MODEL
text_completion LLM
generate_content LLM
response LLM
embeddings EMBEDDING
execute_tool TOOL
create_agent AGENT
invoke_agent AGENT
span.set_attribute("gen_ai.operation.name", "chat")

Festlegen von Eingaben und Ausgaben

Legen Sie gen_ai.input.messages und gen_ai.output.messages auf jeder Spanne fest, die Eingaben und Ausgaben anzeigen soll. Durch das Festlegen auf die Stammspanne werden auch die Anforderungs- und Antwortvorschauen auf Ablauflaufeverfolgungsebene ausgefüllt.

OTel-Attribut MLflow-Attribut
gen_ai.input.messages mlflow.spanInputs
gen_ai.output.messages mlflow.spanOutputs

Werte können einfache Zeichenfolgen oder JSON-serialisierte Zeichenfolgen sein. Die Verwendung von JSON-Arrays von Nachrichtenobjekten mit role und content Feldern ermöglicht ein umfangreicheres Rendering in der MLflow-Oberfläche (z. B. als "Benutzer" und "Assistent"-Blasen).

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."}
]))

Festlegen der Tokenverwendung

Um die Tokenanzahl in der Zusammenfassung der UI-Ablaufverfolgung anzuzeigen, setzen Sie gen_ai.usage.input_tokens und gen_ai.usage.output_tokens ein, indem Sie span.set_attribute() auf dem Wurzel-Intervall aufrufen. MLflow liest diese Werte speziell aus dem Root-Span, da sie die Anzahl auf Trace-Ebene aggregiert.

OTel-Attribut gen_ai.usage.* MLflow-Tokenfeld
gen_ai.usage.input_tokens Anzahl von Eingabetoken
gen_ai.usage.output_tokens Ausgabetokenanzahl
(nicht festgelegt — automatisch berechnet) Gesamtzahl der Token
root.set_attribute("gen_ai.usage.input_tokens", 150)
root.set_attribute("gen_ai.usage.output_tokens", 42)

Festlegen von Sitzung und Benutzer

Wenn Sie Ablaufverfolgungen mit einer bestimmten Sitzung oder einem bestimmten Benutzer verknüpfen möchten, setzen Sie session.id und user.id auf eine beliebige Spanne, indem Sie span.set_attribute() aufrufen. MLflow liest diese Attribute aus dem Root-Span und zeigt sie als Metadaten auf Traceebene an. Die Einstellung session.id aktiviert die Sitzungsregisterkarte in der MLflow-Benutzeroberfläche.

OTel-Attribut MLflow-Metadatenfeld
session.id Sitzungs- oder Konversationsbezeichner
user.id Anwendungs-Endbenutzer-ID
span.set_attribute("session.id", "conversation-123")
span.set_attribute("user.id", "user-456")

Vollständiges Beispiel: Instrumentierung eines Python-Agents

Im folgenden Beispiel werden alle vier Attributkategorien in einem einfachen Agent mit einer untergeordneten LLM-Spanne zusammengefasst. Es wird davon ausgegangen, dass Sie den OTLP-Exporter bereits so konfiguriert haben, dass Ablaufverfolgungen an Azure Databricks gesendet werden.

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

Überprüfen in der MLflow-Benutzeroberfläche

Öffnen Sie nach dem Aufrufen run_agent() die Registerkarte "MLflow-Ablaufverfolgungen" in Ihrem Experiment. Eine richtig instrumentierte Spur zeigt:

  • Span-Typen: Jeder Bereich zeigt seine Typbezeichnung (z. B chat. ) anstelle von UNKNOWN
  • Anforderung und Antwort: Die Stammspanne zeigt die Eingabenachrichten und Ausgabemeldungen an.
  • Tokenverwendung: Die Ablaufverfolgungszusammenfassung zeigt Eingabe-, Ausgabe- und Gesamttokenanzahlen an.
  • Sitzung und Benutzer: Die Ablaufverfolgung wird auf der Registerkarte "Sitzung" unter dem angegebenen Sitzungsbezeichner angezeigt, und die Benutzer-ID ist in den Ablaufverfolgungsmetadaten sichtbar.

OTel GenAI-Ablaufverfolgung in MLflow

Suchen nach Ablaufverfolgungen anhand von OTel-Span-Attributen

Verwenden Sie nach dem Erfassen von OTel-Ablaufverfolgungen im Unity Catalog das Präfix span.attributes.* in mlflow.search_traces(), um nach den von Ihnen festgelegten OTel-Attributwerten zu filtern. Der Attributname nach dem Präfix ist derselbe OTel-Attributname, den Sie mit span.set_attribute() festgelegt haben.

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"
)

Die vollständige filter_string-Syntax einschließlich unterstützter Operatoren und Vergleichszeichen finden Sie unter programmgesteuert Suchablaufverfolgungen.

Nächste Schritte