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

Disjoncteurs et replis maîtrisés

Après cette leçon: Je peux garder une fonction utile pendant que son modèle échoue.

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

Comment fonctionne un disjoncteur

Un disjoncteur est une petite règle qui cesse d’appeler un service qui échoue sans cesse. Tant qu’il est ouvert, la fonction utilise un repli au lieu d’attendre un appel qui échouera.

Le module sur le coût, le traçage et la fiabilité liste les replis. Cette leçon va plus loin : quand arrêter d’appeler, quand réessayer, et un interrupteur d’urgence qu’une personne peut presser.

À la fin de cette leçon

Remarque

Je peux garder une fonction utile pendant que son modèle échoue.

Mots clés

MotCe que ça veut direExemple
Disjoncteurune règle qui arrête les appels à un service en échec
Fermél’état normal : les appels passent
Ouvertl’état d’arrêt : aucun appel, un repli répond
Semi-ouvertun appel d’essai pour voir si le service est revenu
Reposles pas à attendre avant un essai4
Interrupteur d’urgenceune commande qui coupe une fonction aussitôt

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

Trois états

Un disjoncteur est fermé quand tout va bien. Les appels passent. Il compte les échecs d’affilée. Quand le compte atteint le seuil, ici 3, il s’ouvre.

Ouvert, il ne fait aucun appel. Après le repos, ici 4 pas, il devient semi-ouvert et laisse passer un appel. Un succès le ferme. Un échec le rouvre.

Exemple détaillé : les pas 3 à 9

PasL’appelÉtat trouvéServiPourquoi
3ÉchoueraitFerméÉchouéPremier échec d’affilée, compte 1
4ÉchoueraitFerméÉchouéCompte 2
5ÉchoueraitFerméÉchouéLe compte atteint 3, donc il s’ouvre
6MarcheraitOuvertIgnoréAucun appel. 1 pas depuis l’ouverture
7MarcheraitOuvertIgnoré2 pas depuis l’ouverture
8MarcheraitOuvertIgnoré3 pas depuis l’ouverture
9MarcheraitSemi-ouvertModèle4 pas, l’essai marche, donc il se ferme

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

Une erreur courante

Attention

Beaucoup pensent qu’un disjoncteur doit s’ouvrir au premier échec. Un seul échec est souvent un accident. Comptez les échecs d’affilée et laissez un succès remettre le compte à zéro, sinon un service sain est coupé par un seul mauvais appel.

Ce que dit le repli

Un repli doit être honnête et utile. Le meilleur est une réponse enregistrée à la même question. S’il n’y en a pas, dites simplement que l’assistant est occupé et quand réessayer.

N’affichez jamais une réponse inventée comme si le modèle l’avait donnée.

L’interrupteur d’urgence est une décision humaine

Un disjoncteur réagit aux échecs. Une personne presse l’interrupteur d’urgence quand le modèle marche mais ne doit pas servir. Il peut donner de mauvaises réponses, ou coûter trop cher.

Tant qu’il est actif, chaque appel est ignoré. Il ne touche pas au disjoncteur, qui garde son propre compte et son propre état.

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

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { demander } = require(\"./model\");' 'function pas(b, issue, i, seuil, repos, coupure) {' '  if (coupure) return [b.etat, \"ignore\"];' '  if (b.etat === \"ouvert\" && i - b.ouvertA >= repos) b.etat = \"semi_ouvert\";' '  const trouve = b.etat;' '  if (trouve === \"ouvert\") return [trouve, \"ignore\"];' '  if (issue === 1) { b.etat = \"ferme\"; b.echecs = 0; return [trouve, \"modele\"]; }' '  b.echecs = b.echecs + 1;' '  if (trouve === \"semi_ouvert\" || b.echecs >= seuil) { b.etat = \"ouvert\"; b.ouvertA = i; b.echecs = 0; }' '  return [trouve, \"echoue\"];' '}' > disjoncteur.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 du disjoncteur, partie 2

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const issues = [1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1];' 'function derouler(coupures) {' '  const b = { etat: \"ferme\", echecs: 0, ouvertA: 0 };' '  return issues.map(function (o, k) {' '    const r = pas(b, o, k + 1, 3, 4, coupures.includes(k + 1));' '    return r[0] + \":\" + r[1];' '  });' '}' >> disjoncteur.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 du disjoncteur, partie 3

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' '  const trace = derouler([]);' '  console.log(trace.slice(0, 10).join(\" \"));' '  console.log(trace.slice(10).join(\" \"));' '  const faits = trace.filter(function (t) { return t.endsWith(\"ignore\") === false; }).length;' '  console.log(\"appels faits \" + faits + \" sur \" + trace.length);' '  console.log(\"coupure 9 et 10 : \" + derouler([9, 10]).slice(8, 11).join(\" \"));' '  const q = \"En une phrase courte, que doit dire une fonction quand son modèle est en panne ?\";' '  const reponse = await demander([{ role: \"user\", content: q }], \"Dire simplement que l’assistant est occupé, et proposer une réponse enregistrée ou une autre voie.\", 60);' '  console.log(\"le modèle dit : \" + reponse.texte);' '}' 'main();' >> disjoncteur.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 disjoncteur

Commande
docker exec -w /home/node/project agent node disjoncteur.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
ferme:modele ferme:modele ferme:echoue ...Les pas 1 à 10, l’état trouvé et comment l’appel a été servi
ouvert:ignore ouvert:ignore ouvert:ignore semi_ouvert:modeleLe disjoncteur s’ouvre, attend, et un essai marche
appels faits 14 sur 20Six appels ont été économisés
coupure 9 et 10 : ouvert:ignore ouvert:ignore semi_ouvert:modeleL’interrupteur a ignoré deux pas et le repos a continué
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.