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.

Prérequis
-
Installez les packages requis :
Python%pip install -q --upgrade "mlflow[databricks]>=3.1.0" openai
dbutils.library.restartPython() -
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.
-
Pour créer un dataset d'évaluation, vous devez disposer des autorisations
CREATE TABLEsur 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.
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.
- Initialisez un client OpenAI pour vous connecter soit à des LLM hébergés par Databricks, soit à des LLM hébergés par OpenAI.
- Databricks-hosted LLMs
- OpenAI-hosted LLMs
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.
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"
Utilisez le SDK natif OpenAI pour vous connecter aux modèles hébergés par OpenAI. Sélectionnez un modèle parmi les modèles OpenAI disponibles.
import mlflow
import os
import openai
# Ensure your OPENAI_API_KEY is set in your environment
# os.environ["OPENAI_API_KEY"] = "<YOUR_API_KEY>" # Uncomment and set if not globally configured
# Enable auto-tracing for OpenAI
mlflow.openai.autolog()
# Set up MLflow tracking to Databricks
mlflow.set_tracking_uri("databricks")
mlflow.set_experiment("/Shared/docs-demo")
# Create an OpenAI client connected to OpenAI SDKs
client = openai.OpenAI()
# Select an LLM
model_name = "gpt-4o-mini"
-
Créez l'application de génération d'e-mails :
Pythonfrom 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"])

É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.
# 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.
- UI
- SDK
-
Cliquez sur **Expériences** dans la barre latérale pour afficher la page Expériences.
-
Cliquez sur le nom de votre experimentation pour l'ouvrir.

-
Dans la barre latérale gauche, cliquez sur **Traces**.
-
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.

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

-
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.
-
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 :
- Cliquez sur Créer un nouveau dataset .
- Sélectionnez le schéma Unity Catalog pour contenir le nouveau dataset.
- Saisissez un nom pour le dataset et cliquez sur **Créer un dataset**.
- Cliquez sur Exporter , puis sur Terminé .

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é**.

Créez un dataset d'évaluation de manière programmatique en recherchant des traces et en les ajoutant au dataset.
import mlflow
import mlflow.genai.datasets
import time
from databricks.connect import DatabricksSession
# 0. If you are using a local development environment, connect to Serverless Spark which powers MLflow's evaluation dataset service
spark = DatabricksSession.builder.remote(serverless=True).getOrCreate()
# 1. Create an evaluation dataset
# Replace with a Unity Catalog schema where you have CREATE TABLE permission
uc_schema = "workspace.default"
# This table will be created in the above UC schema
evaluation_dataset_table_name = "email_generation_eval"
eval_dataset = mlflow.genai.datasets.create_dataset(
uc_table_name=f"{uc_schema}.{evaluation_dataset_table_name}",
)
print(f"Created evaluation dataset: {uc_schema}.{evaluation_dataset_table_name}")
# 2. Search for the simulated production traces from step 2: get traces from the last 20 minutes with our trace name.
ten_minutes_ago = int((time.time() - 10 * 60) * 1000)
traces = mlflow.search_traces(
filter_string=f"attributes.timestamp_ms > {ten_minutes_ago} AND "
f"attributes.status = 'OK' AND "
f"tags.`mlflow.traceName` = 'generate_sales_email'",
order_by=["attributes.timestamp_ms DESC"]
)
print(f"Found {len(traces)} successful traces from beta test")
# 3. Add the traces to the evaluation dataset
eval_dataset = eval_dataset.merge_records(traces)
print(f"Added {len(traces)} records to evaluation dataset")
# Preview the dataset
df = eval_dataset.to_df()
print(f"\nDataset preview:")
print(f"Total records: {len(df)}")
print("\nSample record:")
sample = df.iloc[0]
print(f"Inputs: {sample['inputs']}")
É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.
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.
- UI
- SDK
Résumé de l'évaluation
-
Cliquez sur **Expériences** dans la barre latérale pour afficher la page Expériences.
-
Cliquez sur le nom de votre experimentation pour l'ouvrir.
-
Dans la barre latérale gauche, cliquez sur Exécutions d'évaluation . Le volet de droite affiche un tableau de traces.

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.

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

Détails et ajout de commentaires.
Pour voir plus de détails pour chaque trace :
-
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.

-
À 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
. Pour ajouter une nouvelle Évaluation, faites défiler l’écran vers le bas et cliquez sur
.
-
Vous pouvez utiliser les flèches de chaque côté de cette fenêtre pour parcourir les requêtes.

Pour afficher les résultats détaillés par programme :
eval_traces = mlflow.search_traces(run_id=eval_results.run_id)
# eval_traces is a Pandas DataFrame that has the evaluated traces. The column `assessments` includes each judge's feedback.
print(eval_traces)
É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 :
@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.
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é.
- UI
- SDK
-
Cliquez sur **Expériences** dans la barre latérale pour afficher la page Expériences.
-
Cliquez sur le nom de votre experimentation pour l'ouvrir.
-
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.

-
Cochez les cases des exécutions que vous souhaitez comparer.
-
Dans le menu déroulant **Actions**, sélectionnez **Comparer**.

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

-
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.

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 .
Comparez les métriques d'évaluation stockées dans chaque exécution d'évaluation par programmation :
import pandas as pd
# Fetch runs separately since mlflow.search_runs doesn't support IN or OR operators
run_v1_df = mlflow.search_runs(
filter_string=f"run_id = '{eval_results_v1.run_id}'"
)
run_v2_df = mlflow.search_runs(
filter_string=f"run_id = '{eval_results_v2.run_id}'"
)
# Extract metric columns (they end with /mean, not .aggregate_score)
# Skip the agent metrics (latency, token counts) for quality comparison
metric_cols = [col for col in run_v1_df.columns
if col.startswith('metrics.') and col.endswith('/mean')
and 'agent/' not in col]
# Create comparison table
comparison_data = []
for metric in metric_cols:
metric_name = metric.replace('metrics.', '').replace('/mean', '')
v1_score = run_v1_df[metric].iloc[0]
v2_score = run_v2_df[metric].iloc[0]
improvement = v2_score - v1_score
comparison_data.append({
'Metric': metric_name,
'V1 Score': f"{v1_score:.3f}",
'V2 Score': f"{v2_score:.3f}",
'Improvement': f"{improvement:+.3f}",
'Improved': '✓' if improvement >= 0 else '✗'
})
comparison_df = pd.DataFrame(comparison_data)
print("\n=== Version Comparison Results ===")
print(comparison_df.to_string(index=False))
# Calculate overall improvement (only for quality metrics)
avg_v1 = run_v1_df[metric_cols].mean(axis=1).iloc[0]
avg_v2 = run_v2_df[metric_cols].mean(axis=1).iloc[0]
print(f"\nOverall average improvement: {(avg_v2 - avg_v1):+.3f} ({((avg_v2/avg_v1 - 1) * 100):+.1f}%)")
=== Version Comparison Results ===
Metric V1 Score V2 Score Improvement Improved
safety 1.000 1.000 +0.000 ✓
professional_tone 1.000 1.000 +0.000 ✓
follows_instructions 0.571 0.714 +0.143 ✓
includes_next_steps 0.286 0.571 +0.286 ✓
mentions_contact_name 1.000 1.000 +0.000 ✓
retrieval_groundedness 0.857 0.571 -0.286 ✗
concise_communication 0.286 1.000 +0.714 ✓
relevance_to_query 0.714 1.000 +0.286 ✓
Overall average improvement: +0.143 (+20.0%)
Recherchez des exemples spécifiques où les métriques d'évaluation ont régressé afin de pouvoir vous concentrer sur ceux-ci.
import pandas as pd
# Get detailed traces for both versions
traces_v1 = mlflow.search_traces(run_id=eval_results_v1.run_id)
traces_v2 = mlflow.search_traces(run_id=eval_results_v2.run_id)
# Create a merge key based on the input parameters
traces_v1['merge_key'] = traces_v1['request'].apply(
lambda x: f"{x.get('customer_name', '')}|{x.get('user_instructions', '')}"
)
traces_v2['merge_key'] = traces_v2['request'].apply(
lambda x: f"{x.get('customer_name', '')}|{x.get('user_instructions', '')}"
)
# Merge on the input data to compare same inputs
merged = traces_v1.merge(
traces_v2,
on='merge_key',
suffixes=('_v1', '_v2')
)
print(f"Found {len(merged)} matching examples between v1 and v2")
# Find examples where specific metrics did NOT improve
regression_examples = []
for idx, row in merged.iterrows():
v1_assessments = {a['assessment_name']: a for a in row['assessments_v1']}
v2_assessments = {a['assessment_name']: a for a in row['assessments_v2']}
# Check each judge for regressions
for scorer_name in ['follows_instructions', 'concise_communication', 'includes_next_steps', 'retrieval_groundedness']:
v1_assessment = v1_assessments.get(scorer_name)
v2_assessment = v2_assessments.get(scorer_name)
if v1_assessment and v2_assessment:
v1_val = v1_assessment['feedback']['value']
v2_val = v2_assessment['feedback']['value']
# Check if metric got worse (yes -> no)
if v1_val == 'yes' and v2_val == 'no':
regression_examples.append({
'index': idx,
'customer': row['request_v1']['customer_name'],
'instructions': row['request_v1']['user_instructions'],
'metric': scorer_name,
'v1_score': v1_val,
'v2_score': v2_val,
'v1_rationale': v1_assessment['rationale'],
'v2_rationale': v2_assessment['rationale'],
'v1_response': row['response_v1']['email'],
'v2_response': row['response_v2']['email']
})
# Display regression examples
if regression_examples:
print(f"\n=== Found {len(regression_examples)} metric regressions ===\n")
# Group by metric
by_metric = {}
for ex in regression_examples:
metric = ex['metric']
if metric not in by_metric:
by_metric[metric] = []
by_metric[metric].append(ex)
# Show examples for each regressed metric
for metric, examples in by_metric.items():
print(f"\n{'='*80}")
print(f"METRIC REGRESSION: {metric}")
print(f"{'='*80}")
# Show the first example for this metric
ex = examples[0]
print(f"\nCustomer: {ex['customer']}")
print(f"Instructions: {ex['instructions']}")
print(f"\nV1 Score: ✓ (passed)")
print(f"V1 Rationale: {ex['v1_rationale']}")
print(f"\nV2 Score: ✗ (failed)")
print(f"V2 Rationale: {ex['v2_rationale']}")
print(f"\n--- V1 Response ---")
print(ex['v1_response'][:800] + "..." if len(ex['v1_response']) > 800 else ex['v1_response'])
print(f"\n--- V2 Response ---")
print(ex['v2_response'][:800] + "..." if len(ex['v2_response']) > 800 else ex['v2_response'])
if len(examples) > 1:
print(f"\n(+{len(examples)-1} more examples with {metric} regression)")
else:
print("\n✓ No metric regressions found - V2 improved or maintained all metrics!")
Found 7 matching examples between v1 and v2
=== Found 2 metric regressions ===
================================================================================
METRIC REGRESSION: retrieval_groundedness
================================================================================
Customer: TechStart
Instructions: Check on support ticket status
V1 Score: ✓ (passed)
V1 Rationale: The response mentions a follow-up email regarding support ticket status, addressed to Bob, discussing three tickets (#456, #457, and #458) and their current status. The retrieved context confirms the existence of these tickets and their issues: Ticket #456 (login issues - critical), Ticket #457 (performance degradation), and Ticket #458 (CRM integration failure). The retrieved context also mentions that the initial sales call was last Thursday and that Mike Thompson is the account manager. All these details match the information provided in the response.
V2 Score: ✗ (failed)
V2 Rationale: The response mentions three support tickets: Ticket #456 (Login issues), Ticket #457 (Performance degradation), and Ticket #458 (CRM integration failure). The retrieved context confirms the existence of these tickets and their statuses: Ticket #456 is open and critical, Ticket #457 is reported, and Ticket #458 is failing with their CRM. The response also mentions that Mike Thompson will provide a detailed status update by the end of the day tomorrow, which is not directly supported by the retrieved context. Therefore, the part about Mike Thompson providing a detailed status update is not supported by the retrieved context.
--- V1 Response ---
# Follow-up Email: Support Ticket Status Update
Subject: Update on Your Support Tickets - Critical Issues Being Addressed
Dear Bob,
I hope you're doing well following our initial discussion last Thursday about pricing options.
I wanted to personally follow up regarding your open support tickets:
- Ticket #456 (Critical): Our technical team has prioritized your login issues and is working to resolve them urgently
- Ticket #457: The performance degradation investigation is in progress
- Ticket #458: Our integration specialists are addressing the CRM connection failures
Mike Thompson, your Account Manager, is closely monitoring these issues. We understand how critical these matters are to your operations.
Would you be available for a brief call tomorrow to discuss both the support prog...
--- V2 Response ---
# Subject: Update on Your Support Tickets
Hi Bob,
I'm following up on your open support tickets:
- Ticket #456 (Login issues): Currently marked as critical and open
- Ticket #457 (Performance degradation): Under investigation
- Ticket #458 (CRM integration failure): Being reviewed by our technical team
I'll contact our support team today and provide you with a detailed status update by end of day tomorrow.
Please let me know if you need any immediate assistance with these issues.
Best regards,
Mike Thompson
(+1 more examples with retrieval_groundedness regression)
É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
- Créez des datasets d'évaluation - Préparez les données pour des exécutions d'évaluation cohérentes
- Évaluer les conversations — Évaluez les conversations à plusieurs tours avec des évaluateurs spécialisés
- Simulation de conversation : générez des conversations synthétiques pour tester votre agent avec divers scénarios.
- Créer des juges LLM personnalisés — Personnalisez davantage les juges LLM utilisés dans ce guide.
- Aligner les juges avec le feedback humain — Améliorer la précision du juge de 30 à 50 % pour correspondre aux normes de votre équipe
- Créer des évaluateurs de code personnalisés - Évaluez votre application avec des évaluateurs déterministes basés sur le code.
- Configurer le monitoring de la production – Utilisez les mêmes scorers pour surveiller la qualité en production
- Suivez les versions de l'application et des invites - Suivez les versions de l'application et des invites avec MLflow.
- Harnais d'évaluation – Référence complète pour
mlflow.genai.evaluate() - Scorers - Approfondir la manière dont les Scorers évaluent la qualité
- Jeux de données d'évaluation : Découvrez les datasets versionnés pour des tests cohérents