Plus facile à lire avec un fond crème, une teinte, plus de contraste ou un texte plus grand ? Choisissez vos couleurs et votre texte, une fois pour toutes les pages.

Leçon gratuite

Tests A/B et tests fantômes

Après cette leçon: Je peux comparer deux versions sans me laisser tromper par le hasard.

Leçon de 70 min6 commandesLab agent de code IA : utiliser opencode pour expliquer et corriger du code, et vérifier son travail

Comment comparer deux versions d’IA équitablement

Un test A/B donne la version A à un groupe d’utilisateurs et la version B à un autre, puis compare la fréquence de réussite. Un test fantôme lance la nouvelle version sur de vraies requêtes, mais personne ne voit ses réponses.

Les deux peuvent tromper. Un écart de neuf points peut n’être que du hasard.

À la fin de cette leçon

Remarque

Je peux comparer deux versions sans me laisser tromper par le hasard.

Mots clés

MotCe que ça veut dire
Test A/Bdeux groupes d’utilisateurs, une version chacun
Test fantômeune nouvelle version lancée là où personne ne la voit
Taux de réussitela part des requêtes qui ont marché
Écartun taux de réussite moins l’autre, en points
Fluctuationde combien un écart bouge par hasard

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Un écart doit dépasser la fluctuation

La version B réussit 138 fois sur 200 et A réussit 120 fois sur 200. L’écart est de 9 points. Mais deux groupes de 200 utilisateurs diffèrent aussi par hasard.

La fluctuation mesure de combien un écart bouge par hasard. Une règle simple : ne faites confiance à un écart que s’il vaut au moins deux fois la fluctuation.

Exemple détaillé : deux tests

TestUtilisateurs par groupeÉcartFluctuationDeux fois la fluctuationVerdict
A contre B2009,04,89,6Non prouvé
A contre C1 0005,02,24,3Fiable

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Une erreur courante

Attention

Beaucoup pensent que le meilleur score gagne. Un meilleur score sur un petit test peut venir du hasard. Ne nommez un gagnant que si l’écart vaut au moins deux fois la fluctuation. Sinon, dites non prouvé et récoltez plus de données.

Un test fantôme trouve les nouveaux échecs

Lancez la nouvelle version sur les mêmes vraies requêtes et gardez ses réponses cachées. Pour chaque requête, vous avez une paire : le résultat ancien et le résultat nouveau.

Des totaux égaux peuvent cacher un changement. Deux cas peuvent devenir pires pendant que deux autres deviennent meilleurs. Comptez les cas pires et lisez chacun.

Exemple détaillé : douze paires

Paire (ancien, nouveau)SensNombre
réussi, réussiIdentique7
échoué, échouéIdentique1
échoué, réussiNouvelle meilleure2
réussi, échouéNouvelle pire, à lire2

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Écrire l’assistant du modèle, partie 1

Commande
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

Commande
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 script de comparaison, partie 1

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { demander } = require(\"./model\");' 'function fluctuation(a, an, b, bn) {' '  const p = (a + b) / (an + bn);' '  return Math.sqrt(p * (1 - p) * (1 / an + 1 / bn)) * 100;' '}' 'function ecart(a, an, b, bn) { return (b / bn - a / an) * 100; }' 'function verdict(a, an, b, bn) {' '  const sur = Math.abs(ecart(a, an, b, bn)) >= 2 * fluctuation(a, an, b, bn);' '  return sur ? \"fiable\" : \"non prouvé\";' '}' 'function virgule(x) { return x.toFixed(1).replace(\".\", \",\"); }' > ab.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 script de comparaison, partie 2

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const tests = [' '  { nom: \"A contre B\", a: 120, an: 200, b: 138, bn: 200 },' '  { nom: \"A contre C\", a: 600, an: 1000, b: 650, bn: 1000 },' '];' 'const paires = \"rr rr re rr er rr ee rr re rr rr er\".split(\" \");' 'function compter(sorte) { return paires.filter(function (p) { return p === sorte; }).length; }' >> ab.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 script de comparaison, partie 3

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' '  tests.forEach(function (t) {' '    console.log(t.nom + \" : écart \" + virgule(ecart(t.a, t.an, t.b, t.bn)) + \" points, fluctuation \" + virgule(fluctuation(t.a, t.an, t.b, t.bn)) + \" -> \" + verdict(t.a, t.an, t.b, t.bn));' '  });' '  console.log(\"fantôme : identiques \" + (compter(\"rr\") + compter(\"ee\")) + \", nouvelle meilleure \" + compter(\"er\") + \", nouvelle pire \" + compter(\"re\"));' '  const q = \"En une phrase courte, pourquoi un écart de 9 points peut-il n’être que du hasard ?\";' '  const echantillon = \"Avec 200 utilisateurs seulement par groupe, le hasard peut à lui seul déplacer un score de cette taille.\";' '  const reponse = await demander([{ role: \"user\", content: q }], echantillon, 60);' '  console.log(\"le modèle dit : \" + reponse.texte);' '}' 'main();' >> ab.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 la comparaison

Commande
docker exec -w /home/node/project agent node ab.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.

Ce que le Run affiche

LigneCe qu’elle montre
A contre B : écart 9,0 points, fluctuation 4,8 -> non prouvéUn grand écart, un petit test
A contre C : écart 5,0 points, fluctuation 2,2 -> fiableUn écart plus petit, un test plus grand
fantôme : identiques 8, nouvelle meilleure 2, nouvelle pire 2Compté sur douze paires enregistrées
le modèle dit : ...Une phrase du labo. Un échantillon enregistré si aucun modèle ne répond

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

À propos de ce labo et de sa source: Lab agent de code IA : utiliser opencode pour expliquer et corriger du code, et vérifier son travail

Vous enseignez à une classe ? Proposez ce module à vos étudiants avec un guide de l'enseignant, des devoirs corrigés et un laboratoire pour chaque étudiant.