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

Mettre en cache les réponses d’un modèle

Après cette leçon: Je peux mettre des réponses de modèle en cache sans risque et dire exactement ce qui fait qu’une entrée est trouvée.

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

Ne pas payer deux fois la même réponse

Mettre en cache une réponse de modèle, c’est la ranger puis la rendre pour la même requête plus tard. C’est utile parce qu’un appel coûte de l’argent et des secondes, et que beaucoup de requêtes se répètent.

Une page d’aide demande au modèle de résumer la même politique de retour pour chaque visiteur. Mille appels paient mille fois la même réponse. Un appel et neuf cent quatre-vingt-dix-neuf réponses trouvées dans le cache, non.

À la fin de cette leçon

Remarque

Je peux mettre des réponses de modèle en cache sans risque et dire exactement ce qui fait qu’une entrée est trouvée.

Mots clés

MotCe que ça veut dire
Cacheun stock de réponses déjà payées
Clé de cachela valeur qui décide si deux requêtes se ressemblent
Entrée trouvéeune requête servie depuis le cache
Entrée absenteune requête qui doit appeler le modèle
Expirationle moment où une entrée est retirée
Donnée personnelletout ce qui identifie une personne

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

La clé couvre toute la requête

Deux requêtes ne partagent une réponse que si le modèle voit la même chose. La clé de cache couvre donc tout ce qui change la réponse. C’est le modèle, chaque message avec son rôle, et les paramètres comme la température et la limite de réponse.

Oubliez un élément, et vous servez la mauvaise réponse. Un hachage de ce texte garde la clé courte.

Exemple détaillé : ce qui change la clé

ChangementMême clé ?Pourquoi
Même modèle, mêmes messages et paramètresOuiLe modèle voit la même requête
Un mot de différence dans un messageNonLes messages font partie de la clé
Température 0, puis 1NonLes réponses peuvent différer
Un autre modèleNonUn autre modèle répond autrement

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

Les entrées expirent, le personnel reste dehors

Une réponse vieillit. Donnez à chaque entrée une expiration : une durée de vie en secondes. Ensuite l’entrée est retirée et la requête suivante est absente du cache.

Ne mettez jamais en cache ce qui est personnel. Une réponse construite avec l’adresse ou la commande d’un utilisateur pourrait être donnée au suivant qui a la même clé. Examinez la requête avant la recherche, et n’utilisez pas le cache pour elle.

Une erreur courante

Attention

Beaucoup pensent que le cache est toujours sans risque, puisque la réponse n’est que du texte. Une réponse en cache qui contient les détails d’une personne peut être montrée à une autre. Décidez ce qui peut être mis en cache avant d’en ranger une seule.

É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 cache, partie 1

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const crypto = require(\"crypto\");' 'const { demander } = require(\"./model\");' '' 'let maintenant = 0; // des secondes, sur une horloge que nous avançons nous-mêmes' 'const DUREE_DE_VIE = 60; // une entrée vit 60 secondes' 'const cache = new Map();' > cache2.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 cache, partie 2

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' '// La clé est construite sur toute la requête : modèle, messages et paramètres.' 'function cleDe(requete) {' '  const tout = JSON.stringify([requete.modele, requete.messages, requete.temperature, requete.max_tokens]);' '  return crypto.createHash(\"sha256\").update(tout).digest(\"hex\").slice(0, 12);' '}' '// Une donnée personnelle n’est jamais mise en cache. Ici : une adresse ou un long nombre.' 'function personnelle(requete) {' '  return /@|[0-9]{7,}/.test(JSON.stringify(requete.messages));' '}' >> cache2.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 cache, partie 3

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function repondre(requete, echantillon) {' '  if (personnelle(requete)) return \"ignorée, personnelle\";' '  const cle = cleDe(requete);' '  const trouve = cache.get(cle);' '  if (trouve && trouve.expire > maintenant) return \"trouvé\";' '  const reponse = await demander(requete.messages, echantillon, requete.max_tokens);' '  cache.set(cle, { texte: reponse.texte, expire: maintenant + DUREE_DE_VIE });' '  return trouve ? \"périmé, absent\" : \"absent\";' '}' >> cache2.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 cache, partie 4

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' '  const conseil = [{ role: \"user\", content: \"Donne un conseil sur le cache, en une phrase.\" }];' '  const base = { modele: \"lab\", temperature: 0, max_tokens: 40, messages: conseil };' '  const autre = { ...base, temperature: 1 };' '  const secret = { ...base, messages: [{ role: \"user\", content: \"Écris à [email protected] un conseil.\" }] };' '  const echantillon = \"Ne mettez en cache que ce qui est identique pour tous.\";' '  for (const a of [0, 30, 90]) {' '    maintenant = a;' '    console.log(\"t=\" + a + \" s : \" + (await repondre(base, echantillon)));' '  }' '  console.log(\"même clé avec une autre température : \" + (cleDe(base) === cleDe(autre)));' '  console.log(\"requête personnelle : \" + (await repondre(secret, echantillon)));' '}' 'main();' >> cache2.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 le cache

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

Ceci est une maquette

Le labo n’a pas de serveur de cache. Le cache est donc une Map dans le script, et l’horloge est un nombre que le script fixe. Un vrai système utilise un vrai service de cache, partagé par tous les serveurs.

Les règles restent les mêmes : une clé sur toute la requête, une expiration, et un contrôle des données personnelles.

Une sortie possible

LigneCe qu’elle montre
t=0 s : absentLa première requête appelle le modèle
t=30 s : trouvéLa même requête, servie depuis le cache
t=90 s : périmé, absentL’entrée avait 60 secondes, le modèle est rappelé
même clé avec une autre température : falseUn nouveau paramètre est une nouvelle clé
requête personnelle : ignorée, personnelleLe cache n’a pas été touché

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.