> ## Documentation Index
> Fetch the complete documentation index at: https://wb-21fd5541-docs-1917.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Optimisation des prompts DSPy

> Apprenez à utiliser l’optimisation des prompts DSPy avec W&B Weave

<Note>
  Il s’agit d’un notebook interactif. Vous pouvez l’exécuter localement ou utiliser les liens ci-dessous :

  * [Open in Google Colab](https://colab.research.google.com/github/wandb/docs/blob/main/weave/cookbooks/source/dspy_prompt_optimization.ipynb)
  * [Voir la source sur GitHub](https://github.com/wandb/docs/blob/main/weave/cookbooks/source/dspy_prompt_optimization.ipynb)
</Note>

<div id="optimizing-llm-workflows-using-dspy-and-weave">
  # Optimiser les flux de travail LLM à l’aide de DSPy et Weave
</div>

Le [BIG-bench (Beyond the Imitation Game Benchmark)](https://github.com/google/BIG-bench) est un benchmark collaboratif conçu pour tester les grands modèles de langage et extrapoler leurs capacités futures. Il comprend plus de 200 tâches. Le [BIG-Bench Hard (BBH)](https://github.com/suzgunmirac/BIG-Bench-Hard) est une suite de 23 tâches BIG-Bench parmi les plus difficiles, qui peuvent s’avérer assez complexes à résoudre avec la génération actuelle de modèles de langage.

Ce tutoriel montre comment améliorer les performances de notre flux de travail LLM appliqué à la **tâche de jugement causal** du benchmark BIG-Bench Hard et évaluer nos stratégies de prompting. Nous utiliserons [DSPy](https://dspy.ai) pour implémenter notre flux de travail LLM et optimiser notre stratégie de prompting. Nous utiliserons également [Weave](/fr/weave) pour suivre notre flux de travail LLM et évaluer nos stratégies de prompting.

<div id="installing-the-dependencies">
  ## Installation des dépendances
</div>

Ce tutoriel nécessite les bibliothèques suivantes :

* [DSPy](https://dspy.ai) pour construire le flux de travail LLM et l’optimiser.
* [Weave](/fr/weave) pour suivre notre flux de travail LLM et évaluer nos stratégies de prompting.
* [datasets](https://huggingface.co/docs/datasets/index) pour accéder au jeu de données Big-Bench Hard depuis le Hub Hugging Face.

```python lines theme={null}
!pip install -qU dspy weave "datasets<4"
```

Puisque nous allons utiliser l’[API OpenAI](https://openai.com/index/openai-api/) comme fournisseur de LLM, nous aurons également besoin d’une clé API OpenAI. Vous pouvez [vous inscrire](https://platform.openai.com/signup) sur la plateforme OpenAI pour obtenir votre propre clé API.

```python lines theme={null}
import os
from getpass import getpass

api_key = getpass("Enter you OpenAI API key: ")
os.environ["OPENAI_API_KEY"] = api_key
```

<div id="enable-tracking-using-weave">
  ## Activer le suivi avec Weave
</div>

Weave est actuellement intégré à DSPy, et le fait d’inclure [`weave.init`](/fr/weave/reference/python-sdk/trace/weave_client#method-init) au début de votre code vous permet de tracer automatiquement vos fonctions DSPy et de les explorer dans la Weave UI. Consultez la [documentation de l’intégration Weave pour DSPy](/fr/weave/guides/integrations/dspy) pour en savoir plus.

```python lines theme={null}
import weave

weave.init(project_name="dspy-bigbench-hard")
```

Dans ce tutoriel, nous utilisons une classe de métadonnées qui hérite de [`weave.Object`](/fr/weave/reference/python-sdk#class-object) pour gérer nos métadonnées.

```python lines theme={null}
class Metadata(weave.Object):
    dataset_address: str = "maveriq/bigbenchhard"
    big_bench_hard_task: str = "causal_judgement"
    num_train_examples: int = 50
    openai_model: str = "gpt-4o-mini"
    openai_max_tokens: int = 2048
    max_bootstrapped_demos: int = 8
    max_labeled_demos: int = 8

metadata = Metadata()
```

<Tip>
  **Gestion des versions des objets** : les objets `Metadata` font automatiquement l’objet d’une gestion des versions et sont tracés lorsque les fonctions qui les utilisent sont elles-mêmes tracées
</Tip>

<div id="load-the-big-bench-hard-dataset">
  ## Charger le jeu de données BIG-Bench Hard
</div>

Nous allons charger ce jeu de données à partir de Hugging Face Hub, le répartir en ensembles d'entraînement et de validation, puis les [publier](/fr/weave/guides/core-types/datasets) sur Weave. Cela nous permettra de versionner les jeux de données et d'utiliser [`weave.Evaluation`](/fr/weave/guides/core-types/evaluations) pour évaluer notre stratégie de prompting.

```python lines theme={null}
import dspy
from datasets import load_dataset

@weave.op()
def get_dataset(metadata: Metadata):
    # charger le jeu de données BIG-Bench Hard correspondant à la tâche depuis Huggingface Hub
    dataset = load_dataset(metadata.dataset_address, metadata.big_bench_hard_task)[
        "train"
    ]

    # créer les jeux de données d'entraînement et de validation
    rows = [{"question": data["input"], "answer": data["target"]} for data in dataset]
    train_rows = rows[0 : metadata.num_train_examples]
    val_rows = rows[metadata.num_train_examples :]

    # créer les exemples d'entraînement et de validation composés d'objets `dspy.Example`
    dspy_train_examples = [
        dspy.Example(row).with_inputs("question") for row in train_rows
    ]
    dspy_val_examples = [dspy.Example(row).with_inputs("question") for row in val_rows]

    # publier les jeux de données sur Weave, ce qui nous permettra de versionner les données et de les utiliser pour l'évaluation
    weave.publish(
        weave.Dataset(
            name=f"bigbenchhard_{metadata.big_bench_hard_task}_train", rows=train_rows
        )
    )
    weave.publish(
        weave.Dataset(
            name=f"bigbenchhard_{metadata.big_bench_hard_task}_val", rows=val_rows
        )
    )

    return dspy_train_examples, dspy_val_examples

dspy_train_examples, dspy_val_examples = get_dataset(metadata)
```

<Frame>
  <img src="https://mintcdn.com/wb-21fd5541-docs-1917/PReu-nQCaYehtM7U/media/dspy_optimization/1.png?fit=max&auto=format&n=PReu-nQCaYehtM7U&q=85&s=8eb91eebaec67cbec428bf4aeb5dbcdc" alt="Interface de chargement d’un jeu de données DSPy avec les étapes de préparation et la structure des données" width="3024" height="1188" data-path="media/dspy_optimization/1.png" />
</Frame>

<div id="the-dspy-program">
  ## Le programme DSPy
</div>

[DSPy](https://dspy.ai) est un framework qui déplace la création de nouveaux pipelines de LM de la manipulation de chaînes de texte libres vers la programmation (en composant des opérateurs modulaires pour construire des graphes de transformation de texte), où un compilateur génère automatiquement, à partir d’un programme, des stratégies d’invocation de LM et des prompts optimisés.

Nous utiliserons [`dspy.LM`](https://dspy.ai/learn/programming/language_models) pour configurer notre modèle de langage et [`dspy.configure`](https://dspy.ai/api/utils/configure/) pour le définir comme valeur par défaut.

```python lines theme={null}
llm = dspy.LM("openai/gpt-4o-mini")
dspy.configure(lm=llm)
```

<div id="writing-the-causal-reasoning-signature">
  ### Écrire la signature du raisonnement causal
</div>

Une [signature](https://dspy.ai/learn/programming/signatures) est une spécification déclarative du comportement en entrée/sortie d’un [module DSPy](https://dspy.ai/learn/programming/modules). Les modules DSPy sont des composants adaptatifs à la tâche — comparables à des couches de réseau de neurones — qui font abstraction de toute transformation de texte particulière.

```python lines theme={null}
class CausalReasoning(dspy.Signature):
    """You are an expert in causal reasoning. Analyze the given question carefully
    and answer Yes or No. Provide a detailed explanation justifying your answer."""

    question: str = dspy.InputField(desc="The question to be answered")
    answer: str = dspy.OutputField(desc="Yes or No")
    confidence: float = dspy.OutputField(desc="Confidence score between 0 and 1")
    explanation: str = dspy.OutputField(desc="Detailed explanation for the answer")

class CausalReasoningModule(dspy.Module):
    def __init__(self):
        self.prog = dspy.Predict(CausalReasoning)

    @weave.op()
    def forward(self, question: str) -> dict:
        result = self.prog(question=question)
        return {
            "answer": result.answer,
            "confidence": result.confidence,
            "explanation": result.explanation,
        }
```

Testons notre flux de travail LLM, c'est-à-dire le `CausalReasoningModule`, sur un exemple tiré du sous-ensemble de raisonnement causal de Big-Bench Hard.

```python lines theme={null}
import rich

baseline_module = CausalReasoningModule()

prediction = baseline_module(dspy_train_examples[0]["question"])
rich.print(prediction)
```

<Frame>
  <img src="https://mintcdn.com/wb-21fd5541-docs-1917/PReu-nQCaYehtM7U/media/dspy_optimization/2.png?fit=max&auto=format&n=PReu-nQCaYehtM7U&q=85&s=1b076c6d40975b1f909f331bbd3a658a" alt="Résultats de l’évaluation du programme DSPy de référence avec des métriques de performances et des exemples de sortie" width="3018" height="1894" data-path="media/dspy_optimization/2.png" />

  ## Évaluation de notre programme DSPy
</Frame>

Maintenant que nous disposons d’une stratégie de prompting de référence, évaluons-la sur notre ensemble de validation à l’aide de [`weave.Evaluation`](/fr/weave/guides/core-types/evaluations), avec une métrique simple qui compare la réponse prédite à la réponse de référence. Weave prendra chaque exemple, le fera passer dans votre application et attribuera un score à la sortie à l’aide de plusieurs fonctions de score personnalisées. Vous obtiendrez ainsi une vue des performances de votre application, ainsi qu’une UI riche pour examiner en détail chaque sortie et son score.

Nous devons d’abord créer une fonction de score qui indique si la réponse prédite correspond à la réponse de référence. Les fonctions de score Weave reçoivent la valeur de retour du modèle sous la forme de `output`, ainsi que toutes les clés correspondantes de l’exemple du jeu de données en arguments supplémentaires. Ici, `answer` provient du jeu de données et `output` est le dictionnaire renvoyé par `CausalReasoningModule.forward`.

```python lines theme={null}
@weave.op()
def weave_evaluation_scorer(answer: str, output: dict) -> dict:
    return {"match": int(answer.lower() == output["answer"].lower())}
```

Ensuite, nous encapsulons le module dans une fonction tracée que `weave.Evaluation` peut appeler. Les noms des arguments de cette fonction d’encapsulation doivent correspondre aux noms des colonnes du jeu de données utilisées en entrée par le modèle.

```python lines theme={null}
@weave.op()
def predict(question: str) -> dict:
    return baseline_module(question=question)
```

Nous pouvons maintenant définir l’évaluation et l’exécuter.

```python lines theme={null}
validation_dataset = weave.ref(
    f"bigbenchhard_{metadata.big_bench_hard_task}_val:v0"
).get()

evaluation = weave.Evaluation(
    name="baseline_causal_reasoning_module",
    dataset=validation_dataset,
    scorers=[weave_evaluation_scorer],
)

await evaluation.evaluate(predict)
```

<Frame>
  <img src="https://mintcdn.com/wb-21fd5541-docs-1917/PReu-nQCaYehtM7U/media/dspy_optimization/3.png?fit=max&auto=format&n=PReu-nQCaYehtM7U&q=85&s=56563cd9173e176581c3d5444485024b" alt="Tableau de bord d’évaluation Weave avec les métriques de performances du programme DSPy, les traces et les résultats de comparaison" width="3024" height="1892" data-path="media/dspy_optimization/3.png" />
</Frame>

<Note>
  Si vous exécutez ce code depuis un script Python, vous pouvez utiliser le code suivant pour lancer l’évaluation :

  ```python lines theme={null}
  import asyncio
  asyncio.run(evaluation.evaluate(predict))
  ```
</Note>

<Warning>
  Exécuter l’évaluation sur le jeu de données de raisonnement causal coûtera environ 0,24 \$ en crédits OpenAI.
</Warning>

<div id="optimizing-our-dspy-program">
  ## Optimisation de notre programme DSPy
</div>

Maintenant que nous disposons d’un programme DSPy de référence, essayons d’en améliorer les performances en raisonnement causal à l’aide de l’optimiseur [BootstrapFewShot](https://dspy.ai/api/optimizers/BootstrapFewShot/), qui peut ajuster les paramètres d’un programme DSPy afin de maximiser les métriques spécifiées.

```python lines theme={null}
from dspy.teleprompt import BootstrapFewShot

@weave.op()
def get_optimized_program(model: dspy.Module, metadata: Metadata) -> dspy.Module:
    @weave.op()
    def dspy_evaluation_metric(true, prediction, trace=None):
        return prediction["answer"].lower() == true.answer.lower()

    teleprompter = BootstrapFewShot(
        metric=dspy_evaluation_metric,
        max_bootstrapped_demos=metadata.max_bootstrapped_demos,
        max_labeled_demos=metadata.max_labeled_demos,
    )
    return teleprompter.compile(model, trainset=dspy_train_examples)

optimized_module = get_optimized_program(baseline_module, metadata)
```

<Frame>
  <img src="https://mintcdn.com/wb-21fd5541-docs-1917/PReu-nQCaYehtM7U/media/dspy_optimization/4.png?fit=max&auto=format&n=PReu-nQCaYehtM7U&q=85&s=08ec140c78979b57595857300523364c" alt="Interface du processus d’optimisation du programme DSPy avec la configuration du téléprompteur et la progression de l’optimisation" width="3024" height="1896" data-path="media/dspy_optimization/4.png" />
</Frame>

<Warning>
  L’exécution de l’évaluation sur le jeu de données de raisonnement causal coûtera environ 0,04 \$ en crédits OpenAI.
</Warning>

Maintenant que nous disposons de notre programme optimisé (la stratégie de prompting optimisée), évaluons-le à nouveau sur notre ensemble de validation et comparons-le à notre programme DSPy de référence.

```python lines theme={null}
@weave.op()
def predict_optimized(question: str) -> dict:
    return optimized_module(question=question)

evaluation = weave.Evaluation(
    name="optimized_causal_reasoning_module",
    dataset=validation_dataset,
    scorers=[weave_evaluation_scorer],
)

await evaluation.evaluate(predict_optimized)
```

<Frame>
  <img src="https://mintcdn.com/wb-21fd5541-docs-1917/PReu-nQCaYehtM7U/media/dspy_optimization/5.png?fit=max&auto=format&n=PReu-nQCaYehtM7U&q=85&s=646c20d46a94bc88ea4cfa943718e301" alt="Résultats de l’évaluation du programme DSPy optimisé, avec de meilleures métriques de performances et une meilleure qualité des réponses" width="3024" height="1892" data-path="media/dspy_optimization/5.png" />
</Frame>

La comparaison entre l’évaluation du programme de référence et celle du programme optimisé montre que ce dernier répond aux questions de raisonnement causal avec une précision nettement supérieure.

<div id="conclusion">
  ## Conclusion
</div>

Dans ce tutoriel, nous avons appris à utiliser DSPy pour optimiser les prompts, ainsi que Weave pour le suivi et l’évaluation afin de comparer les programmes original et optimisé.
