Arrêtez de réécrire vos prompts : traitez-les comme du code
Voici un schéma que j'ai vu se répéter dans plusieurs équipes.
Quelqu'un remarque que la fonctionnalité IA donne une mauvaise réponse. Il ouvre le fichier, ajuste le prompt, rafraîchit, obtient une bonne réponse et livre. Une semaine plus tard, une autre mauvaise réponse apparaît. Quelqu'un réajuste. Au bout de six semaines, le prompt fait quatre cents lignes de superstitions accumulées, personne ne sait quelle phrase sert à quoi, et retirer quoi que ce soit paraît dangereux.
Le prompt est devenu la partie la moins bien conçue d'un code par ailleurs maintenu de façon professionnelle. C'est cela le vrai problème — pas le modèle.
Un prompt, c'est du code avec des modes de défaillance inhabituels
Un prompt a des entrées, produit des sorties, comporte des cas limites et peut régresser. Il a sa place dans le gestionnaire de versions comme le reste — mais trois propriétés le rendent plus difficile à maintenir que du code ordinaire :
- Les échecs sont silencieux. Un mauvais code lève une exception. Un mauvais prompt renvoie une réponse fluide, plausible et fausse, sans la moindre trace d'erreur.
- Les modifications ne sont pas locales. Ajouter une phrase pour corriger un cas peut changer le comportement sur des cas auxquels vous ne pensiez pas.
- Le comportement dérive sous vos pieds. Changez de version de modèle et vos instructions finement réglées peuvent se comporter autrement.
Rien de tout cela ne rend les prompts ingérables. Cela signifie que la discipline d'ingénierie habituelle y est plus nécessaire, pas moins.
Commencez par le jeu d'évaluation
Toute la discipline tient dans cette habitude. Avant d'optimiser un prompt, rassemblez de vraies entrées et notez à quoi ressemble une bonne sortie.
Vingt à cinquante cas suffisent pour démarrer. Incluez les cas ennuyeux, les cas ambigus, ceux dont la bonne réponse est « je n'ai pas assez d'informations », et chaque défaut réellement remonté par un utilisateur.
Dès lors, chaque modification devient mesurable. Vous cessez de demander « est-ce que ça semble mieux ? » pour demander « est-ce que cela corrige le cas 12 sans casser les cas 3, 7 et 19 ? ». Cette question-là a une réponse.
Séparez le stable du variable
Traitez un prompt comme une fonction, pas comme un paragraphe.
const SYSTEM = `Tu es un assistant support pour {product}.
Réponds uniquement à partir du contexte fourni.
Si le contexte est insuffisant, dis-le explicitement.`
const buildPrompt = ({ product, context, question }: Args) => ({
system: SYSTEM.replace('{product}', product),
messages: [{ role: 'user', content: `Contexte :\n${context}\n\nQuestion : ${question}` }],
})
Les bénéfices sont ceux de n'importe quel refactor : l'instruction stable est écrite une seule fois, les parties variables sautent aux yeux, et l'ensemble devient testable isolément. Cela rend aussi possible la mise en cache côté fournisseur, puisque le préfixe stable reste identique octet pour octet d'un appel à l'autre.
Écrivez vos instructions comme une spécification
La plupart des mauvais prompts sont de la mauvaise rédaction plutôt que du mauvais « prompting ».
- Soyez précis sur la forme attendue. « Réponds en moins de 80 mots, sans puces » vaut mieux que « sois concis ».
- Formulez la contrainte positivement. « Réponds uniquement à partir du contexte fourni » fonctionne plus sûrement que « n'invente rien ».
- Un bon exemple vaut mieux que trois règles vagues. Un seul exemple complet entrée/sortie surpasse en général tout un paragraphe de description.
- Supprimez ce que vous ne pouvez pas justifier. Si personne ne sait expliquer pourquoi une ligne est là, c'est probablement une superstition — retirez-la et vérifiez les évaluations.
Versionnez le prompt avec le modèle
Épinglez explicitement la version du modèle et notez quelle version du prompt a été évaluée avec elle. Lors d'une montée de version, rejouez le jeu d'évaluation avant de supposer qu'il s'agit d'une amélioration. Un modèle plus récent est généralement meilleur, et parfois moins bon sur votre tâche précise.
Journalisez, pour chaque appel en production : version du prompt, version du modèle, entrées et sortie. Quand un utilisateur signale un problème trois semaines plus tard, c'est la différence entre une correction en cinq minutes et un mystère irreproductible.
Le plus petit harnais d'évaluation qui fonctionne
On imagine qu'évaluer exige une plateforme. Il suffit d'un fichier JSON et d'une trentaine de lignes. Le voici en entier.
// evals/cases.json — enrichissez-le à chaque défaut remonté par un utilisateur
// [{ "input": "...", "expect": { "contains": ["remboursement"], "absent": ["garantie"] } }]
import cases from './cases.json'
const results = await Promise.all(
cases.map(async (c) => {
const output = await runPrompt(c.input)
const missing = (c.expect.contains ?? []).filter((s) => !output.includes(s))
const leaked = (c.expect.absent ?? []).filter((s) => output.includes(s))
return { input: c.input, pass: !missing.length && !leaked.length, missing, leaked, output }
}),
)
const failed = results.filter((r) => !r.pass)
console.table(failed.map(({ input, missing, leaked }) => ({ input, missing, leaked })))
console.log(`${results.length - failed.length}/${results.length} réussis`)
process.exit(failed.length ? 1 : 0)
Les assertions par sous-chaîne paraissent rudimentaires, et elles le sont. Elles attrapent pourtant l'immense majorité des régressions réelles : la mention légale disparue, la formulation exigée par le juridique, la promesse que le modèle ne doit jamais faire. Commencez rudimentaire, rejouez à chaque modification de prompt, et ne passez à une évaluation notée par un modèle que lorsque la version simple ne suffit vraiment plus.
La ligne process.exit(1) est la plus importante. Elle transforme le fichier en quelque chose que la CI peut faire échouer — et c'est ce qui fait tenir la discipline une fois l'enthousiasme initial retombé.
Ce que cela rapporte
Une équipe disposant d'un jeu d'évaluation modifie ses prompts sereinement un vendredi. Une équipe qui n'en a pas les modifie avec appréhension, surtout en ajoutant du texte, et son prompt ne fait que grossir.
L'ironie, c'est que cette discipline n'a rien de nouveau ni de spécifique à l'IA. Ce sont les tests, le versionnage et l'écriture claire — les trois mêmes choses qui ont rendu le reste du code maintenable. Les prompts en ont simplement été dispensés pendant deux ans, et cela se voit.
Traitez le prompt comme du logiciel, et il se met à se comporter comme du logiciel : compréhensible, modifiable, et sûr à toucher.