Udostępnij za pośrednictwem


Obserwowalność produkcji ze śledzeniem

Śledzenie MLflow zapewnia kompleksową obserwowalność dla produkcyjnych aplikacji GenAI wdrożonych poza usługą Databricks, przechwytując szczegóły wykonywania i wysyłając je do obszaru roboczego usługi Databricks, w którym można je wyświetlić w interfejsie MLflow.

Przegląd śledzenia produkcji w MLflow

Jak działa śledzenie produkcji:

  1. Aplikacja generuje ślady — każde wywołanie interfejsu API tworzy dane śledzenia
  2. Zapisy przechodzą do serwera śledzenia MLflow usługi Databricks — używając poświadczeń do obszaru roboczego
  3. Wyświetl w interfejsie MLflow – analizuj ślady w obszarze roboczym Databricks

Ta strona obejmuje śledzenie aplikacji wdrożonych poza usługą Databricks. Jeśli aplikacja jest wdrażana przy użyciu usługi Databricks Model Serving, zobacz Śledzenie za pomocą usługi Databricks Model Serving.

Wymagania wstępne

Uwaga / Notatka

Śledzenie produkcji wymaga platformy MLflow 3. Funkcja MLflow 2.x nie jest obsługiwana w przypadku śledzenia produkcji.

Zainstaluj wymagane pakiety. W poniższej tabeli opisano opcje:

Temat mlflow-tracing mlflow[databricks]
Zalecany przypadek użycia Wdrożenia produkcyjne Programowanie i eksperymentowanie
Korzyści Minimalne zależności dla sprawnych, szybkich wdrożeń
Wydajność zoptymalizowana pod kątem śledzenia dużych woluminów
Skoncentrowane na śledzeniu po stronie klienta na potrzeby monitorowania produkcyjnego
Pełny zestaw funkcji eksperymentalnych MLflow (interfejs użytkownika, LLM jako sędzia, narzędzia dla deweloperów i inne)
Obejmuje wszystkie narzędzia programistyczne i aplikacje użytkowe.
## Install mlflow-tracing for production deployment tracing
%pip install --upgrade mlflow-tracing

## Install mlflow for experimentation and development
%pip install --upgrade "mlflow[databricks]>=3.1"

Podstawowa konfiguracja śledzenia

Skonfiguruj wdrożenie aplikacji w celu nawiązania połączenia z obszarem roboczym usługi Databricks, aby usługa Databricks mogła zbierać ślady.

Skonfiguruj następujące zmienne środowiskowe:

# Required: Set the Databricks workspace host and authentication token
export DATABRICKS_HOST="https://your-workspace.cloud.databricks.com"
export DATABRICKS_TOKEN="your-databricks-token"

# Required: Set MLflow Tracking URI to "databricks" to log to Databricks
export MLFLOW_TRACKING_URI=databricks

# Required: Configure the experiment name for organizing traces (must be a workspace path)
export MLFLOW_EXPERIMENT_NAME="/Shared/production-genai-app"

Przykłady wdrożeń

Po ustawieniu zmiennych środowiskowych przekaż je do aplikacji. Kliknij karty, aby zobaczyć, jak przekazać szczegóły połączenia do różnych platform.

Doker

W przypadku wdrożeń platformy Docker przekaż zmienne środowiskowe za pośrednictwem konfiguracji kontenera:

# Dockerfile
FROM python:3.9-slim

# Install dependencies
COPY requirements.txt .
RUN pip install -r requirements.txt

# Copy application code
COPY . /app
WORKDIR /app

# Set default environment variables (can be overridden at runtime)
ENV DATABRICKS_HOST=""
ENV DATABRICKS_TOKEN=""
ENV MLFLOW_TRACKING_URI=databricks
ENV MLFLOW_EXPERIMENT_NAME="/Shared/production-genai-app"

CMD ["python", "app.py"]

Uruchom kontener ze zmiennymi środowiskowymi:

docker run -d \
  -e DATABRICKS_HOST="https://your-workspace.cloud.databricks.com" \
  -e DATABRICKS_TOKEN="your-databricks-token" \
  -e MLFLOW_TRACKING_URI=databricks \
  -e MLFLOW_EXPERIMENT_NAME="/Shared/production-genai-app" \
  -e APP_VERSION="1.0.0" \
  your-app:latest

Kubernetes

W przypadku wdrożeń platformy Kubernetes przekaż zmienne środowiskowe przy użyciu obiektów ConfigMaps i wpisów tajnych:

# configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: databricks-config
data:
  DATABRICKS_HOST: 'https://your-workspace.cloud.databricks.com'
  MLFLOW_TRACKING_URI: databricks
  MLFLOW_EXPERIMENT_NAME: '/Shared/production-genai-app'

---
# secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: databricks-secrets
type: Opaque
stringData:
  DATABRICKS_TOKEN: 'your-databricks-token'

---
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: genai-app
spec:
  template:
    spec:
      containers:
        - name: app
          image: your-app:latest
          envFrom:
            - configMapRef:
                name: databricks-config
            - secretRef:
                name: databricks-secrets
          env:
            - name: APP_VERSION
              value: '1.0.0'

Weryfikowanie kolekcji śledzenia

Po wdrożeniu aplikacji sprawdź, czy ślady są prawidłowo zbierane:

import mlflow
from mlflow.client import MlflowClient
import os

# Ensure MLflow is configured for Databricks
mlflow.set_tracking_uri("databricks")

# Check connection to MLflow server
client = MlflowClient()
try:
    # List recent experiments to verify connectivity
    experiments = client.search_experiments()
    print(f"Connected to MLflow. Found {len(experiments)} experiments.")

    # Check if traces are being logged
    traces = mlflow.search_traces(
        experiment_names=[os.getenv("MLFLOW_EXPERIMENT_NAME", "/Shared/production-genai-app")],
        max_results=5
    )
    print(f"Found {len(traces)} recent traces.")
except Exception as e:
    print(f"Error connecting to MLflow: {e}")
    print(f"Check your authentication and connectivity")

Dodawanie kontekstu do śladów

Po wykonaniu podstawowych prac śledzenia dodaj kontekst, aby poprawić debugowanie i uzyskać lepsze wgląd w dane. MLflow ma następujące standardowe tagi i atrybuty do przechwytywania ważnych informacji kontekstowych:

  • Śledzenie żądań — łączenie śladów z określonymi wywołaniami interfejsu API dla kompleksowego debugowania
  • Sesje użytkowników — interakcje związane z grupami w celu zrozumienia podróży użytkowników
  • Dane środowiska — śledzenie, które wdrożenie, wersja lub region wygenerowało każdy ślad
  • Opinie użytkowników — zbieranie ocen jakości i łączenie ich z określonymi interakcjami

Śledzenie żądania, sesji i kontekstu użytkownika

Aplikacje produkcyjne muszą jednocześnie śledzić wiele elementów kontekstu: identyfikatory żądań klienta na potrzeby debugowania, identyfikatory sesji na potrzeby konwersacji wieloeściowych, identyfikatory użytkowników na potrzeby personalizacji i analizy oraz metadane środowiska na potrzeby szczegółowych informacji operacyjnych. Oto kompleksowy przykład pokazujący, jak śledzić wszystkie te elementy w aplikacji FastAPI:

import mlflow
import os
from fastapi import FastAPI, Request, HTTPException
from pydantic import BaseModel

# Initialize FastAPI app
app = FastAPI()

class ChatRequest(BaseModel):
    message: str

@mlflow.trace # Ensure @mlflow.trace is the outermost decorator
@app.post("/chat") # FastAPI decorator should be inner
def handle_chat(request: Request, chat_request: ChatRequest):
    # Retrieve all context from request headers
    client_request_id = request.headers.get("X-Request-ID")
    session_id = request.headers.get("X-Session-ID")
    user_id = request.headers.get("X-User-ID")

    # Update the current trace with all context and environment metadata
    # The @mlflow.trace decorator ensures an active trace is available
    mlflow.update_current_trace(
        client_request_id=client_request_id,
        tags={
            # Session context - groups traces from multi-turn conversations
            "mlflow.trace.session": session_id,
            # User context - associates traces with specific users
            "mlflow.trace.user": user_id,
            # Environment metadata - tracks deployment context
            "environment": "production",
            "app_version": os.getenv("APP_VERSION", "1.0.0"),
            "deployment_id": os.getenv("DEPLOYMENT_ID", "unknown"),
            "region": os.getenv("REGION", "us-east-1")
        }
    )

    # --- Your application logic for processing the chat message ---
    # For example, calling a language model with context
    # response_text = my_llm_call(
    #     message=chat_request.message,
    #     session_id=session_id,
    #     user_id=user_id
    # )
    response_text = f"Processed message: '{chat_request.message}'"
    # --- End of application logic ---

    # Return response
    return {
        "response": response_text
    }

# To run this example (requires uvicorn and fastapi):
# uvicorn your_file_name:app --reload
#
# Example curl request with all context headers:
# curl -X POST "http://127.0.0.1:8000/chat" \
#      -H "Content-Type: application/json" \
#      -H "X-Request-ID: req-abc-123-xyz-789" \
#      -H "X-Session-ID: session-def-456-uvw-012" \
#      -H "X-User-ID: user-jane-doe-12345" \
#      -d '{"message": "What is my account balance?"}'

To połączone podejście zapewnia kilka korzyści:

  • Identyfikator żądania klienta: umożliwia kompleksowe debugowanie przez korelację śladów z określonymi żądaniami klientów w całym systemie
  • Identyfikator sesji (tag: mlflow.trace.session): Grupuje ślady z wieloetapowych konwersacji, które umożliwiają analizowanie pełnego przepływu rozmowy
  • Identyfikator użytkownika (tag: mlflow.trace.user): kojarzy ślady z określonymi użytkownikami na potrzeby personalizacji, analizy kohorty i debugowania specyficznego dla użytkownika
  • Metadane środowiska: śledzi kontekst wdrożenia (środowisko, wersja, region) dla uzyskania wglądu operacyjnego i debugowania w różnych środowiskach wdrożeniowych.

Aby uzyskać więcej informacji na temat dodawania kontekstu do śladów, zobacz dokumentację dotyczącą śledzenia użytkowników i sesji oraz środowisk śledzenia i kontekstu.

Zbieranie opinii użytkowników

Przechwytywanie opinii użytkowników na temat określonych interakcji jest niezbędne do zrozumienia jakości i poprawy aplikacji GenAI. Korzystając ze śledzenia identyfikatora żądania klienta pokazanego w poprzedniej sekcji, w tym przykładzie pokazano, jak używać tego identyfikatora do łączenia opinii z określonymi śladami.

Oto przykład implementacji zbierania opinii w interfejsie FastAPI:

import mlflow
from mlflow.client import MlflowClient
from fastapi import FastAPI, Query, Request
from pydantic import BaseModel
from typing import Optional
from mlflow.entities import AssessmentSource

# Initialize FastAPI app
app = FastAPI()

class FeedbackRequest(BaseModel):
    is_correct: bool  # True for correct, False for incorrect
    comment: Optional[str] = None

@app.post("/chat_feedback")
def handle_chat_feedback(
    request: Request,
    client_request_id: str = Query(..., description="The client request ID from the original chat request"),
    feedback: FeedbackRequest = ...
):
    """
    Collect user feedback for a specific chat interaction identified by client_request_id.
    """
    # Search for the trace with the matching client_request_id
    client = MlflowClient()
    # Get the experiment by name (using Databricks workspace path)
    experiment = client.get_experiment_by_name("/Shared/production-app")
    traces = client.search_traces(
        experiment_ids=[experiment.experiment_id],
        filter_string=f"attributes.client_request_id = '{client_request_id}'",
        max_results=1
    )

    if not traces:
        return {
            "status": "error",
            "message": f"Unable to find data for client request ID: {client_request_id}"
        }, 500

    # Log feedback using MLflow's log_feedback API
    mlflow.log_feedback(
        trace_id=traces[0].info.trace_id,
        name="response_is_correct",
        value=feedback.is_correct,
        source=AssessmentSource(
            source_type="HUMAN",
            source_id=request.headers.get("X-User-ID")
        ),
        rationale=feedback.comment
    )

    return {
        "status": "success",
        "message": "Feedback recorded successfully",
        "trace_id": traces[0].info.trace_id,
        "client_request_id": client_request_id,
        "feedback_by": request.headers.get("X-User-ID")
    }

# Example usage:
# After a chat interaction returns a response, the client can submit feedback:
#
# curl -X POST "http://127.0.0.1:8000/chat_feedback?client_request_id=req-abc-123-xyz-789" \
#      -H "Content-Type: application/json" \
#      -H "X-User-ID: user-jane-doe-12345" \
#      -d '{
#        "is_correct": true,
#        "comment": "The response was accurate and helpful"
#      }'

To podejście do zbierania opinii umożliwia:

  • Połącz opinię z określonymi interakcjami: użyj identyfikatora żądania klienta, aby znaleźć dokładny ślad i dołączyć opinię
  • Przechowywanie opinii ustrukturyzowanych: interfejs log_feedback API tworzy odpowiednie obiekty oceny widoczne w interfejsie użytkownika platformy MLflow
  • Analizowanie wzorców jakości: śledzenie zapytań ze skojarzonymi opiniami w celu zidentyfikowania typów interakcji, które otrzymują pozytywne lub negatywne oceny

Możesz później wykonywać zapytania dotyczące śladów z opiniami, używając interfejsu użytkownika MLflow lub programowo, aby analizować wzorce i ulepszać swoją aplikację.

Ślady zapytań z kontekstem

Użyj informacji kontekstowych do analizowania zachowania produkcyjnego:

import mlflow
from mlflow.client import MlflowClient
import pandas as pd

client = MlflowClient()
experiment = client.get_experiment_by_name("/Shared/production-app")

# Query traces by user
user_traces = client.search_traces(
    experiment_ids=[experiment.experiment_id],
    filter_string="tags.`mlflow.trace.user` = 'user-jane-doe-12345'",
    max_results=100
)

# Query traces by session
session_traces = client.search_traces(
    experiment_ids=[experiment.experiment_id],
    filter_string="tags.`mlflow.trace.session` = 'session-123'",
    max_results=100
)

Dalsze kroki

Kontynuuj pracę z tymi zalecanymi akcjami i samouczkami.

Przewodniki referencyjne

Zapoznaj się ze szczegółową dokumentacją dotyczącą pojęć i funkcji wymienionych w tym przewodniku.