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

Pannes des systèmes multi-agents

Après cette leçon: Je peux trouver la panne dans une transcription et nommer son genre.

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

Une équipe tombe en panne autrement

Une panne multi-agents est une façon dont une équipe d’agents déraille, alors qu’aucun agent seul ne le ferait. Cela compte, car la faute est dans la conversation entre eux, et chaque agent paraît correct isolément.

On la trouve en lisant la transcription, la liste des messages qu’ils ont envoyés.

À la fin de cette leçon

Remarque

Je peux trouver la panne dans une transcription et nommer son genre.

Mots-clés

MotCe que ça veut dire
Transcriptionles messages envoyés par les agents, dans l’ordre
Bouclele même message envoyé encore et encore
Interblocagedeux agents qui attendent chacun l’autre
Dérive du coûtune consommation de jetons qui dépasse le budget
Transmiseune hypothèse qui est reprise plus tard comme un fait
Garde-fouune règle dans le code qui arrête une panne tôt

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

Quatre façons de dérailler pour une équipe

Une boucle répète un seul message. Un interblocage met deux agents à attendre chacun que l’autre commence. Une dérive du coût grandit, car chaque tour relit tout l’historique.

La quatrième est plus discrète. Un exécutant devine, l’agent suivant répète l’hypothèse, et au troisième elle est écrite comme un fait.

Exemple travaillé : le signe et le garde-fou

PanneSigne dans une transcriptionGarde-fou
BoucleMêmes émetteur, destinataire et texte trois foisS’arrêter à la troisième répétition
InterblocageDeux messages qui disent tous deux attente, échangésUne limite de temps et un départage
TransmiseUne hypothèse, puis les mêmes mots comme un faitFaire voyager le statut avec l’affirmation
DériveDes jetons par tour qui ne cessent de monterUn budget pour toute l’exécution

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

Contrôlez d’abord le signe le plus net

Une vraie transcription peut montrer plusieurs signes. Fixez un ordre et gardez-le. Un interblocage et une boucle arrêtent tous deux le travail, nommez-les donc avant le coût.

Le module précédent traitait le garde-fou de boucle. Cette leçon apprend à reconnaître les quatre, pour savoir quel garde-fou ajouter.

Une erreur fréquente

Attention

Beaucoup ajoutent une nouvelle tentative quand une équipe cale. Elle allonge une boucle et ne raccourcit pas un interblocage. Nommez d’abord la panne, puis choisissez le garde-fou qui lui convient.

É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 détecteur de pannes, partie 1

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { demander } = require(\"./model\");' 'function m(de, vers, texte, jetons, statut) {' '  return { de: de, vers: vers, texte: texte, jetons: jetons, statut: statut };' '}' 'const T = {};' 'T.boucle = [m(\"auteur\", \"relecteur\", \"relis le brouillon\", 300, \"aucun\"), m(\"relecteur\", \"auteur\", \"ajoute une source\", 200, \"aucun\"),' '    m(\"auteur\", \"relecteur\", \"relis le brouillon\", 300, \"aucun\"), m(\"relecteur\", \"auteur\", \"ajoute une source\", 200, \"aucun\"),' '    m(\"auteur\", \"relecteur\", \"relis le brouillon\", 300, \"aucun\")];' 'T.interblocage = [m(\"planificateur\", \"verificateur\", \"attente de la relecture avant de planifier\", 150, \"aucun\"),' '  m(\"verificateur\", \"planificateur\", \"attente du plan avant de relire\", 150, \"aucun\")];' > panne.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 détecteur de pannes, partie 2

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'T.transmise = [m(\"lecteur\", \"planificateur\", \"les visites du samedi ont monté de 40 pour cent\", 200, \"hypothese\"),' '  m(\"planificateur\", \"auteur\", \"les visites du samedi ont monté de 40 pour cent\", 200, \"fait\")];' 'T.derive = [m(\"a\", \"b\", \"tour un\", 1000, \"aucun\"), m(\"b\", \"a\", \"tour deux\", 2000, \"aucun\"), m(\"a\", \"b\", \"tour trois\", 4000, \"aucun\"),' '  m(\"b\", \"a\", \"tour quatre\", 8000, \"aucun\"), m(\"a\", \"b\", \"tour cinq\", 16000, \"aucun\")];' 'T.correct = [m(\"planificateur\", \"lecteur\", \"cherche la demande du dimanche\", 200, \"aucun\"), m(\"lecteur\", \"planificateur\", \"212 sur 400\", 150, \"fait\")];' >> panne.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 détecteur de pannes, partie 3

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function deux(ms, essai) {' '  return ms.some(function (x, i) { return ms.some(function (y, j) { return i < j && essai(x, y); }); });' '}' 'function interblocage(ms) {' '  return deux(ms, function (x, y) {' '    return x.texte.startsWith(\"attente\") && y.texte.startsWith(\"attente\") && x.de === y.vers && x.vers === y.de;' '  });' '}' 'function boucle(ms) {' '  return ms.some(function (x) {' '    return ms.filter(function (y) { return y.de === x.de && y.vers === x.vers && y.texte === x.texte; }).length >= 3;' '  });' '}' >> panne.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 détecteur de pannes, partie 4

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function transmise(ms) {' '  return deux(ms, function (x, y) { return x.statut === \"hypothese\" && y.statut === \"fait\" && x.texte === y.texte; });' '}' 'function total(ms) { return ms.reduce(function (a, x) { return a + x.jetons; }, 0); }' 'function trouver(ms, budget) {' '  if (interblocage(ms)) return \"interblocage\";' '  if (boucle(ms)) return \"boucle\";' '  if (transmise(ms)) return \"hypothese-transmise\";' '  return total(ms) > budget ? \"derive-du-cout\" : \"aucune\";' '}' >> panne.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 détecteur de pannes, partie 5

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' '  for (const nom of Object.keys(T)) {' '    console.log(nom + \" : \" + T[nom].length + \" messages, \" + total(T[nom]) + \" jetons, trouvé \" + trouver(T[nom], 20000));' '  }' '  const q = [{ role: \"user\", content: \"En une phrase : quelle règle simple empêche deux agents de s’envoyer le même message sans fin ?\" }];' '  const r = await demander(q, \"Compter chaque message et s’arrêter à la troisième répétition.\", 40);' '  console.log(\"Modèle : \" + r.texte.trim());' '}' 'main();' >> panne.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 détecteur de pannes

Commande
docker exec -w /home/node/project agent node panne.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 sont des transcriptions enregistrées

Un vrai essai dépenserait le quota du labo sur une seule équipe en panne. Les cinq transcriptions sont donc des données enregistrées, courtes et inventées. Le détecteur est du vrai code.

Le seul appel en direct demande une règle. Ses mots changent à chaque exécution.

Une sortie possible

LigneCe qu’elle montre
boucle : 5 messages, 1300 jetons, trouvé boucleUn message trois fois
interblocage : 2 messages, 300 jetons, trouvé interblocageChacun attend l’autre
transmise : 2 messages, 400 jetons, trouvé hypothese-transmiseUne hypothèse est devenue un fait
derive : 5 messages, 31000 jetons, trouvé derive-du-coutAu-dessus du budget de 20000
correct : 2 messages, 350 jetons, trouvé aucuneAucun signe de panne

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.