L’agent qui avait oublié le budget
La mémoire d’un agent, c’est tout ce qu’il emporte d’une étape, ou d’un run, à la suivante. Un modèle ne retient rien seul : la mémoire est du texte que votre programme remet dans la consigne.
Un agent d’achats propose un manteau à 60 euros à une cliente qui avait dit 30. Le budget a été dit à l’étape un et avait disparu à l’étape neuf.
À la fin de cette leçon
Remarque
Je peux décider ce qu’un agent retient entre les étapes et entre les runs.
Mots-clés
| Mot | Ce que ça veut dire | Exemple |
|---|---|---|
| Bloc-notes | les notes qu’un agent garde pendant un run | |
| Résumé | un texte plus court qui remplace un texte plus long | |
| Réserve | une mémoire gardée entre les runs | |
| Budget de mémoire | la quantité maximale de texte en mémoire | 120 caractères |
| Fenêtre de contexte | la quantité de texte qu’un modèle lit d’un coup |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Trois sortes de mémoire
Le bloc-notes est la liste des messages et des notes d’un seul run. Un résumé remplace un long historique par un texte court. Une réserve vit entre les runs, dans un fichier ou une base.
Les trois finissent dans la consigne. Chaque ligne retenue est donc renvoyée à chaque étape, et vous la payez à chaque fois.
Exemple travaillé : les trois sortes comparées
| Sorte | Dure | Grossit de | Risque principal |
|---|---|---|---|
| Bloc-notes | Un run | Chaque étape | Remplit la fenêtre de contexte |
| Résumé | Un run ou plus | Remplacé à chaque fois | Perd un détail important |
| Réserve | Entre les runs | Chaque run | Des faits anciens qui ne sont plus vrais |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
É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 la démo de mémoire, partie 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { demander } = require(\"./model\");' 'const notes = [' ' { texte: \"La cliente est Léa, un cadeau pour son frère\", important: true },' ' { texte: \"Il pleut aujourd’hui\", important: false },' ' { texte: \"Le budget est de 30 euros\", important: true },' ' { texte: \"Des gants coûtent 4 euros\", important: false },' ' { texte: \"Une écharpe coûte 18 euros\", important: false },' ' { texte: \"Léa n’aime pas le rouge\", important: true },' '];' 'const BUDGET = 120;' 'const memoire = [];' 'function taille() { return memoire.reduce(function (n, m) { return n + m.texte.length; }, 0); }' > memoire1.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 la démo de mémoire, partie 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function retenir(note) {' ' memoire.push(note);' ' while (taille() > BUDGET) {' ' const place = memoire.findIndex(function (m) { return m.important === false; });' ' if (place === -1) break;' ' console.log(\" oublié : \" + memoire[place].texte);' ' memoire.splice(place, 1);' ' }' ' console.log(\"Ajouté, \" + memoire.length + \" notes, \" + taille() + \" caractères\");' '}' >> memoire1.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 la démo de mémoire, partie 3
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' ' notes.forEach(retenir);' ' const texte = notes.map(function (n) { return n.texte; }).join(\". \");' ' const demande = [{ role: \"user\", content: \"Résumez ces notes en une phrase pour un agent qui poursuit le travail : \" + texte }];' ' const echantillon = \"Léa cherche un cadeau pour son frère, 30 euros au plus, rien de rouge.\";' ' console.log(\"Résumé : \" + await demander(demande, echantillon, 80));' '}' 'main();' >> memoire1.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 voir ce qui est oublié
docker exec -w /home/node/project agent node memoire1.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.
Une sortie possible
| Ligne | Ce qu’elle peut montrer |
|---|---|
| Ajouté, 1 notes, 44 caractères | Une ligne après chaque ajout : le nombre de notes et de caractères |
| oublié : Il pleut aujourd’hui | Affiché quand la mémoire dépasse son budget de 120 caractères |
| oublié : Des gants coûtent 4 euros | La deuxième note sans importance, la plus ancienne qui reste, part ensuite |
| Ajouté, 4 notes, 118 caractères | La dernière ligne : les trois notes importantes et une autre tiennent sous 120 |
| Résumé | Une phrase qui nomme le budget et la couleur à éviter |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Décider ce qui vaut d’être retenu
Gardez ce dont la prochaine étape a besoin. Il s’agit de la demande, des limites fixées, des décisions prises et des faits rendus par un outil. Écartez les politesses et les sorties brutes d’outils.
Gardez les notes importantes mot pour mot. Un résumé est écrit par un modèle et peut changer un chiffre. Résumez le bavardage et épinglez les faits, c’est-à-dire gardez-les mot pour mot.
Une erreur fréquente
Attention
Beaucoup pensent qu’une mémoire plus grande fait un meilleur agent. La mémoire se paie à chaque étape et les vieilles notes peuvent tromper. Gardez ce dont la prochaine étape a besoin, avec une limite de taille et un moyen d’oublier.