Des prompts en fichiers, avec versions et tests
Une bibliothèque de prompts est un dossier de prompts gardés en fichiers, chacun avec une version et un test. Un prompt qui vit dans un message de discussion se perd, se copie mal et se modifie par n’importe qui.
Dans un fichier, il peut être relu, testé et annulé, comme du code.
À la fin de cette leçon
Remarque
Je peux garder des prompts dans des fichiers avec une version et un test.
Mots clés
| Mot | Ce que ça veut dire | Exemple |
|---|---|---|
| Bibliothèque | un dossier de prompts gardés en fichiers | |
| Variable | un trou nommé que le code remplit | {prenom} |
| Version | un numéro qui dit de quelle modification il s’agit | |
| Journal des changements | une liste de ce qui a changé et pourquoi | |
| Règle | une phrase qu’un prompt doit toujours contenir | |
| Audit | un contrôle de tous les prompts à la fois |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Que contient le fichier d’un prompt ?
Chaque prompt est un fichier, comme reponse-remboursement.txt. Les trous sont des variables entre accolades, comme {prenom}, pour que le code les remplisse. Un numéro de version accompagne le fichier, et une ligne du journal des changements dit ce qui a changé.
Un test se tient à côté. Le test contient les règles que le prompt doit toujours avoir.
Ce que dit un numéro de version
| Changement | Hausse | De 1.2.3 à |
|---|---|---|
| Une faute corrigée | correctif | 1.2.4 |
| Une limite ou un exemple ajouté | mineure | 1.3.0 |
| Les variables changent, donc les appelants doivent changer | majeure | 2.0.0 |
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 vérificateur de bibliothèque, partie 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { demander } = require(\"./model\");' 'const ANCIEN = \"Rôle : Vous êtes un assistant de la compagnie de tram.\nTâche : Répondez à {prenom} au sujet d’un remboursement.\nLimites : Moins de 25 mots. Ne jamais promettre de date.\";' 'const REGLES = [\"moins de 25 mots\", \"ne jamais promettre de date\"];' > biblio6.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 vérificateur de bibliothèque, partie 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function variables(texte) {' ' const noms = [];' ' for (const f of texte.match(/\{[a-z_]+\}/g) || []) {' ' if (noms.includes(f.slice(1, -1)) === false) noms.push(f.slice(1, -1));' ' }' ' return noms;' '}' 'function remplir(texte, valeurs) {' ' const absentes = variables(texte).filter(function (n) { return (n in valeurs) === false; });' ' if (absentes.length > 0) return { ok: false, manquantes: absentes };' ' let sortie = texte;' ' for (const n of Object.keys(valeurs)) sortie = sortie.split(\"{\" + n + \"}\").join(valeurs[n]);' ' return { ok: true, texte: sortie };' '}' >> biblio6.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 vérificateur de bibliothèque, partie 3
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function perdues(ancien, nouveau) {' ' const o = ancien.toLowerCase();' ' const n = nouveau.toLowerCase();' ' return REGLES.filter(function (r) { return o.includes(r) && n.includes(r) === false; });' '}' 'async function main() {' ' console.log(\"variables : \" + variables(ANCIEN).join(\", \"));' ' const mauvais = remplir(ANCIEN, {});' ' console.log(\"remplir sans valeurs : ok \" + mauvais.ok + \", manquantes \" + mauvais.manquantes.join(\", \"));' ' const edition = ANCIEN.replace(\"Ne jamais promettre de date.\", \"\");' ' console.log(\"la modification perd : \" + perdues(ANCIEN, edition).join(\", \"));' ' const rempli = remplir(ANCIEN, { prenom: \"Mina\" });' ' const reponse = await demander([{ role: \"user\", content: rempli.texte }], \"Chère Mina, nous examinons votre remboursement.\", 50);' ' console.log(\"modèle : \" + reponse.texte);' '}' 'main();' >> biblio6.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 refuser une mauvaise modification
docker exec -w /home/node/project agent node biblio6.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
Il liste la variable, puis montre que remplir sans valeur est refusé et nomme celle qui manque. Ensuite il modifie le prompt pour retirer une limite et liste la règle que la modification perd. Cette modification serait refusée.
La dernière ligne est une courte réponse au prompt rempli. Sans modèle, un Échantillon enregistré s’affiche d’abord.
Une erreur courante
Attention
Beaucoup pensent qu’une petite modification d’un prompt partagé est sans danger. Une courte modification peut retirer une limite sur laquelle d’autre code comptait. Lancez toujours le test des règles avant d’enregistrer, même pour une petite modification.