Tester un prompt sur des cas fixes
Un test de prompt lance un ensemble fixe de cas et applique une règle à chaque réponse. La règle est simple : un mot doit apparaître, un autre non, la réponse doit rester courte.
Sans test, un prompt modifié qui règle le cas que vous regardez peut en casser deux autres sans que vous le voyiez.
À la fin de cette leçon
Remarque
Je peux dire si un prompt modifié est meilleur.
Mots clés
| Mot | Ce que ça veut dire |
|---|---|
| Cas | une entrée avec laquelle on teste |
| Règle | un contrôle simple sur une réponse |
| Référence | le prompt auquel on compare |
| Régression | un cas qui réussissait et qui rate maintenant |
| Réussite | une réponse qui respecte sa règle |
| Enregistrée | une réponse gardée pour qu’un test se répète |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Qu’est-ce qu’un cas et une règle ?
Un cas est une entrée, comme un voyageur qui demande un remboursement. Une règle est un contrôle que le code peut faire sur la réponse. « Contient le mot rembours » est une règle. « A l’air aimable » n’en est pas une, car le code ne peut pas le vérifier.
Gardez un petit ensemble fixe de cas. Lancez chaque prompt sur le même ensemble : ainsi, seul le prompt a changé.
Deux prompts sur trois cas
| Cas | Prompt A | Prompt B |
|---|---|---|
| remboursement | réussite | échec (dit désolé) |
| retard | échec | réussite |
| merci | réussite | échec (parle de retard) |
| Total | 2 sur 3 | 1 sur 3 |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Écrire l’assistant du modèle, partie 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const base = process.env.AI_URL || \"http://ai:4000\";' '// Les jetons d’une réponse, ou null si elle n’en donne pas.' 'function compter(donnees, nom) {' ' return donnees.usage && typeof donnees.usage[nom] === \"number\" ? donnees.usage[nom] : null;' '}' > model.js"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Écrire l’assistant du modèle, partie 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function demander(messages, echantillon, max) {' ' try {' ' const res = await fetch(base + \"/v1/chat/completions\", {' ' method: \"POST\",' ' headers: { \"content-type\": \"application/json\", authorization: \"Bearer lab\" },' ' body: JSON.stringify({ model: \"lab\", messages: messages, max_tokens: max || 100 }),' ' signal: AbortSignal.timeout(30000),' ' });' ' if (res.ok === false) throw new Error(\"statut \" + res.status);' ' const d = await res.json();' ' return { texte: d.choices[0].message.content, entree: compter(d, \"prompt_tokens\"), sortie: compter(d, \"completion_tokens\"), enregistre: false };' ' } catch (erreur) {' ' console.log(\"Échantillon enregistré : aucun modèle n’a répondu (\" + erreur.message + \").\");' ' return { texte: echantillon, entree: null, sortie: null, enregistre: true };' ' }' '}' 'module.exports = { demander };' >> model.js"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Écrire le testeur de prompt, partie 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { demander } = require(\"./model\");' 'const cas = [' ' { nom: \"remboursement\", doit: [\"rembours\"], interdit: [\"désolé\"], max: 25 },' ' { nom: \"retard\", doit: [\"retard\"], interdit: [], max: 25 },' ' { nom: \"merci\", doit: [\"merci\"], interdit: [\"retard\"], max: 25 },' '];' 'const A = [\"Nous vous rembourserons sous cinq jours.\", \"Le tram est en panne, nous nous excusons.\", \"Merci pour votre message.\"];' 'const B = [\"Désolé, nous vous rembourserons sous cinq jours.\", \"Le tram a dix minutes de retard.\", \"Merci. Désolé pour le retard.\"];' > tester5.js"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Écrire le testeur de prompt, partie 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function reussit(reponse, c) {' ' const bas = reponse.toLowerCase();' ' const trop = reponse.split(\" \").length > c.max;' ' const a = c.doit.every(function (m) { return bas.includes(m); });' ' const mauvais = c.interdit.some(function (n) { return bas.includes(n); });' ' return a && mauvais === false && trop === false;' '}' 'function lancer(reponses) {' ' return reponses.map(function (r, i) { return reussit(r, cas[i]); });' '}' >> tester5.js"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Écrire le testeur de prompt, partie 3
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' ' const ra = lancer(A);' ' const rb = lancer(B);' ' const noms = function (drapeaux, autre) {' ' return cas.filter(function (c, i) { return drapeaux[i] && autre[i] === false; }).map(function (c) { return c.nom; });' ' };' ' console.log(\"A réussit \" + ra.filter(Boolean).length + \" sur 3, B réussit \" + rb.filter(Boolean).length + \" sur 3\");' ' console.log(\"aidés : \" + noms(rb, ra).join(\", \") + \" | abîmés : \" + noms(ra, rb).join(\", \"));' ' const question = \"Répondez à un voyageur qui veut un remboursement, en moins de 25 mots.\";' ' const reponse = await demander([{ role: \"user\", content: question }], A[0], 50);' ' console.log(\"la réponse réelle respecte la règle du remboursement : \" + reussit(reponse.texte, cas[0]));' '}' 'main();' >> tester5.js"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Lancer et comparer deux prompts
docker exec -w /home/node/project agent node tester5.jsAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Ce que le Run affiche
La première ligne dit que A réussit 2 sur 3 et B 1 sur 3. La deuxième dit que B a aidé le cas du retard et abîmé remboursement et merci. Vous gardez donc A.
Ces deux lignes utilisent des réponses enregistrées : tous les étudiants les voient. La dernière ligne vérifie une réponse réelle et peut valoir vrai ou faux. Elle montre qu’une vraie réponse peut rater une règle. Sans modèle, un Échantillon enregistré s’affiche d’abord.
Une erreur courante
Attention
Beaucoup pensent qu’un prompt est meilleur s’il a réglé le cas qui les agaçait. Un cas n’est qu’un échantillon. Lancez tout l’ensemble et comptez ce qui a été aidé et ce qui a été abîmé avant de décider.