Assembler les pièces
Un petit agent IA est une seule boucle qui planifie, appelle des outils, garde des notes et s’arrête selon une règle. Vous avez construit chaque pièce séparément. Le savoir-faire, c’est de les relier pour que la boucle se teste facilement.
Une boucle qui ne marche qu’avec un vrai modèle ne se teste pas. Une boucle sur un modèle scripté, si.
À la fin de cette leçon
Remarque
Je peux construire un petit agent qui planifie, appelle des outils, retient et s’arrête.
Mots-clés
| Mot | Ce que ça veut dire |
|---|---|
| Boucle d’agent | choisir une action, la lancer, la noter, recommencer |
| Modèle scripté | un remplaçant qui rend des actions fixes |
| Trace | la liste de ce que chaque étape a fait |
| Action de fin | l’action qui termine un run |
| Doublure de test | un remplaçant utilisé à la place de la vraie pièce |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
La boucle d’agent en une image
À chaque tour, on vérifie d’abord le budget. Le modèle choisit une action. Une action de fin termine le run. Toute autre action lance un outil et note le résultat.
Ensuite la boucle compte les échecs de suite. Assez d’échecs terminent le run en « bloqué ». Sinon on repart pour un tour.
Écrire l’aide 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\";' '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 || 200 }),' ' signal: AbortSignal.timeout(30000),' ' });' ' if (res.ok === false) throw new Error(\"statut \" + res.status);' ' return (await res.json()).choices[0].message.content;' > 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’aide du modèle, partie 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' ' } catch (erreur) {' ' console.log(\"Échantillon enregistré : aucun modèle n’a répondu (\" + erreur.message + \").\");' ' const liste = [].concat(echantillon);' ' const tour = messages.filter(function (m) { return m.role === \"assistant\"; }).length;' ' return liste[Math.min(tour, liste.length - 1)];' ' }' '}' '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 petit agent, partie 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { demander } = require(\"./model\");' 'const PRIX = { baguette: 110, croissant: 130 };' 'const notes = [];' 'const outils = {' ' lire_prix: function (produit) {' ' if (PRIX[produit] === undefined) return { ok: false, texte: \"pas de prix pour \" + produit };' ' return { ok: true, texte: produit + \" \" + PRIX[produit] + \" centimes\" };' ' },' ' noter: function (texte) { notes.push(texte); return { ok: true, texte: \"enregistre \" + notes.length }; },' '};' > agent1.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 petit agent, partie 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const scenario = [' ' { outil: \"lire_prix\", arg: \"baguette\" },' ' { outil: \"lire_prix\", arg: \"kiwi\" },' ' { outil: \"lire_prix\", arg: \"croissant\" },' ' { outil: \"noter\", arg: \"baguette 110, croissant 130\" },' ' { outil: \"terminer\", arg: \"Une baguette et un croissant coûtent 240 centimes.\" },' '];' '// Un modèle scripté rend la même action à chaque exécution : on peut donc tester la boucle.' 'const modeleScripte = function (tour) { return JSON.stringify(scenario[tour]); };' >> agent1.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 petit agent, partie 3
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' ' const budget = Number(process.argv[2] || 6), echecsMax = 2;' ' let utilisees = 0, echecs = 0, issue = \"budget\", reponse = \"\";' ' while (utilisees < budget && utilisees < scenario.length) {' ' const action = JSON.parse(modeleScripte(utilisees));' ' utilisees += 1;' ' if (action.outil === \"terminer\") { issue = \"termine\"; reponse = action.arg; break; }' ' const lancer = outils[action.outil];' ' const r = lancer ? lancer(action.arg) : { ok: false, texte: \"outil inconnu \" + action.outil };' ' echecs = r.ok ? 0 : echecs + 1;' ' console.log(\"Étape \" + utilisees + \" : \" + action.outil + \"(\" + action.arg + \") -> \" + r.texte);' ' if (echecs === echecsMax) { issue = \"bloque\"; break; }' ' }' ' console.log(\"Issue : \" + issue + \" après \" + utilisees + \" étapes. Notes : \" + JSON.stringify(notes));' >> agent1.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 petit agent, partie 4
docker exec -w /home/node/project agent sh -c "printf '%s\n' ' if (issue === \"termine\") {' ' const demande = [{ role: \"user\", content: \"Dites ceci à un client en une phrase aimable : \" + reponse }];' ' console.log(\"Réponse : \" + await demander(demande, reponse, 60));' ' }' '}' 'main();' >> agent1.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 l’agent avec un budget de 6
docker exec -w /home/node/project agent node agent1.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.
Le relancer avec un budget de 4
docker exec -w /home/node/project agent node agent1.js 4Affiché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.
Une sortie possible
| Budget | Ce qu’il montre |
|---|---|
| 6 | L’étape 2 échoue pour le kiwi, puis Issue : termine après 5 étapes, et une réponse en une phrase |
| 4 | Quatre étapes, puis Issue : budget après 4 étapes, et aucune réponse |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Tester la boucle sur un modèle scripté
Un modèle scripté rend les mêmes actions à chaque exécution. Avec lui, vous testez la boucle pour chaque issue : terminé, budget, bloqué et script épuisé.
Testez le vrai modèle à part, sur ce qu’il fait le mieux : choisir une action sensée. Ne jugez jamais la boucle sur un seul essai réussi.
Une erreur fréquente
Attention
Beaucoup pensent qu’un agent qui a marché une fois avec un vrai modèle est testé. Un modèle donne des actions différentes à chaque fois : un bon essai ne prouve presque rien. Testez la boucle sur un script, puis le modèle sur beaucoup de cas.