Passer au contenu principal
Il s’agit d’un notebook interactif. Vous pouvez l’exécuter localement ou utiliser les liens ci-dessous :

Intégration avec Weave : tableau de bord de production

L’écosystème des outils GenAI évolue rapidement : de nouveaux frameworks, outils et applications émergent en permanence. Weave vise à être une solution tout-en-un pour tous vos besoins en matière de monitoring et d’évaluation GenAI. Cela signifie aussi qu’il est parfois nécessaire d’intégrer des plateformes existantes ou d’étendre Weave pour répondre aux besoins spécifiques de votre projet ou de votre organisation. Dans ce cookbook, nous allons montrer comment exploiter les API et fonctions avancées de Weave pour créer un tableau de bord personnalisé de monitoring en production, en extension de la vue Traces dans Weave. Nous nous concentrerons sur :
  • La récupération des traces, coûts, retours utilisateurs et autres métriques depuis Weave
  • La création de vues agrégées pour les retours utilisateurs et la répartition des coûts
  • La création de visualisations de l’utilisation des tokens et de la latence au fil du temps
Vous pouvez essayer le tableau de bord avec votre propre projet Weave en installant streamlit et en exécutant ce script de tableau de bord de production ! Exemple de tableau de bord de production avec Weave

1. Configuration

Pour suivre ce tutoriel, il vous suffit d’installer les packages suivants :
!pip install streamlit pandas plotly weave

2. Implémentation

2.1 Initialisation du client Weave et définition des coûts

Commencez par configurer une fonction pour initialiser le client Weave et ajouter les coûts pour chaque modèle.
  • Nous avons inclus les coûts standard pour de nombreux modèles, mais vous pouvez aussi facilement ajouter vos propres coûts et modèles personnalisés. La suite montre comment ajouter des coûts personnalisés pour quelques modèles et utiliser les coûts standard pour les autres.
  • Les coûts sont calculés en fonction des tokens suivis pour chaque appel dans Weave. Pour de nombreuses bibliothèques de fournisseurs de LLM, nous suivons automatiquement l’utilisation des tokens, mais vous pouvez aussi renvoyer un nombre de tokens personnalisé pour n’importe quel appel. Voir ce cookbook pour savoir comment définir le nombre de tokens et le calcul du coût d’un modèle personnalisé : cookbook sur les coûts personnalisés.
PROJECT_NAME = "wandb-smle/weave-cookboook-demo"
python
import weave

MODEL_NAMES = [
    # nom du modèle, coût du prompt, coût de complétion
    ("gpt-4o-2024-05-13", 0.03, 0.06),
    ("gpt-4o-mini-2024-07-18", 0.03, 0.06),
    ("gemini/gemini-1.5-flash", 0.00025, 0.0005),
    ("gpt-4o-mini", 0.03, 0.06),
    ("gpt-4-turbo", 0.03, 0.06),
    ("claude-3-haiku-20240307", 0.01, 0.03),
    ("gpt-4o", 0.03, 0.06),
]

def init_weave_client(project_name):
    try:
        client = weave.init(project_name)
        for model, prompt_cost, completion_cost in MODEL_NAMES:
            client.add_cost(
                llm_id=model,
                prompt_token_cost=prompt_cost,
                completion_token_cost=completion_cost,
            )
    except Exception as e:
        print(f"Échec de l'initialisation du client Weave pour le projet '{project_name}' : {e}")
        return None
    else:
        return client

client = init_weave_client(PROJECT_NAME)

2.2 Récupération des données d’appels de Weave

Pour récupérer les données d’appels de Weave, nous avons deux possibilités :
  1. Récupérer les données appel par appel
  2. Utiliser des API de haut niveau

2.2.1 Récupération des données appel par appel

La première option pour accéder aux données de Weave consiste à récupérer une liste d’appels filtrés et à extraire les données souhaitées appel par appel. Pour cela, nous pouvons utiliser l’API calls_query_stream pour récupérer les données des appels depuis Weave :
  • API calls_query_stream : cette API permet de récupérer les données des appels depuis Weave.
  • Dictionnaire filter : ce dictionnaire contient les paramètres de filtre pour récupérer les données des appels - voir ici pour plus de détails.
  • Liste expand_columns : cette liste contient les colonnes à développer dans les données des appels.
  • Liste sort_by : cette liste contient les paramètres de tri des données des appels.
  • Booléen include_costs : ce booléen indique s’il faut inclure les coûts dans les données des appels.
  • Booléen include_feedback : ce booléen indique s’il faut inclure les retours dans les données des appels.
import itertools
from datetime import datetime, timedelta

import pandas as pd

def fetch_calls(client, project_id, start_time, trace_roots_only, limit):
    filter_params = {
        "project_id": project_id,
        "filter": {"started_at": start_time, "trace_roots_only": trace_roots_only},
        "expand_columns": ["inputs.example", "inputs.model"],
        "sort_by": [{"field": "started_at", "direction": "desc"}],
        "include_costs": True,
        "include_feedback": True,
    }
    try:
        calls_stream = client.server.calls_query_stream(filter_params)
        calls = list(
            itertools.islice(calls_stream, limit)
        )  # limiter le nombre d'appels à récupérer si trop nombreux
        print(f"{len(calls)} appels récupérés.")
    except Exception as e:
        print(f"Erreur lors de la récupération des appels : {e}")
        return []
    else:
        return calls

calls = fetch_calls(client, PROJECT_NAME, datetime.now() - timedelta(days=1), True, 100)
python
# les données brutes sont une liste d'objets Call
pd.DataFrame([call.dict() for call in calls]).head(3)
Traiter les appels est très simple à partir du résultat renvoyé par Weave : nous allons extraire les informations pertinentes et les stocker dans une liste de dictionnaires. Nous convertirons ensuite cette liste de dictionnaires en dataframe pandas et la renverrons.
import json
from datetime import datetime

import pandas as pd

def process_calls(calls):
    records = []
    for call in calls:
        feedback = call.summary.get("weave", {}).get("feedback", [])
        thumbs_up = sum(
            1
            for item in feedback
            if isinstance(item, dict) and item.get("payload", {}).get("emoji") == "👍"
        )
        thumbs_down = sum(
            1
            for item in feedback
            if isinstance(item, dict) and item.get("payload", {}).get("emoji") == "👎"
        )
        latency = call.summary.get("weave", {}).get("latency_ms", 0)

        records.append(
            {
                "Call ID": call.id,
                "Trace ID": call.trace_id,  # il s'agit d'un ID unique pour la trace, utilisable pour la récupérer
                "Display Name": call.display_name,  # il s'agit d'un nom facultatif que vous pouvez définir dans l'UI ou par programmation
                "Latency (ms)": latency,
                "Thumbs Up": thumbs_up,
                "Thumbs Down": thumbs_down,
                "Started At": pd.to_datetime(getattr(call, "started_at", datetime.min)),
                "Inputs": json.dumps(call.inputs, default=str),
                "Outputs": json.dumps(call.output, default=str),
            }
        )
    return pd.DataFrame(records)
python
df_calls = process_calls(calls)
df_calls.head(3)

2.2.2 Utilisation d’API de haut niveau

Au lieu de passer en revue chaque appel, Weave fournit aussi des API de haut niveau pour accéder directement aux coûts des modèles, aux retours et à d’autres métriques. Par exemple, pour le coût, nous utiliserons l’API query_costs pour récupérer les coûts de tous les LLM utilisés dans le projet :
# Utiliser l'API de coût pour obtenir les coûts
costs = client.query_costs()
df_costs = pd.DataFrame([cost.dict() for cost in costs])
df_costs["total_cost"] = (
    df_costs["prompt_token_cost"] + df_costs["completion_token_cost"]
)

# afficher uniquement la première ligne pour chaque llm_id unique
df_costs

2.4 Collecte des données d’entrée et génération des visualisations

Ensuite, nous pouvons générer les visualisations avec plotly. Il s’agit du tableau de bord le plus simple, mais vous pouvez le personnaliser comme vous le souhaitez ! Pour un exemple plus complexe, consultez cet exemple Streamlit ici.
import plotly.express as px
import plotly.graph_objects as go

def plot_feedback_pie_chart(thumbs_up, thumbs_down):
    fig = go.Figure(
        data=[
            go.Pie(
                labels=["Thumbs Up", "Thumbs Down"],
                values=[thumbs_up, thumbs_down],
                marker={"colors": ["#66b3ff", "#ff9999"]},
                hole=0.3,
            )
        ]
    )
    fig.update_traces(textinfo="percent+label", hoverinfo="label+percent")
    fig.update_layout(showlegend=False, title="Feedback Summary")
    return fig

def plot_model_cost_distribution(df):
    fig = px.bar(
        df,
        x="llm_id",
        y="total_cost",
        color="llm_id",
        title="Cost Distribution by Model",
    )
    fig.update_layout(xaxis_title="Model", yaxis_title="Cost (USD)")
    return fig

# Voir le code source pour tous les graphiques
python
plot_feedback_pie_chart(df_calls["Thumbs Up"].sum(), df_calls["Thumbs Down"].sum())
python
plot_model_cost_distribution(df_costs)

Conclusion

Dans ce cookbook, nous avons montré comment créer un tableau de bord personnalisé de monitoring en production à l’aide des API et des fonctions de Weave. À l’heure actuelle, Weave privilégie des intégrations rapides pour faciliter à la fois l’ingestion des données et leur extraction à des fins de traitement personnalisé.
  • Entrée des données :
    • Tracing indépendant du framework avec le décorateur @weave-op(), avec la possibilité d’importer des appels depuis un fichier CSV (voir le guide d’import associé)
    • Des API endpoint de service pour envoyer des journaux vers Weave depuis différents frameworks et langages de programmation ; voir ici pour plus de détails.
  • Sortie des données :
    • Téléchargement simple des données aux formats CSV, TSV, JSONL et JSON - voir ici pour plus de détails.
    • Export simple via un accès programmatique aux données - voir la section “Use Python” dans le panneau d’export, comme décrit dans ce cookbook. Voir ici pour plus de détails.
Ce tableau de bord personnalisé étend la vue Traces native de Weave, pour permettre un monitoring sur mesure des applications LLM en production. Si vous souhaitez consulter un tableau de bord plus complexe, découvrez un exemple Streamlit dans lequel vous pouvez ajouter l’URL de votre projet Weave dans ce dépôt.