Passer au contenu principal
Dans Weave, les évaluateurs évaluent les résultats d’IA et renvoient des métriques d’évaluation. Ils prennent le résultat de l’IA, l’analysent et renvoient un dictionnaire de résultats. Les évaluateurs peuvent utiliser vos données d’entrée comme référence si nécessaire et peuvent aussi produire des informations supplémentaires, comme des explications ou le raisonnement fourni lors de l’évaluation. Ce guide s’adresse aux développeurs qui souhaitent mesurer la qualité des résultats de leur système d’IA. Il explique comment les évaluateurs s’intègrent aux évaluations Weave, comment créer vos propres évaluateurs, comment appliquer des évaluateurs à des appels individuels et comment analyser les scores obtenus.
Passez des évaluateurs à un objet weave.Evaluation pendant l’évaluation. Weave prend en charge deux types d’évaluateurs :
  1. évaluateurs basés sur des fonctions : fonctions Python décorées avec @weave.op.
  2. évaluateurs basés sur des classes : classes Python qui héritent de weave.Scorer pour des évaluations plus complexes.
Les évaluateurs doivent renvoyer un dictionnaire et peuvent renvoyer plusieurs métriques, des métriques imbriquées et des valeurs non numériques, comme du texte renvoyé par un LLM-évaluateur sur son raisonnement.

Créez vos propres évaluateurs

Les évaluateurs personnalisés vous permettent d’encoder des critères d’évaluation spécifiques à votre cas d’usage, au-delà de ce que couvrent les évaluateurs intégrés. Les sections suivantes décrivent les deux façons de définir un Scorer : comme une fonction, ou comme une classe pour une logique plus complexe.
Évaluateurs prêts à l’emploi Bien que ce guide vous montre comment créer des évaluateurs personnalisés, Weave propose des évaluateurs prédéfinis et évaluateurs SLM locaux que vous pouvez utiliser immédiatement, notamment :

évaluateurs basés sur des fonctions

Il s’agit de fonctions décorées avec @weave.op qui renvoient un dictionnaire. Elles conviennent bien à des évaluations simples comme :
import weave

@weave.op
def evaluate_uppercase(text: str) -> dict:
    return {"text_is_uppercase": text.isupper()}

my_eval = weave.Evaluation(
    dataset=[{"text": "HELLO WORLD"}],
    scorers=[evaluate_uppercase]
)
Lorsque vous exécutez l’évaluation, evaluate_uppercase vérifie si le texte est entièrement en majuscules.

évaluateurs basés sur des classes

Pour des évaluations plus avancées, en particulier lorsque vous devez suivre des métadonnées supplémentaires associées au scorer, essayer différents prompts pour vos évaluateurs LLM ou effectuer plusieurs appels de fonction, utilisez la classe Scorer.Exigences :
  1. Héritez de weave.Scorer.
  2. Définissez une méthode score décorée avec @weave.op.
  3. La méthode score doit renvoyer un dictionnaire.
Exemple :
import weave
from openai import OpenAI
from weave import Scorer

llm_client = OpenAI()

class SummarizationScorer(Scorer):
    model_id: str = "gpt-4o"
    system_prompt: str = "Evaluate whether the summary is good."

    @weave.op
    def some_complicated_preprocessing(self, text: str) -> str:
        processed_text = "Original text: \n" + text + "\n"
        return processed_text

    @weave.op
    def call_llm(self, summary: str, processed_text: str) -> dict:
        res = llm_client.chat.completions.create(
            messages=[
                {"role": "system", "content": self.system_prompt},
                {"role": "user", "content": (
                    f"Analyze how good the summary is compared to the original text."
                    f"Summary: {summary}\n{processed_text}"
                )}])
        return {"summary_quality": res}

    @weave.op
    def score(self, output: str, text: str) -> dict:
        """Évaluez la qualité de la synthèse.

        Arguments:
            output: La synthèse générée par un système d’IA
            text: Le texte original à synthétiser
        """
        processed_text = self.some_complicated_preprocessing(text)
        eval_result = self.call_llm(summary=output, processed_text=processed_text)
        return {"summary_quality": eval_result}

evaluation = weave.Evaluation(
    dataset=[{"text": "The quick brown fox jumps over the lazy dog."}],
    scorers=[summarization_scorer])
Cette classe évalue la qualité d’un résumé en le comparant au texte original.

Fonctionnement des évaluateurs

Cette section explique comment les évaluateurs reçoivent les données de votre évaluation, comment associer les colonnes du jeu de données aux arguments de l’évaluateur, comment faire référence aux variables d’op dans les prompts de scoring, et comment Weave synthétise les scores de chaque ligne en un résultat final.

Arguments nommés des évaluateurs

Les évaluateurs peuvent accéder à la fois à la sortie de votre système d’IA et aux données d’entrée de la ligne du jeu de données.
  • Entrée : Si vous চান que votre évaluateur utilise des données de la ligne de votre jeu de données, comme une colonne label ou target, ajoutez un argument nommé label ou target à la définition de votre évaluateur pour les lui rendre accessibles.
Par exemple, si vous souhaitez utiliser une colonne nommée label de votre jeu de données, votre fonction d’évaluation (ou la méthode de classe score) doit avoir une liste de paramètres comme celle-ci :
@weave.op
def my_custom_scorer(output: str, label: int) -> dict:
    ...
Lorsqu’une Evaluation Weave s’exécute, elle transmet la sortie du système d’IA au paramètre output. Evaluation essaie également automatiquement d’associer les noms des arguments supplémentaires de l’évaluateur aux colonnes de votre jeu de données. Si vous ne pouvez pas personnaliser les arguments de votre évaluateur ou les colonnes de votre jeu de données, vous pouvez utiliser le mappage de colonnes. Voir la section suivante.
  • Sortie : Incluez un paramètre output dans la signature de la fonction de votre évaluateur pour accéder à la sortie du système d’IA.

Mapper les noms de colonnes avec column_map

Il arrive que les noms des arguments de la méthode score ne correspondent pas aux noms des colonnes de votre jeu de données. Vous pouvez corriger cela à l’aide de column_map.Si vous utilisez un évaluateur basé sur une classe, transmettez un dictionnaire à l’attribut column_map de Scorer lors de l’initialisation de votre classe d’évaluateur. Ce dictionnaire associe les noms des arguments de votre méthode score aux noms des colonnes du jeu de données, selon le format {scorer_keyword_argument: dataset_column_name}.Exemple :
import weave
from weave import Scorer

# Un jeu de données d'articles de presse à résumer
dataset = [
    {"news_article": "The news today was great...", "date": "2030-04-20", "source": "Bright Sky Network"},
    ...
]

# Classe d'évaluateur
class SummarizationScorer(Scorer):

    @weave.op
    def score(self, output, text) -> dict:
        """
            output: synthèse générée par un système de synthèse avec LLM
            text: le texte à résumer
        """
        ...  # évaluer la qualité de la synthèse

# créer un évaluateur avec un mappage de colonnes qui associe l'argument `text` à la colonne de données `news_article`
scorer = SummarizationScorer(column_map={"text" : "news_article"})
Désormais, l’argument text de la méthode score reçoit les données de la colonne news_article du jeu de données.Remarques :
  • Une autre option équivalente pour mapper vos colonnes consiste à sous-classer Scorer et à surcharger la méthode score afin d’associer explicitement les colonnes.
import weave
from weave import Scorer

class MySummarizationScorer(SummarizationScorer):

    @weave.op
    def score(self, output: str, news_article: str) -> dict:  # Ajouts d'annotations de type
        # surcharger la méthode score et mapper les colonnes manuellement
        return super().score(output=output, text=news_article)

Accéder aux variables de vos ops dans les prompts de scoring

Dans les prompts de scoring pour les scorers LLM-as-a-judge, vous pouvez faire référence à des variables de votre op. Weave extrait automatiquement ces valeurs lorsque le scorer s’exécute. Pour une fonction comme :
@weave.op
def summarize_article(article: str, max_length: int) -> str:
    # Votre logique de synthèse ici
    return summary
Les variables suivantes sont disponibles :
VariableDescription
{article}La valeur de l’argument d’entrée article
{max_length}La valeur de l’argument d’entrée max_length
{inputs}Un dictionnaire JSON de tous les arguments d’entrée
{output}Le résultat renvoyé par votre op
Exemple de prompt d’évaluation :
Évaluez la qualité de ce résumé.

Article original : {article}
Résumé : {output}
Longueur maximale demandée : {max_length}

Évaluez le résumé sur une échelle de 1 à 10 selon les critères suivants :
- Exactitude : représente-t-il fidèlement l'article ?
- Exhaustivité : couvre-t-il les points clés ?
- Concision : est-il suffisamment bref ?

Renvoyez un objet JSON avec votre note et votre justification.

Résumé final du scorer

Pendant l’évaluation, Weave calcule le scorer pour chaque ligne de votre jeu de données. Pour produire un score final pour l’évaluation, Weave exécute auto_summarize en fonction du type de retour de la sortie.Vous pouvez redéfinir la méthode summarize de la classe Scorer et fournir votre propre manière de calculer les scores finaux. La fonction summarize attend :
  • Un seul paramètre score_rows : une liste de dictionnaires, où chaque dictionnaire contient les scores renvoyés par la méthode score pour une ligne de votre jeu de données.
  • Elle renvoie un dictionnaire contenant les scores récapitulatifs.
Pourquoi est-ce utileLorsque vous devez scorer toutes les lignes avant de pouvoir déterminer la valeur finale du score pour le jeu de données.
class MyBinaryScorer(Scorer):
    """
    Renvoie True si la sortie complète correspond à la cible, False sinon
    """

    @weave.op
    def score(self, output, target):
        return {"match": output == target}

    def summarize(self, score_rows: list) -> dict:
        full_match = all(row["match"] for row in score_rows)
        return {"full_match": full_match}
Dans cet exemple, auto_summarize renverrait par défaut le nombre et la proportion de valeurs True.
Pour plus d’informations, voir l’implémentation de CorrectnessLLMJudge.

Appliquer des évaluateurs à un appel

En plus d’exécuter des évaluateurs dans le cadre d’une weave.Evaluation, vous pouvez les appliquer directement à un appel donné. Cela est utile lorsque vous souhaitez évaluer le trafic de production ou associer des métriques d’évaluation à une invocation d’op spécifique. Pour appliquer des évaluateurs à vos ops Weave, utilisez la méthode .call(), qui vous donne accès à la fois au résultat de l’opération et à ses informations de suivi. Cela vous permet d’associer les résultats des évaluateurs à des appels spécifiques dans la base de données de Weave. Pour plus d’informations sur l’utilisation de la méthode .call(), consultez le guide Calling Ops.
Voici un exemple simple :
# Obtenir à la fois le résultat et l’objet Call
result, call = generate_text.call("Say hello")

# Appliquer un évaluateur
score = await call.apply_scorer(MyScorer())
Vous pouvez également appliquer plusieurs évaluateurs au même appel :
# Appliquer plusieurs évaluateurs en parallèle
await asyncio.gather(
    call.apply_scorer(quality_scorer),
    call.apply_scorer(toxicity_scorer)
)
Notes :
  • Weave stocke automatiquement les résultats des évaluateurs dans sa base de données.
  • Les évaluateurs s’exécutent de manière asynchrone une fois l’opération principale terminée.
  • Vous pouvez consulter les résultats des évaluateurs dans l’interface utilisateur ou les interroger via l’API.
Pour plus d’informations sur l’utilisation des évaluateurs comme garde-fous ou moniteurs, y compris les bonnes pratiques en production et des exemples complets, consultez le guide Guardrails and Monitors.

Utiliser preprocess_model_input

Vous pouvez utiliser le paramètre preprocess_model_input pour modifier les exemples du jeu de données avant qu’ils n’atteignent votre modèle pendant l’évaluation. Pour plus d’informations sur l’utilisation et pour un exemple, voir Utiliser preprocess_model_input pour mettre en forme les lignes du jeu de dataset avant l’évaluation.

Analyse des scores

Après l’exécution de vos évaluateurs, vous souhaiterez souvent examiner les scores qu’ils ont produits afin de comprendre le comportement du modèle ou de comparer des versions. Les sections suivantes décrivent comment analyser les scores pour un seul Appel, plusieurs appels et tous les appels évalués par un scorer spécifique, à l’aide de l’API et de l’interface Weave.

Analyser les scores d’un appel unique

API pour un appel unique

Pour récupérer un appel unique, utilisez la méthode get_call.
client = weave.init("my-project")

# Obtenir un appel unique
call = client.get_call("call-uuid-here")

# Obtenir le feedback de l'appel, qui contient les scores
feedback = list(call.feedback)

UI d’un appel unique

Onglet Scores d’un appel
Le panneau des détails de l’appel affiche les scores d’un appel individuel sous l’onglet Scores.

Analyser les scores de plusieurs appels

API des appels multiples

Pour récupérer plusieurs appels, utilisez la méthode get_calls.
client = weave.init("my-project")

# Obtenir plusieurs appels - utilisez les filtres de votre choix et incluez le feedback
calls = client.get_calls(..., include_feedback=True)

# Itérer sur les appels et accéder au feedback qui contient les scores
for call in calls:
    feedback = list(call.feedback)

Interface des appels multiples

Onglet Appels multiples
Le tableau des traces affiche les scores de plusieurs appels dans la colonne « Scores ».

Analyser tous les appels évalués par un scorer spécifique

API de tous les appels par scorer

Pour récupérer tous les appels notés par un scorer spécifique, utilisez la méthode get_calls.
client = weave.init("my-project")

# Pour obtenir tous les appels évalués par n'importe quelle version d'un scorer, utilisez le nom du scorer (généralement le nom de la classe)
calls = client.get_calls(scored_by=["MyScorer"], include_feedback=True)

# Pour obtenir tous les appels évalués par une version spécifique d'un scorer, utilisez la référence complète
# Les références peuvent être obtenues depuis l'objet scorer ou via l'interface utilisateur.
calls = client.get_calls(scored_by=[myScorer.ref.uri()], include_feedback=True)

# Parcourir les appels et accéder aux feedback contenant les scores
for call in calls:
    feedback = list(call.feedback)

Tous les appels d’un Scorer dans l’UI

Enfin, si vous souhaitez voir tous les appels évalués par un Scorer, accédez à l’onglet évaluateurs dans l’UI et sélectionnez l’onglet Programmatic Scorer. Cliquez sur votre Scorer pour ouvrir la page de détails du Scorer.
Page de détails du Scorer
Ensuite, cliquez sur le bouton View Traces sous Scores pour voir tous les appels évalués par votre Scorer.
Appels filtrés sur la version du Scorer
Par défaut, cela affiche la version sélectionnée du Scorer. Vous pouvez supprimer le filtre de version pour voir tous les appels évalués par n’importe quelle version du Scorer.
Appels filtrés sur le nom du Scorer