Menu

Itérer sur un prompt : le tester et l'améliorer

Améliorer un prompt marche le mieux comme une petite expérience : définir ce qu'est une bonne réponse, garder quelques entrées de test fixes, changer une seule chose à la fois et comparer les sorties côte à côte.

Chaque prompt de cette page se modifie, puis s'ouvre dans ChatGPT, Claude ou une autre application d'IA.

La première version d'un prompt est un brouillon. Elle vous donne souvent quelque chose de proche de ce que vous voulez, et l'écart entre proche et juste se comble en itérant : modifier le prompt volontairement, le relancer sur la même entrée et vérifier si la modification a aidé. Fait sans méthode, itérer revient à reformuler au hasard jusqu'à ce qu'une sortie chanceuse ait l'air correcte. Fait comme une petite expérience, cela vous donne un prompt qui marche sur les cent entrées suivantes, pas seulement sur celle que vous avez testée.

La méthode tient en cinq étapes : définir ce qu'est une bonne réponse, garder des entrées de test fixes, changer une seule chose à la fois, comparer les sorties et savoir quand s'arrêter.

Définir ce qu'est une bonne réponse

Avant de modifier quoi que ce soit, notez ce que la sortie doit faire, sous forme de vérifications auxquelles on répond par oui ou non. "Un bon message de commit" ne se vérifie pas. Ceci, si :

  1. La ligne de sujet fait moins de 50 caractères.
  2. Elle suit le format Conventional Commits (fix:, feat:, etc.).
  3. Le corps explique pourquoi la modification était nécessaire, pas ce que le diff montre déjà.
  4. Il mentionne le numéro du ticket quand il y en a un.

Les critères ont deux rôles. Ils vous disent quoi ajouter au prompt, puisque chacun correspond souvent à une consigne manquante. Et ils vous empêchent de juger les sorties à leur ton agréable, ce qui est le moyen le plus sûr d'accepter une réponse assurée mais fausse.

Garder un petit jeu d'entrées de test

Choisissez trois à dix entrées et gardez-les fixes pendant que vous travaillez. Incluez des cas typiques, deux ou trois cas difficiles (un champ vide, une entrée très longue, une langue que le prompt n'attendait pas), et chaque entrée qui a déjà échoué. Un prompt réglé sur un seul exemple a tendance à coller à cet exemple et à échouer sur le suivant.

Écrivez le prompt comme un modèle avec un emplacement pour l'entrée, pour que chaque version tourne exactement sur le même contenu.

Changer une seule chose à la fois

Si vous changez à la fois le rôle, le format et les exemples et que la sortie s'améliore, vous ne savez pas quelle modification a joué, et vous gardez peut-être deux changements inutiles. Changez une chose, lancez, comparez. Les onglets ci-dessous sont trois versions d'un même prompt, chacune à une seule modification de la précédente.

Écris un message de commit pour ce diff.- if len(password) > 8: + if len(password) >= 8: return True
Try it
Example replyReplies vary between models and runs.

Mise à jour de la validation de la longueur du mot de passe

Ce commit met à jour la logique de validation du mot de passe en remplaçant l'opérateur de comparaison > par >=. Désormais, les mots de passe d'exactement 8 caractères sont considérés comme valides. Cette modification améliore la précision de la validation et offre une meilleure expérience aux utilisateurs qui créent un compte.

La version 1 échoue aux critères 2 et 3 : le sujet n'a pas de préfixe de type, et le corps raconte le diff avec plus de mots. La version 2 ajoute les exigences de format et valide les critères 1 et 2, mais son corps décrit toujours le diff. La modification suivante qui vient à l'esprit est une consigne de plus ("explique pourquoi"), mais le modèle ne peut pas expliquer une raison qu'on ne lui a jamais donnée. La version 3 ajoute plutôt le contexte manquant, et le corps comme la référence au ticket suivent sans qu'on les demande. C'est la leçon la plus fréquente de l'itération : quand une consigne ne corrige pas une sortie, il manque en général une information au prompt, pas de l'insistance.

Comparer les sorties côte à côte

Lancez chaque version sur chaque entrée de test, et lancez-la plusieurs fois, car les modèles de chat échantillonnent leurs mots et deux exécutions du même prompt diffèrent. Placez les sorties côte à côte et vérifiez-les selon vos critères, pas selon votre souvenir de l'exécution précédente.

Pour des critères précis, un second appel au modèle peut faire une première passe de notation. Collez les sorties dans un prompt de notation avec les critères détaillés :

Noter des sorties selon des critères fixes
Fill in
Vérifie chaque sortie ci-dessous selon les critères. Pour chaque critère, réponds réussi ou échoué avec une courte justification qui cite la sortie. Ne juge que les critères listés. Ne récompense ni la longueur ni le style. Critères : 1. Ligne de sujet de moins de 50 caractères. 2. Suit Conventional Commits. 3. Le corps explique pourquoi la modification était nécessaire, pas ce que montre le diff. 4. Mentionne le numéro du ticket. Sortie A : """ fix: accepte les mots de passe de 8 caractères Remplace la condition de longueur > par >= pour que les mots de passe d'exactement 8 caractères passent la validation. """ Sortie B : """ fix: accepte les mots de passe de 8 caractères La page d'inscription demande au moins 8 caractères, mais la vérification refusait les mots de passe de cette longueur exacte : les utilisateurs qui suivaient les instructions ne pouvaient pas s'inscrire. Fixes #412 """ Réponds sous forme de tableau avec une ligne par critère.
Try it
Example replyReplies vary between models and runs.
CritèreSortie ASortie B
1. Sujet de moins de 50 caractèresRéussi : le sujet fait 46 caractèresRéussi : même sujet, 46 caractères
2. Conventional CommitsRéussi : commence par "fix:"Réussi : commence par "fix:"
3. Le corps explique pourquoiÉchoué : "Remplace la condition de longueur > par >=" répète le diffRéussi : "les utilisateurs qui suivaient les instructions ne pouvaient pas s'inscrire"
4. Mentionne le ticketÉchoué : aucun numéro de ticketRéussi : "Fixes #412"

Traitez un correcteur automatique comme un assistant, pas comme un arbitre. Zheng et al. 2023, "Judging LLM-as-a-Judge with MT-Bench and Chatbot Arena", ont documenté les biais des modèles utilisés comme juges, dont une préférence pour les réponses longues et pour la réponse placée à une certaine position. Gardez des critères vérifiables, demandez des preuves citées, inversez l'ordre de A et B quand vous en comparez deux, et lisez vous-même un échantillon des sorties. Des vérifications comme le nombre de caractères sont plus fiables sous forme d'une ligne de code que du jugement d'un modèle.

Corriger le prompt, pas la conversation

Dans un chat, on est tenté de corriger la réponse par des relances : "plus court", "non, mentionne le ticket", "utilise l'autre format". Vous obtenez ainsi une bonne sortie, et le prompt reste aussi mauvais qu'avant. Quand une correction marche, intégrez-la au prompt et relancez celui-ci depuis zéro. La prochaine fois que vous aurez besoin du résultat, vous collerez un seul message au lieu d'en répéter cinq.

Gardez les anciennes versions avec une note d'une ligne sur ce qui a changé et ce que cela a corrigé. Un simple fichier texte suffit. Quand une modification ultérieure dégrade les choses, vous pouvez revenir en arrière au lieu d'essayer de vous rappeler ce que disait le prompt.

Lancer une comparaison dans le code

Dès qu'un prompt passe par une API, un court script peut produire la vue côte à côte pour chaque version et chaque entrée de test. Celui-ci utilise le SDK Python d'OpenAI et écrit un fichier markdown que vous pouvez lire de haut en bas.

from openai import OpenAI

client = OpenAI()
MODEL = "your-model-id"  # e.g. from your provider's model list

# each prompt file contains {input} where the test diff goes
PROMPTS = {
    "v2": open("prompts/commit_v2.txt").read(),
    "v3": open("prompts/commit_v3.txt").read(),
}
TESTS = [open(f"tests/diff_{i}.txt").read() for i in range(1, 6)]

with open("results.md", "w") as out:
    for i, test in enumerate(TESTS, 1):
        out.write(f"## Test {i}\n\n")
        for name, template in PROMPTS.items():
            for run in (1, 2):
                response = client.chat.completions.create(
                    model=MODEL,
                    messages=[{"role": "user", "content": template.replace("{input}", test)}],
                )
                out.write(f"### {name}, run {run}\n\n{response.choices[0].message.content}\n\n")

Quand s'arrêter

Arrêtez-vous quand chaque critère est validé sur chaque entrée de test, sur deux ou trois exécutions. En ajouter au-delà ajoute surtout de la longueur, et chaque consigne supplémentaire est une chose de plus qui peut entrer en conflit avec les autres.

Arrêtez-vous aussi quand les modifications commencent à échanger les échecs : une retouche corrige le test 2 et casse le test 4, la suivante fait l'inverse. Ce schéma signifie qu'on demande au prompt quelque chose qu'une seule consigne ne peut pas fixer. Les issues habituelles : montrer le format avec deux ou trois exemples (prompting few-shot), découper le travail en étapes avec le chaînage de prompts, ou déplacer les parties déterministes, comme compter des caractères ou vérifier un format, dans du code qui contrôle la sortie. Si vous manquez d'idées, le méta-prompting peut aider : donnez à un modèle le prompt, l'entrée et la mauvaise sortie, et demandez-lui quelle partie du prompt en est le plus probablement la cause.

Questions fréquentes

Comment améliorer un prompt qui donne de mauvaises réponses ?

Regardez la mauvaise réponse et nommez ce qui ne va pas : mauvais format, fait manquant, mauvais public, trop long. Trouvez ensuite ce que le prompt n'a pas dit et qui l'aurait évité, ajoutez cette seule chose, et lancez la nouvelle version sur la même entrée. Les mauvaises réponses viennent plus souvent d'un contexte ou d'une consigne de format manquants que de la formulation.

Combien d'entrées de test faut-il pour tester un prompt ?

Pour un prompt que vous réutiliserez, trois à dix suffisent en général : quelques cas typiques, un ou deux cas limites (très court, très long, inhabituel) et une entrée qui a déjà posé problème. Gardez-les fixes pendant que vous itérez, pour qu'un changement de sortie vienne du prompt et non d'une entrée différente.

Pourquoi le même prompt donne-t-il une réponse différente quand je le relance ?

Les modèles de chat tirent chaque mot d'une distribution de probabilités, donc les sorties varient d'une exécution à l'autre. Quand vous comparez deux versions d'un prompt, lancez chacune plusieurs fois sur les mêmes entrées. Une différence qui apparaît à chaque exécution est probablement réelle ; une qui n'apparaît qu'une fois peut relever du hasard. Via une API, vous pouvez aussi baisser la température pour réduire la variation.

Peut-on utiliser l'IA pour noter les sorties d'un prompt ?

Oui, pour des critères formulables précisément, comme "le corps explique pourquoi la modification était nécessaire" ou "mentionne le numéro du ticket". Donnez au correcteur vos critères exacts et demandez réussi ou échoué par critère, avec une citation comme preuve. Les correcteurs automatiques ont des biais connus, dont une préférence pour les réponses longues et pour une position plutôt que l'autre : lisez vous-même une partie des sorties et inversez l'ordre quand vous en comparez deux.

Quand arrêter d'améliorer un prompt ?

Arrêtez quand chaque critère est validé sur chaque entrée de test, sur deux ou trois exécutions, ou quand chaque nouvelle modification corrige un cas et en casse un autre. À ce stade, le problème n'est en général plus le prompt : la tâche a peut-être besoin d'exemples, d'être découpée en étapes, ou d'une vérification dans le code.

Coddy programming languages illustration

Apprendre à coder avec Coddy

COMMENCER