Un prompt, c'est du verre. Tu passes une heure à peaufiner une phrase pour GPT-4o, et le jour où tu changes de modèle ou de version, tout casse. Tu recommences. Ce petit manège, DSPy — un framework signé Stanford — a décidé d'y mettre fin.
L'idée tient en une phrase : arrête d'écrire des prompts, écris des programmes. Tu décris ce que tu veux (les entrées, les sorties), tu fournis quelques exemples et une façon de noter la qualité, et DSPy fabrique puis améliore les instructions à ta place. Tu changes de modèle ? Tu recompiles au lieu de réécrire.
1. Installe DSPy
Un seul paquet, rien d'autre. DSPy est en pur Python et se glisse dans n'importe quel projet.
pip install dspy
# ou, plus rapide et sans venv :
uv add dspy2. Branche un modèle
DSPy parle à presque tous les LLM via une interface unique : OpenAI, Anthropic, Mistral, ou un modèle local servi par Ollama. Tu ne changes qu'une ligne.
import dspy
lm = dspy.LM("openai/gpt-4o-mini", api_key="sk-...")
dspy.configure(lm=lm)Pour du 100 % local, remplace la première ligne par dspy.LM("ollama_chat/llama3.1") après avoir lancé Ollama. Le reste du code ne bouge pas.
3. Décris la tâche avec une signature
Une signature, c'est la fiche de poste de ton modèle : quelles entrées, quelles sorties, et une consigne en une phrase. Pas de prompt géant à copier-coller.
class Verdict(dspy.Signature):
"""Classe un commentaire en positif, négatif ou neutre."""
commentaire: str = dspy.InputField()
sentiment: str = dspy.OutputField(desc="positif, négatif ou neutre")4. Appelle-le comme une fonction
ChainOfThought demande au modèle de raisonner avant de répondre. Résultat : une sortie propre et un raisonnement visible, que tu peux déboguer.
juger = dspy.ChainOfThought(Verdict)
resultat = juger(commentaire="Écran mort au bout de trois jours.")
print(resultat.sentiment) # négatif
print(resultat.reasoning) # le raisonnement, lisible et corrigeable5. Laisse DSPy optimiser tes prompts
Le vrai super-pouvoir arrive ici. Tu donnes une poignée d'exemples annotés et une métrique de réussite, puis BootstrapFewShot fabrique et teste des dizaines de variantes de ton prompt jusqu'à trouver la meilleure.
exemples = [
dspy.Example(commentaire="Une tuerie, je le rachèterais.", sentiment="positif").with_inputs("commentaire"),
dspy.Example(commentaire="Livré en retard, déjà en panne.", sentiment="négatif").with_inputs("commentaire"),
dspy.Example(commentaire="Correct, sans plus.", sentiment="neutre").with_inputs("commentaire"),
]
def est_juste(exemple, pred, trace=None):
return pred.sentiment.strip().lower() == exemple.sentimentfrom dspy.teleprompt import BootstrapFewShot
optimiseur = BootstrapFewShot(metric=est_juste)
juger_ameliore = optimiseur.compile(juger, trainset=exemples)
print(juger_ameliore(commentaire="Le service client répond en deux minutes.").sentiment)Pourquoi ça change tout
Quand ton prompt vit dans une chaîne de caractères, il est figé. Quand il vit dans une signature, il devient une variable : DSPy peut le mesurer, le comparer, le réoptimiser. C'est la différence entre bricoler et faire de l'ingénierie.
Tu n'as plus besoin d'être un poète du prompt. Décris la tâche, donne des exemples, note les résultats, et laisse la machine faire ce qu'elle sait faire : essayer, comparer, recommencer. Ton code, lui, reste propre et portable d'un modèle à l'autre. La prochaine fois qu'un prompt te résiste, ne le réécris pas. Programme-le.






