Aligner les juges LLM avec les retours humains
L'alignement des juges apprend aux juges LLM à correspondre aux standards d'évaluation humaine grâce à un feedback systématique. Ce processus transforme les évaluateurs génériques en experts du domaine qui comprennent vos critères de qualité uniques, améliorant l'accord avec les évaluations humaines de 30 à 50 % par rapport aux juges de référence.
Le même workflow d’alignement s’applique aux juges intégrés (tels que RelevanceToQuery, Safety ou Correctness) et aux juges personnalisés créés avec make_judge(). Utilisez l'alignement avec des juges intégrés pour adapter leurs critères génériques à votre domaine, ou avec des juges personnalisés pour affiner la logique d'évaluation spécialisée.
L'alignement du juge suit un workflow en trois étapes :
- Générez les évaluations initiales : Utilisez un juge intégré ou personnalisé pour évaluer les traces et établir une référence.
- Recueillir les commentaires humains : Les experts du domaine examinent et corrigent les évaluations des juges.
- Aligner et déployer : Invoquez la méthode
align()du juge pour créer un nouveau juge qui est davantage aligné avec le feedback humain.
Le système prend en charge les optimiseurs qui sont disponibles dans le package mlflow.genai.judges.optimizers.
Exigences
-
MLflow 3.4.0 ou supérieur pour utiliser les fonctionnalités d'alignement des juges
Python%pip install --upgrade "mlflow[databricks]>=3.4.0" databricks_openai dspy
dbutils.library.restartPython() -
Un juge à aligner. Il peut s'agir d'un juge intégré (par exemple,
RelevanceToQueryouCorrectness) ou d'un juge personnalisé créé avecmake_judge(). -
Le nom de l'évaluation du feedback humain doit correspondre exactement à l'attribut
namedu juge. Pour les juges intégrés, il s'agit du nom par default en snake_case (par exemple,relevance_to_querypourRelevanceToQuery), sauf si vous le remplacez en passantname=lors de l'instanciation de la classe. Pour les juges personnalisés, c'est lenameque vous avez transmis àmake_judge()(par exemple,product_quality). -
L'alignement n'est pas pris en charge pour les juges au niveau de la session (multi-tour) tels que
ConversationCompleteness.
Étape 1 : Configurez le juge et générez des traces.
Configurez votre premier juge et générez des traces avec des évaluations. Vous pouvez obtenir un alignement raisonnable avec au moins 10 traces, mais 50 à 100 traces donnent de meilleurs résultats.
- Built-in judge
- Custom judge
Instancier un juge intégré directement. Les juges intégrés exposent un attribut name (la valeur default est une chaîne de caractères snake_case telle que relevance_to_query) que vous utiliserez lors de l’enregistrement des retours humains à l’étape 2.
from mlflow.genai.scorers import RelevanceToQuery
import mlflow
# Create or set an MLflow experiment for alignment.
# Use a workspace path such as /Shared/<name> or /Users/<your-email>/<name>.
experiment = mlflow.set_experiment("/Shared/relevance-alignment")
experiment_id = experiment.experiment_id
# Use a built-in judge
initial_judge = RelevanceToQuery()
Créez un juge personnalisé avec make_judge(). L’argument name est le même nom que vous utiliserez lors de l’enregistrement des commentaires humains à l’étape 2.
from mlflow.genai.judges import make_judge
import mlflow
# Create or set an MLflow experiment for alignment.
# Use a workspace path such as /Shared/<name> or /Users/<your-email>/<name>.
experiment = mlflow.set_experiment("/Shared/product-quality-alignment")
experiment_id = experiment.experiment_id
# Create initial judge with template-based evaluation
initial_judge = make_judge(
name="product_quality",
instructions=(
"Evaluate if the product description in {{ outputs }} "
"is accurate and helpful for the query in {{ inputs }}. "
"Rate as: excellent, good, fair, or poor"
),
model="databricks:/databricks-gpt-oss-120b",
)
Définissez votre logique d'application. L'exemple suivant utilise un modèle de fondation hébergé par Databricks pour générer une description de produit à partir d'une query. Remplacez ceci par votre propre code d'application :
import mlflow
from databricks_openai import DatabricksOpenAI
# Enable automatic tracing of OpenAI calls
mlflow.openai.autolog()
# Create an OpenAI client connected to Databricks-hosted LLMs
client = DatabricksOpenAI()
model_name = "databricks-claude-sonnet-4"
def generate_product_description(query: str) -> str:
response = client.chat.completions.create(
model=model_name,
messages=[
{
"role": "system",
"content": "You write concise, accurate product descriptions.",
},
{"role": "user", "content": query},
],
)
return response.choices[0].message.content
Générez des traces et exécutez le juge. Utilisez l'attribut name du juge (par exemple, relevance_to_query pour le juge intégré ci-dessus, ou product_quality pour le juge personnalisé ci-dessus) comme feedback name:
# Generate traces for alignment (minimum 10, recommended 50+)
for i in range(50):
query = f"Tell me about product {i}"
description = generate_product_description(query)
# Retrieve the ID of the most recent finished trace
trace_id = mlflow.get_last_active_trace_id()
trace = mlflow.get_trace(trace_id)
# Generate judge assessment
judge_result = initial_judge(trace=trace)
# Log judge feedback to the trace using the judge's name
mlflow.log_feedback(
trace_id=trace_id,
name=initial_judge.name,
value=judge_result.value,
rationale=judge_result.rationale,
)
Étape 2 : Recueillir les commentaires des utilisateurs
Recueillez les retours humains pour enseigner au juge vos standards de qualité. Choisissez parmi les approches suivantes :
- Databricks UI review
- Programmatic feedback
Recueillez le feedback humain lorsque :
- Vous avez besoin d'experts du domaine pour examiner les sorties.
- Vous souhaitez affiner de manière itérative les critères de feedback.
- Vous travaillez avec un plus petit dataset (< 100 exemples).
Utilisez l'interface utilisateur MLflow pour examiner manuellement et fournir des commentaires :
- Accédez à votre experimentation MLflow dans le Workspace Databricks.
- Cliquez sur l'onglet **Traces** pour afficher les traces.
- Examinez chaque trace et son évaluation par le juge.
- Ajoutez un feedback humain à l'aide de l'interface de feedback de l'interface utilisateur.
- Assurez-vous que le nom de la rétroaction correspond exactement à l'attribut
namede votre juge (par exemple,relevance_to_querypour une instanceRelevanceToQueryintégrée ouproduct_qualitypour le juge personnalisé ci-dessus).
Utilisez les retours programmatiques lorsque :
- Vous avez des étiquettes de vérité de terrain préexistantes.
- Vous travaillez avec de grands datasets (100+ exemples).
- Vous avez besoin d'une collecte de feedback reproductible.
Si vous avez des étiquettes de vérité terrain existantes, enregistrez-les par programme :
from mlflow.entities import AssessmentSource, AssessmentSourceType
# Your ground truth data
ground_truth_data = [
{"trace_id": "<trace_id_1>", "label": "excellent", "rationale": "Comprehensive and accurate description"},
{"trace_id": "<trace_id_2>", "label": "poor", "rationale": "Missing key product features"},
{"trace_id": "<trace_id_3>", "label": "good", "rationale": "Accurate but could be more detailed"},
# ... more ground truth labels
]
# Log human feedback for each trace
for item in ground_truth_data:
mlflow.log_feedback(
trace_id=item["trace_id"],
name=initial_judge.name, # Must match judge name (built-in or custom)
value=item["label"],
rationale=item.get("rationale", ""),
source=AssessmentSource(
source_type=AssessmentSourceType.HUMAN,
source_id="ground_truth_dataset"
),
)
Bonnes pratiques pour la collecte de commentaires
- Relecteurs variés : Incluez de multiples experts du domaine afin de saisir diverses perspectives.
- Exemples équilibrés : incluez au moins 30 % d'exemples négatifs (évaluations médiocres/passables)
- Justifications claires : Fournissez des explications détaillées pour les évaluations
- Échantillons représentatifs : Couvrez les cas limites et les scénarios courants
Étape 3 : Alignez et enregistrez le juge
Une fois que vous disposez d'un feedback humain suffisant, alignez le juge. La même méthode align() est utilisée pour les juges intégrés et personnalisés.
- Default optimizer (recommended)
- Explicit optimizer
Lorsque vous appelez align() sans spécifier d'optimiseur, l'optimiseur MemAlign est utilisé automatiquement :
# Retrieve traces with both judge and human assessments
traces_for_alignment = mlflow.search_traces(
experiment_ids=[experiment_id],
max_results=100,
return_type="list"
)
if len(traces_for_alignment) >= 10:
# Align the judge based on human feedback using the default optimizer
aligned_judge = initial_judge.align(traces_for_alignment)
# Register the aligned judge for production use.
# Use a new name to distinguish it from the original judge.
aligned_judge.register(
experiment_id=experiment_id,
name=f"{initial_judge.name}_aligned",
tags={"alignment_date": "2025-10-23", "num_traces": str(len(traces_for_alignment))}
)
print(f"Successfully aligned judge using {len(traces_for_alignment)} traces")
else:
print(f"Insufficient traces for alignment. Found {len(traces_for_alignment)}, need at least 10")
from mlflow.genai.judges.optimizers import MemAlignOptimizer
# Retrieve traces with both judge and human assessments
traces_for_alignment = mlflow.search_traces(
experiment_ids=[experiment_id], max_results=15, return_type="list"
)
# Align the judge using human corrections (minimum 10 traces recommended)
if len(traces_for_alignment) >= 10:
# Explicitly specify optimizer with custom model configuration
optimizer = MemAlignOptimizer(model="databricks:/databricks-gpt-oss-120b")
aligned_judge = initial_judge.align(traces_for_alignment, optimizer)
# Register the aligned judge
aligned_judge.register(experiment_id=experiment_id)
print("Judge aligned successfully with human feedback")
else:
print(f"Need at least 10 traces for alignment, have {len(traces_for_alignment)}")
Activer la journalisation détaillée
Pour surveiller le processus d'alignement, activez la journalisation de débogage pour l'optimiseur :
import logging
# Enable detailed logging
logging.getLogger("mlflow.genai.judges.optimizers.memalign").setLevel(logging.DEBUG)
# Run alignment with verbose output
aligned_judge = initial_judge.align(traces_for_alignment)
Valider l'alignement
Vérifiez que l'alignement a amélioré le juge :
def test_alignment_improvement(
original_judge, aligned_judge, test_traces: list
) -> dict:
"""Compare judge performance before and after alignment."""
original_correct = 0
aligned_correct = 0
for trace in test_traces:
# Get human ground truth from trace assessments
feedbacks = trace.search_assessments(type="feedback")
human_feedback = next(
(f for f in feedbacks if f.source.source_type == "HUMAN"), None
)
if not human_feedback:
continue
# Get judge evaluations
# Judges can evaluate entire traces instead of individual inputs/outputs
original_eval = original_judge(trace=trace)
aligned_eval = aligned_judge(trace=trace)
# Check agreement with human
if original_eval.value == human_feedback.value:
original_correct += 1
if aligned_eval.value == human_feedback.value:
aligned_correct += 1
total = len(test_traces)
return {
"original_accuracy": original_correct / total,
"aligned_accuracy": aligned_correct / total,
"improvement": (aligned_correct - original_correct) / total,
}
Créer des optimiseurs d’alignement personnalisés
Pour les stratégies d'alignement spécialisées, étendez la classe de base AlignmentOptimizer :
from mlflow.genai.judges.base import AlignmentOptimizer, Judge
from mlflow.entities.trace import Trace
class MyCustomOptimizer(AlignmentOptimizer):
"""Custom optimizer implementation for judge alignment."""
def __init__(self, model: str = None, **kwargs):
"""Initialize your optimizer with custom parameters."""
self.model = model
# Add any custom initialization logic
def align(self, judge: Judge, traces: list[Trace]) -> Judge:
"""
Implement your alignment algorithm.
Args:
judge: The judge to be optimized
traces: List of traces containing human feedback
Returns:
A new Judge instance with improved alignment
"""
# Your custom alignment logic here
# 1. Extract feedback from traces
# 2. Analyze disagreements between judge and human
# 3. Generate improved instructions
# 4. Return new judge with better alignment
# Example: Return judge with modified instructions
from mlflow.genai.judges import make_judge
improved_instructions = self._optimize_instructions(judge.instructions, traces)
return make_judge(
name=judge.name,
instructions=improved_instructions,
model=judge.model,
)
def _optimize_instructions(self, instructions: str, traces: list[Trace]) -> str:
"""Your custom optimization logic."""
# Implement your optimization strategy
pass
# Create your custom optimizer
custom_optimizer = MyCustomOptimizer(model="your-model")
# Use it for alignment
aligned_judge = initial_judge.align(traces_with_feedback, custom_optimizer)
Limitations
- L'alignement des juges ne prend pas en charge l'évaluation basée sur l'agent ou les attentes.
Étapes suivantes
- Apprenez-en davantage sur le monitoring de la production pour déployer des juges alignés à grande échelle.
- Consultez les évaluateurs basés sur le code pour des métriques déterministes complémentaires.
- En savoir plus sur la création de juges personnalisés dans ce blog Databricks.