Passer au contenu principal
Les évaluations vous aident à itérer sur vos applications et à les améliorer en les testant sur un ensemble d’exemples après chaque modification. Weave offre une prise en charge native du suivi des évaluations avec les classes Model et Evaluation. Les API sont conçues pour faire le moins d’hypothèses possible, ce qui les rend flexibles pour un large éventail de cas d’usage. Evals hero

Ce que vous allez apprendre :

Ce guide vous montre comment :
  • Configurer un Model
  • Créer un jeu de données pour évaluer les réponses d’un LLM
  • Définir une fonction de scoring pour comparer les résultats du modèle aux résultats attendus
  • Exécuter une évaluation qui teste le modèle sur le jeu de données à l’aide de la fonction de score et d’un scorer intégré supplémentaire
  • Consulter les résultats de l’évaluation dans la Weave UI

Prérequis

  • Un compte W&B
  • Python 3.8+ ou Node.js 18+
  • Packages requis :
    • Python: pip install weave openai
    • TypeScript: npm install weave openai
  • Une clé API OpenAI configurée comme variable d’environnement

Importez les bibliothèques et les fonctions nécessaires

Importez les bibliothèques suivantes dans votre script :
import json
import openai
import asyncio
import weave
from weave.scorers import MultiTaskBinaryClassificationF1

Créer un Model

Dans Weave, les Models sont des objets qui capturent à la fois le comportement de votre modèle/agent (logique, prompt, paramètres) et ses métadonnées versionnées (paramètres, code, micro-config), afin que vous puissiez le suivre, le comparer, l’évaluer et itérer dessus de manière fiable. Lorsque vous instanciez un Model, Weave capture automatiquement sa configuration et ses comportements, puis met à jour sa version en cas de modification. Cela vous permet de suivre ses performances au fil du temps, à mesure que vous l’améliorez. Les Model sont déclarés en créant une sous-classe de Model et en implémentant une fonction predict, qui prend un exemple et renvoie la réponse. L’exemple de modèle suivant utilise OpenAI pour extraire les noms, les couleurs et les saveurs de fruits extraterrestres à partir des phrases qui lui sont envoyées.
class ExtractFruitsModel(weave.Model):
    model_name: str
    prompt_template: str

    @weave.op()
    async def predict(self, sentence: str) -> dict:
        client = openai.AsyncClient()

        response = await client.chat.completions.create(
            model=self.model_name,
            messages=[
                {"role": "user", "content": self.prompt_template.format(sentence=sentence)}
            ],
        )
        result = response.choices[0].message.content
        if result is None:
            raise ValueError("No response from model")
        parsed = json.loads(result)
        return parsed
La classe ExtractFruitsModel hérite de weave.Model (ou en est une sous-classe) afin que Weave puisse suivre l’objet instancié. @weave.op décore la fonction predict pour suivre ses entrées et ses sorties. Vous pouvez instancier des objets Model comme ceci :
# Définissez le nom de votre team et de votre projet
weave.init('<team-name>/eval_pipeline_quickstart')

model = ExtractFruitsModel(
    model_name='gpt-3.5-turbo-1106',
    prompt_template='Extract fields ("fruit": <str>, "color": <str>, "flavor": <str>) from the following text, as json: {sentence}'
)

sentence = "There are many fruits that were found on the recently discovered planet Goocrux. There are neoskizzles that grow there, which are purple and taste like candy."

print(asyncio.run(model.predict(sentence)))
# si vous êtes dans un notebook Jupyter, exécutez :
# await model.predict(sentence)

Créer un jeu de données

Ensuite, vous avez besoin d’un jeu de données sur lequel évaluer votre modèle. Un Dataset est une collection d’exemples stockée comme objet Weave. L’exemple de jeu de données suivant définit trois phrases d’entrée et leurs réponses correctes (labels), puis les met en forme dans un tableau JSON que les fonctions de scoring peuvent lire. Cet exemple construit une liste d’exemples dans le code, mais vous pouvez aussi les journaliser une par une depuis votre application en cours d’exécution.
sentences = ["There are many fruits that were found on the recently discovered planet Goocrux. There are neoskizzles that grow there, which are purple and taste like candy.",
"Pounits are a bright green color and are more savory than sweet.",
"Finally, there are fruits called glowls, which have a very sour and bitter taste which is acidic and caustic, and a pale orange tinge to them."]
labels = [
    {'fruit': 'neoskizzles', 'color': 'purple', 'flavor': 'candy'},
    {'fruit': 'pounits', 'color': 'bright green', 'flavor': 'savory'},
    {'fruit': 'glowls', 'color': 'pale orange', 'flavor': 'sour and bitter'}
]
examples = [
    {'id': '0', 'sentence': sentences[0], 'target': labels[0]},
    {'id': '1', 'sentence': sentences[1], 'target': labels[1]},
    {'id': '2', 'sentence': sentences[2], 'target': labels[2]}
]
Créez ensuite votre jeu de données avec la classe weave.Dataset() et publiez-le :
weave.init('eval_pipeline_quickstart')
dataset = weave.Dataset(name='fruits', rows=examples)
weave.publish(dataset)

Définir des fonctions de scoring personnalisées

Lorsque vous utilisez les évaluations Weave, Weave s’attend à recevoir une target à comparer à output. La fonction de scoring suivante prend deux dictionnaires (target et output) et renvoie un dictionnaire de valeurs booléennes indiquant si la sortie correspond à la cible. Le décorateur @weave.op() permet à Weave de suivre l’exécution de la fonction de scoring.
@weave.op()
def fruit_name_score(target: dict, output: dict) -> dict:
    return {'correct': target['fruit'] == output['fruit']}
Pour créer votre propre fonction de scoring, consultez le guide Scorers. Dans certaines applications, vous souhaiterez peut-être créer des classes Scorer personnalisées. Par exemple, vous pouvez créer une classe LLMJudge standardisée avec des paramètres spécifiques (comme un modèle de chat ou un prompt), une logique de scoring par ligne spécifique et un calcul de score agrégé. Pour en savoir plus, consultez le tutoriel sur la définition d’une classe Scorer dans le chapitre suivant sur l’évaluation des applications RAG basée sur des modèles.

Utiliser un scorer intégré et exécuter l’évaluation

En plus des fonctions de scoring personnalisées, vous pouvez aussi utiliser les évaluateurs intégrés de Weave. Dans l’évaluation suivante, weave.Evaluation() utilise la fonction fruit_name_score définie dans la section précédente ainsi que le scorer intégré MultiTaskBinaryClassificationF1, qui calcule les scores F1. L’exemple suivant exécute une évaluation de ExtractFruitsModel sur le jeu de données fruits à l’aide de ces deux fonctions de scoring et enregistre les résultats dans Weave.
weave.init('eval_pipeline_quickstart')

evaluation = weave.Evaluation(
    name='fruit_eval',
    dataset=dataset, 
    scorers=[
        MultiTaskBinaryClassificationF1(class_names=["fruit", "color", "flavor"]), 
        fruit_name_score
    ],
)
print(asyncio.run(evaluation.evaluate(model)))
# si vous êtes dans un notebook Jupyter, exécutez :
# await evaluation.evaluate(model)
Si vous exécutez ce code depuis un script Python, vous devrez utiliser asyncio.run. En revanche, si vous l’exécutez dans un notebook Jupyter, vous pouvez utiliser directement await.

Exemple complet

import json
import asyncio
import openai
import weave
from weave.scorers import MultiTaskBinaryClassificationF1

# Initialiser Weave une seule fois
weave.init('eval_pipeline_quickstart')

# 1. Définir le modèle
class ExtractFruitsModel(weave.Model):
    model_name: str
    prompt_template: str

    @weave.op()
    async def predict(self, sentence: str) -> dict:
        client = openai.AsyncClient()
        response = await client.chat.completions.create(
            model=self.model_name,
            messages=[{"role": "user", "content": self.prompt_template.format(sentence=sentence)}],
        )
        result = response.choices[0].message.content
        if result is None:
            raise ValueError("No response from model")
        return json.loads(result)

# 2. Instancier le modèle
model = ExtractFruitsModel(
    model_name='gpt-3.5-turbo-1106',
    prompt_template='Extract fields ("fruit": <str>, "color": <str>, "flavor": <str>) from the following text, as json: {sentence}'
)

# 3. Créer le jeu de données
sentences = ["There are many fruits that were found on the recently discovered planet Goocrux. There are neoskizzles that grow there, which are purple and taste like candy.",
"Pounits are a bright green color and are more savory than sweet.",
"Finally, there are fruits called glowls, which have a very sour and bitter taste which is acidic and caustic, and a pale orange tinge to them."]
labels = [
    {'fruit': 'neoskizzles', 'color': 'purple', 'flavor': 'candy'},
    {'fruit': 'pounits', 'color': 'bright green', 'flavor': 'savory'},
    {'fruit': 'glowls', 'color': 'pale orange', 'flavor': 'sour and bitter'}
]
examples = [
    {'id': '0', 'sentence': sentences[0], 'target': labels[0]},
    {'id': '1', 'sentence': sentences[1], 'target': labels[1]},
    {'id': '2', 'sentence': sentences[2], 'target': labels[2]}
]

dataset = weave.Dataset(name='fruits', rows=examples)
weave.publish(dataset)

# 4. Définir la fonction de scoring
@weave.op()
def fruit_name_score(target: dict, output: dict) -> dict:
    return {'correct': target['fruit'] == output['fruit']}

# 5. Lancer l'évaluation
evaluation = weave.Evaluation(
    name='fruit_eval',
    dataset=dataset,
    scorers=[
        MultiTaskBinaryClassificationF1(class_names=["fruit", "color", "flavor"]),
        fruit_name_score
    ],
)
print(asyncio.run(evaluation.evaluate(model)))

Consultez les résultats de votre évaluation

Weave capture automatiquement les traces de chaque prédiction et de chaque score. Cliquez sur le lien affiché par l’évaluation pour consulter les résultats dans la Weave UI. Résultats de l’évaluation

En savoir plus sur les évaluations Weave

Étapes suivantes

Créez une application RAG pour découvrir l’évaluation de la génération augmentée par récupération.