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

Agents orchestrateur et exécutants

Après cette leçon: Je peux découper une tâche en consignes autonomes et vérifier chaque résultat avant de les rassembler.

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

Un exécutant ne connaît que sa consigne

Le schéma orchestrateur-exécutants est un programme où un agent découpe une tâche en consignes, confie chacune à un exécutant et rassemble les résultats. Cela compte, car un exécutant ne sait rien d’autre que sa consigne.

Une consigne vague donne une réponse assurée à la mauvaise question. Une consigne autonome donne une réponse vérifiable.

À la fin de cette leçon

Remarque

Je peux découper une tâche en consignes autonomes et vérifier chaque résultat avant de les rassembler.

Mots-clés

MotCe que ça veut dire
Consignetout ce qu’un exécutant reçoit : question, matériel et forme de la réponse
Forme du résultatles champs qu’un exécutant doit renvoyer
Matérielle texte qu’un exécutant peut utiliser pour répondre
Validationla vérification d’un résultat avant son emploi
Jointurel’assemblage des résultats acceptés
Source inconnueune source citée par un exécutant mais jamais donnée

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

Ce que contient une consigne

Un exécutant ne voit ni la tâche, ni les autres consignes, ni la conversation. Ce qui n’est pas dans la consigne n’existe pas.

Une consigne contient donc la question, le matériel autorisé, la forme de la réponse et une limite de taille. Le matériel est le texte lui-même, pas la promesse que l’exécutant ira le chercher.

Exemple travaillé : une consigne

ChampExemplePourquoi il est là
questionQue coûterait un dimanche en temps de personnel ?Une question, pas toute la tâche
matérielLa fiche de coût du personnel, en texteL’exécutant ne peut rien utiliser d’autre
sourcess2Pour que la réponse dise d’où elle vient
réponseUn objet avec réponse et sourcesPour que l’orchestrateur la vérifie

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

Validez un résultat avant de le joindre

Un résultat est une donnée venue d’une partie du système que vous ne contrôlez pas. Vérifiez d’abord la forme : y a-t-il une réponse, une liste de sources ? Puis vérifiez que chaque source figure dans la consigne.

Ne joignez que ce qui passe. Le module précédent faisait passer un message d’un agent à l’autre. Ici, on décide s’il faut croire ce qui revient.

Une erreur fréquente

Attention

Beaucoup joignent tous les résultats et réparent le désordre ensuite. Un mauvais résultat pèse alors autant qu’un bon dans la réponse finale. Refusez à l’entrée et gardez la raison.

É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 l’orchestrateur, partie 1

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { demander } = require(\"./model\");' 'const SOURCES = {' '  s1: \"Sondage : 212 visiteurs sur 400 ont demandé l’ouverture le dimanche.\",' '  s2: \"Personnel : six heures à 18 euros de l’heure font 108 euros chaque dimanche.\",' '  s3: \"Visites : le samedi a compté 310 visites le mois dernier, un jour de semaine 120.\",' '};' '// Une consigne porte tout ce que son exécutant peut utiliser : la question et le texte.' 'function consigne(id, question, ids) {' '  const materiel = ids.map(function (i) { return SOURCES[i]; });' '  return { id: id, question: question, sources: ids, materiel: materiel, reponse: \"un objet avec reponse et sources\" };' '}' > equipe.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’orchestrateur, partie 2

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' '// Des exécutants scriptés. Chacun ne voit que sa consigne.' 'const EXECUTANTS = {' '  b1: function (c) { return { reponse: \"212 visiteurs sur 400 la veulent\", sources: [\"s1\"] }; },' '  b2: function (c) { return { reponse: \"108 euros chaque dimanche\", sources: [\"s2\"] }; },' '  b3: function (c) { return { reponse: \"Les week-ends sont chargés\", sources: [\"s9\"] }; },' '};' 'function problemes(c, r) {' '  const sortie = [];' '  const plein = typeof r.reponse === \"string\" && r.reponse.trim().length > 0;' '  if (plein === false) sortie.push(\"réponse absente\");' '  if (Array.isArray(r.sources) === false || r.sources.length === 0) sortie.push(\"sources absentes\");' '  else r.sources.forEach(function (s) { if (c.sources.includes(s) === false) sortie.push(\"source inconnue \" + s); });' '  return sortie;' '}' >> equipe.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’orchestrateur, partie 3

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' '  const propre = \"Quelle est l’affluence de la bibliothèque un jour de week-end ?\";' '  const q = [{ role: \"user\", content: \"Écrivez une courte question de recherche sur l’affluence d’une bibliothèque le week-end.\" }];' '  const texte = (await demander(q, propre, 30)).texte.trim();' '  const consignes = [' '    consigne(\"b1\", \"Combien de visiteurs veulent l’ouverture le dimanche ?\", [\"s1\"]),' '    consigne(\"b2\", \"Que coûterait un dimanche en temps de personnel ?\", [\"s2\"]),' '    consigne(\"b3\", texte.endsWith(\"?\") ? texte : propre, [\"s3\"]),' '  ];' '  for (const c of consignes) {' '    const r = EXECUTANTS[c.id](c);' '    const p = problemes(c, r);' '    console.log(c.id + \" [\" + c.materiel.length + \" source] \" + c.question);' '    console.log(\"   \" + (p.length ? \"REFUSÉE : \" + p.join(\", \") : \"acceptée : \" + r.reponse));' '  }' '}' 'main();' >> equipe.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’orchestrateur

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

Les exécutants sont scriptés

Le labo n’a qu’un modèle, donc une vraie équipe serait un seul modèle jouant tous les rôles. Les trois exécutants ici sont de simples fonctions aux réponses enregistrées. Le seul appel en direct formule une question de recherche.

Un vrai système envoie chaque consigne à un modèle, et la vérification reste la même.

Une sortie possible

LigneCe qu’elle montre
b1 [1 source] Combien de visiteurs veulent l’ouverture le dimanche ?Une consigne avec son matériel
acceptée : 212 visiteurs sur 400 la veulentLa forme et les sources passent
acceptée : 108 euros chaque dimancheLe deuxième exécutant passe aussi
REFUSÉE : source inconnue s9Le troisième cite une source qu’il n’a jamais reçue

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.