Aller au contenu principal

Tutoriel : évaluer et améliorer une application GenAI

Les datasets d'évaluation vous permettent de mesurer la qualité d'une application GenAI, d'identifier les problèmes et de vérifier que les améliorations fonctionnent sans introduire de régressions. Ce tutoriel explique comment évaluer et améliorer de manière itérative une application de génération d'e-mails qui utilise la génération augmentée de récupération (RAG).

Ce guide vous présente l'évaluation d'une application de génération d'e-mails qui utilise la génération augmentée par récupération (RAG). L'application simule la récupération des informations des clients à partir d'une base de données et génère des e-mails de suivi personnalisés basés sur les informations récupérées.

Pour une introduction plus courte à l'évaluation, consultez démonstration de 10 minutes : évaluer une application GenAI.

Ce tutoriel comprend les étapes suivantes :

  • Créez des datasets d'évaluation à partir de données d'utilisation réelles.
  • Évaluez la qualité avec les juges LLM de MLflow à l'aide du faisceau d'évaluation.
  • Interpréter les résultats pour identifier les problèmes de qualité.
  • Améliorez votre application en fonction des résultats de l’évaluation.
  • Comparez les versions pour vérifier que les améliorations ont fonctionné et n'ont pas causé de régressions.

Le tutoriel utilise des traces d'une application déployée pour créer le dataset d'évaluation, mais le même workflow s'applique quelle que soit la façon dont vous avez créé votre dataset d'évaluation. Pour d'autres approches de création d'un dataset d'évaluation, consultez Création de datasets d'évaluation MLflow. Pour en savoir plus sur le traçage, consultez MLflow Tracing - Observabilité GenAI.

Diagramme de workflow de monitoring hors ligne

Prérequis

  1. Installez les packages requis :

    Python
    %pip install -q --upgrade "mlflow[databricks]>=3.1.0" openai
    dbutils.library.restartPython()
  2. Créez une Experimentation MLflow. Si vous utilisez un Notebook Databricks, vous pouvez ignorer cette étape et utiliser l'Experimentation Notebook par default. Sinon, suivez le guide de démarrage rapide de la configuration de l'environnement pour créer l'Experimentation et vous connecter au serveur MLflow Tracking.

  3. Pour créer un dataset d'évaluation, vous devez disposer des autorisations CREATE TABLE sur un schéma dans Unity Catalog.

    Si vous utilisez un compte d’essai Databricks, vous devez disposer des autorisations CREATE TABLE sur le schéma Unity Catalog workspace.default.

remarque

L'exécution d'un agent complexe peut prendre beaucoup de temps. Pour configurer la parallélisation, consultez (Facultatif) Configurer la parallélisation.

Étape 1 : Créez votre application

La première étape consiste à créer l'application de génération d'e-mail. Le composant de récupération est marqué avec span_type="RETRIEVER" pour activer les juges LLM spécifiques à la récupération de MLflow.

  1. Initialisez un client OpenAI pour vous connecter soit à des LLM hébergés par Databricks, soit à des LLM hébergés par OpenAI.

Utilisez databricks-openai pour obtenir un client OpenAI qui se connecte aux LLM hébergés par Databricks. Sélectionnez un modèle parmi les modèles de fondation disponibles.

Python
import mlflow
from databricks_openai import DatabricksOpenAI

# Enable MLflow's autologging to instrument your application with Tracing
mlflow.openai.autolog()

# Set up MLflow tracking to Databricks
mlflow.set_tracking_uri("databricks")
mlflow.set_experiment("/Shared/docs-demo")

# Create an OpenAI client that is connected to Databricks-hosted LLMs
client = DatabricksOpenAI()

# Select an LLM
model_name = "databricks-claude-sonnet-4"
  1. Créez l'application de génération d'e-mails :

    Python
    from mlflow.entities import Document
    from typing import List, Dict

    # Simulated customer relationship management database
    CRM_DATA = {
    "Acme Corp": {
    "contact_name": "Alice Chen",
    "recent_meeting": "Product demo on Monday, very interested in enterprise features. They asked about: advanced analytics, real-time dashboards, API integrations, custom reporting, multi-user support, SSO authentication, data export capabilities, and pricing for 500+ users",
    "support_tickets": ["Ticket #123: API latency issue (resolved last week)", "Ticket #124: Feature request for bulk import", "Ticket #125: Question about GDPR compliance"],
    "account_manager": "Sarah Johnson"
    },
    "TechStart": {
    "contact_name": "Bob Martinez",
    "recent_meeting": "Initial sales call last Thursday, requested pricing",
    "support_tickets": ["Ticket #456: Login issues (open - critical)", "Ticket #457: Performance degradation reported", "Ticket #458: Integration failing with their CRM"],
    "account_manager": "Mike Thompson"
    },
    "Global Retail": {
    "contact_name": "Carol Wang",
    "recent_meeting": "Quarterly review yesterday, happy with platform performance",
    "support_tickets": [],
    "account_manager": "Sarah Johnson"
    }
    }

    # Use a retriever span to enable MLflow's predefined RetrievalGroundedness judge to work
    @mlflow.trace(span_type="RETRIEVER")
    def retrieve_customer_info(customer_name: str) -> List[Document]:
    """Retrieve customer information from CRM database"""
    if customer_name in CRM_DATA:
    data = CRM_DATA[customer_name]
    return [
    Document(
    id=f"{customer_name}_meeting",
    page_content=f"Recent meeting: {data['recent_meeting']}",
    metadata={"type": "meeting_notes"}
    ),
    Document(
    id=f"{customer_name}_tickets",
    page_content=f"Support tickets: {', '.join(data['support_tickets']) if data['support_tickets'] else 'No open tickets'}",
    metadata={"type": "support_status"}
    ),
    Document(
    id=f"{customer_name}_contact",
    page_content=f"Contact: {data['contact_name']}, Account Manager: {data['account_manager']}",
    metadata={"type": "contact_info"}
    )
    ]
    return []

    @mlflow.trace
    def generate_sales_email(customer_name: str, user_instructions: str) -> Dict[str, str]:
    """Generate personalized sales email based on customer data & a sale's rep's instructions."""
    # Retrieve customer information
    customer_docs = retrieve_customer_info(customer_name)

    # Combine retrieved context
    context = "\n".join([doc.page_content for doc in customer_docs])

    # Generate email using retrieved context
    prompt = f"""You are a sales representative. Based on the customer information below,
    write a brief follow-up email that addresses their request.

    Customer Information:
    {context}

    User instructions: {user_instructions}

    Keep the email concise and personalized."""

    response = client.chat.completions.create(
    model=model_name, # This example uses a Databricks hosted LLM - you can replace this with any AI Gateway or Model Serving endpoint. If you provide your own OpenAI credentials, replace with a valid OpenAI model e.g., gpt-4o, etc.
    messages=[
    {"role": "system", "content": "You are a helpful sales assistant."},
    {"role": "user", "content": prompt}
    ],
    max_tokens=2000
    )

    return {"email": response.choices[0].message.content}

    # Test the application
    result = generate_sales_email("Acme Corp", "Follow up after product demo")
    print(result["email"])

Évaluation de la trace d'application

Étape 2 : Simuler le trafic de production

Cette étape simule le trafic à des fins de démonstration. En pratique, vous utiliseriez des traces d'utilisation réelle pour créer votre dataset d'évaluation.

Python
# Simulate beta testing traffic with scenarios designed to fail guidelines
test_requests = [
{"customer_name": "Acme Corp", "user_instructions": "Follow up after product demo"},
{"customer_name": "TechStart", "user_instructions": "Check on support ticket status"},
{"customer_name": "Global Retail", "user_instructions": "Send quarterly review summary"},
{"customer_name": "Acme Corp", "user_instructions": "Write a very detailed email explaining all our product features, pricing tiers, implementation timeline, and support options"},
{"customer_name": "TechStart", "user_instructions": "Send an enthusiastic thank you for their business!"},
{"customer_name": "Global Retail", "user_instructions": "Send a follow-up email"},
{"customer_name": "Acme Corp", "user_instructions": "Just check in to see how things are going"},
]

# Run requests and capture traces
print("Simulating production traffic...")
for req in test_requests:
try:
result = generate_sales_email(**req)
print(f"✓ Generated email for {req['customer_name']}")
except Exception as e:
print(f"✗ Error for {req['customer_name']}: {e}")

Étape 3 : Créer un dataset d’évaluation

À cette étape, vous enregistrez les traces dans un dataset d’évaluation. Stocker les traces dans un dataset d'évaluation vous permet de lier les résultats d'évaluation au dataset afin que vous puissiez suivre les modifications apportées à celui-ci au fil du temps et voir tous les résultats d'évaluation générés à l'aide de ce dataset.

  1. Cliquez sur **Expériences** dans la barre latérale pour afficher la page Expériences.

  2. Cliquez sur le nom de votre experimentation pour l'ouvrir.

    Ouvrir l'expérimentation

  3. Dans la barre latérale gauche, cliquez sur **Traces**.

  4. Utilisez les cases à cocher sur le côté gauche de la liste de traces pour sélectionner les traces que vous souhaitez ajouter. Pour sélectionner toutes les traces de la page actuelle, cliquez sur la case à cocher à côté de **Trace ID** dans l’en-tête de colonne.

    Sélectionner des traces

  5. Cliquez sur Actions . L'étiquette du bouton indique le nombre de traces sélectionnées, par exemple Actions (3) .

    Menu Actions

  6. Sous **Utiliser pour l'évaluation**, sélectionnez **Ajouter au dataset d'évaluation**. La boîte de dialogue **Ajouter des traces au dataset d’évaluation** s’ouvre.

  7. Si aucun dataset d'évaluation n'existe pour cette expérimentation, ou si vous souhaitez ajouter des traces à un nouveau dataset, suivez ces étapes pour créer un nouveau dataset d'évaluation :

    1. Cliquez sur Créer un nouveau dataset .
    2. Sélectionnez le schéma Unity Catalog pour contenir le nouveau dataset.
    3. Saisissez un nom pour le dataset et cliquez sur **Créer un dataset**.
    4. Cliquez sur Exporter , puis sur Terminé .

    Ajouter une boîte de dialogue de traces si aucun dataset d'évaluation n'existe.

    Si des datasets d'évaluation existent déjà pour l'Experiment, cliquez sur **Exporter** à droite du dataset auquel vous souhaitez ajouter les traces. Vous pouvez exporter vers plus d'un dataset. Lorsque vous avez terminé l'exportation, cliquez sur **Terminé**.

    Ajouter une boîte de dialogue de traces si avec des datasets d'évaluation existants

Étape 4 : Exécuter l'évaluation avec des juges LLM

Dans cette étape, vous utilisez les juges LLM intégrés de MLflow pour évaluer automatiquement différents aspects de la qualité de l’application GenAI. Pour en savoir plus, consultez les juges LLM et les évaluateurs basés sur le code.

Python
from mlflow.genai.scorers import (
RetrievalGroundedness,
RelevanceToQuery,
Safety,
Guidelines,
)

# Save the LLM judges as a variable so you can re-use them in step 7

email_judges = [
RetrievalGroundedness(), # Checks if email content is grounded in retrieved data
Guidelines(
name="follows_instructions",
guidelines="The generated email must follow the user_instructions in the request.",
),
Guidelines(
name="concise_communication",
guidelines="The email MUST be concise and to the point. The email should communicate the key message efficiently without being overly brief or losing important context.",
),
Guidelines(
name="mentions_contact_name",
guidelines="The email MUST explicitly mention the customer contact's first name (e.g., Alice, Bob, Carol) in the greeting. Generic greetings like 'Hello' or 'Dear Customer' are not acceptable.",
),
Guidelines(
name="professional_tone",
guidelines="The email must be in a professional tone.",
),
Guidelines(
name="includes_next_steps",
guidelines="The email MUST end with a specific, actionable next step that includes a concrete timeline.",
),
RelevanceToQuery(), # Checks if email addresses the user's request
Safety(), # Checks for harmful or inappropriate content
]

# Run evaluation with LLM judges
eval_results = mlflow.genai.evaluate(
data=eval_dataset,
predict_fn=generate_sales_email,
scorers=email_judges,
)

Étape 5 : Afficher et interpréter les résultats

L'exécution de mlflow.genai.evaluate() crée une exécution d'évaluation. Pour plus de détails, consultez les exécutions d'évaluation dans MLflow.

Une exécution d'évaluation est comme un rapport de test qui capture tout sur la façon dont votre application a fonctionné sur un dataset spécifique. L'exécution de l'évaluation contient une trace pour chaque ligne de votre dataset d'évaluation, annotée avec les commentaires de chaque juge.

En utilisant l'exécution d'évaluation, vous pouvez afficher les métriques agrégées et étudier les cas de test où votre application a mal fonctionné.

Cette évaluation montre plusieurs problèmes :

  • **Mauvaise exécution des instructions** - L'agent fournit fréquemment des réponses qui ne correspondent pas aux demandes de l'utilisateur, comme l'envoi d'informations détaillées sur les produits lorsqu'on lui demande de simples enregistrements, ou la fourniture de mises à jour de tickets de support lorsqu'on lui demande des messages de remerciement enthousiastes.
  • Manque de concision – La plupart des e-mails sont inutilement longs et contiennent des détails excessifs qui diluent le message clé, ne parvenant pas à communiquer efficacement malgré les instructions de garder les e-mails « concis et personnalisés ».
  • Absence d’étapes suivantes concrètes - La majorité des e-mails ne se terminent pas par des étapes suivantes précises et exploitables, avec des délais concrets, ce qui a été identifié comme un élément requis.

Résumé de l'évaluation

  1. Cliquez sur **Expériences** dans la barre latérale pour afficher la page Expériences.

  2. Cliquez sur le nom de votre experimentation pour l'ouvrir.

  3. Dans la barre latérale gauche, cliquez sur Exécutions d'évaluation . Le volet de droite affiche un tableau de traces.

    Tableau des exécutions d'évaluation

    Si vous ne voyez pas les Évaluations avec leurs étiquettes Réussite et Échec , faites défiler vers la droite ou survolez le séparateur de volet et cliquez sur la flèche pointant vers la gauche.

    Développer la table

  4. Pour voir la justification de l'étiquette Réussite ou Échec , passez la souris sur l'étiquette.

    Survoler l'étiquette pour afficher la justification.

Détails et ajout de commentaires.

Pour voir plus de détails pour chaque trace :

  1. Cliquez sur l'identifiant de la demande dans la colonne **Demande**. Une fenêtre apparaît, affichant la trace complète, y compris les entrées et les sorties pour chaque étape.

    Fenêtre des détails de la requête

  2. À droite, vous pouvez ajouter des commentaires ou des attentes à appliquer à la réponse pour cette demande. Si le volet Évaluations n’apparaît pas, cliquez sur Bouton d'évaluations. Pour ajouter une nouvelle Évaluation, faites défiler l’écran vers le bas et cliquez sur Bouton Ajouter une nouvelle évaluation.

  3. Vous pouvez utiliser les flèches de chaque côté de cette fenêtre pour parcourir les requêtes.

    Parcourir les requêtes à l'aide des flèches

Étape 6 : Créer une version améliorée

Utilisez les résultats de l'évaluation pour créer une version améliorée qui résout les problèmes identifiés.

Lors de la création d'une version améliorée, concentrez-vous sur les changements ciblés basés sur les résultats de l'évaluation. Les stratégies d'amélioration courantes incluent :

  • Ingénierie de prompt : Affinez les invites système pour traiter les modèles d'échec spécifiques, ajoutez des directives explicites pour les cas limites, incluez des exemples démontrant une gestion correcte, ou ajustez le ton ou le style.
  • Gardes-fous : implémentez des étapes de validation dans la logique de l’application et ajoutez un post-traitement pour vérifier les résultats avant de les présenter aux utilisateurs.
  • Améliorations de la récupération (pour les applications RAG) : améliorer les mécanismes de récupération si les documents pertinents ne sont pas trouvés en examinant les étendues de récupération, en améliorant les modèles d'intégration ou en affinant les stratégies de découpage.
  • Améliorations du raisonnement : Découper les tâches complexes en plusieurs segments, implémenter des techniques de chaîne de pensée ou ajouter des étapes de vérification pour les sorties critiques.

Le code ci-dessous présente des améliorations de l'ingénierie de prompt basées sur les résultats de l'évaluation :

Python
@mlflow.trace
def generate_sales_email_v2(customer_name: str, user_instructions: str) -> Dict[str, str]:
"""Generate personalized sales email based on customer data & a sale's rep's instructions."""
# Retrieve customer information
customer_docs = retrieve_customer_info(customer_name) # retrive_customer_info is defined in Step 1

if not customer_docs:
return {"error": f"No customer data found for {customer_name}"}

# Combine retrieved context
context = "\n".join([doc.page_content for doc in customer_docs])

# Generate email using retrieved context with better instruction following
prompt = f"""You are a sales representative writing an email.

MOST IMPORTANT: Follow these specific user instructions exactly:
{user_instructions}

Customer context (only use what's relevant to the instructions):
{context}

Guidelines:
1. PRIORITIZE the user instructions above all else
2. Keep the email CONCISE - only include information directly relevant to the user's request
3. End with a specific, actionable next step that includes a concrete timeline (e.g., "I'll follow up with pricing by Friday" or "Let's schedule a 15-minute call this week")
4. Only reference customer information if it's directly relevant to the user's instructions

Write a brief, focused email that satisfies the user's exact request."""

response = client.chat.completions.create(
model="databricks-claude-sonnet-4-5",
messages=[
{"role": "system", "content": "You are a helpful sales assistant who writes concise, instruction-focused emails."},
{"role": "user", "content": prompt}
],
max_tokens=2000
)

return {"email": response.choices[0].message.content}

# Test the application
result = generate_sales_email("Acme Corp", "Follow up after product demo")
print(result["email"])

Étape 7 : Évaluez la nouvelle version et comparez

Exécutez l'évaluation sur la version améliorée en utilisant les mêmes évaluateurs et dataset pour voir si vous avez réussi à résoudre les problèmes.

Python
import mlflow

# Run evaluation of the new version with the same judges as before
# Use start_run to name the evaluation run in the UI
with mlflow.start_run(run_name="v2"):
eval_results_v2 = mlflow.genai.evaluate(
data=eval_dataset, # same eval dataset
predict_fn=generate_sales_email_v2, # new app version
scorers=email_judges, # same judges as step 4
)

Étape 8 : comparer les résultats

Comparez les résultats pour comprendre si les modifications ont amélioré la qualité.

  1. Cliquez sur **Expériences** dans la barre latérale pour afficher la page Expériences.

  2. Cliquez sur le nom de votre experimentation pour l'ouvrir.

  3. Dans la barre latérale gauche, cliquez sur Exécutions d'évaluation . Le volet de gauche affiche une liste d’exécutions d’évaluation pour cette Expérimentation.

    Volet Exécutions

  4. Cochez les cases des exécutions que vous souhaitez comparer.

  5. Dans le menu déroulant **Actions**, sélectionnez **Comparer**.

    Sélectionnez les exécutions à comparer

  6. Le volet de droite affiche une comparaison de chaque trace dans les exécutions sélectionnées.

    Écran de comparaison des traces

  7. Pour plus de détails, cliquez sur l’identifiant de requête dans la colonne Request . Une fenêtre s'affiche, montrant les traces complètes de la requête pour chaque exécution sélectionnée pour la comparaison.

    Fenêtre des détails de comparaison

    Pour afficher les détails de chaque évaluation, cliquez sur Voir les détails . Pour voir les détails de la trace, cliquez sur Afficher la vue détaillée de la trace .

Étape 9 : Continuer l’itération

En fonction des résultats de l’évaluation, vous pouvez continuer à itérer pour améliorer la qualité de l’application et tester chaque nouveau correctif.

Exemple de Notebook

Le Notebook suivant inclut l'ensemble du code sur cette page.

Évaluation d'un Notebook de démarrage rapide d'application GenAI.

Ressources supplémentaires