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

Construire une équipe de recherche d’agents

Après cette leçon: Je peux faire tourner un orchestrateur et des exécutants avec un budget, un contrôle et une règle d’arrêt.

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

Assembler l’équipe

Une équipe de recherche d’agents est un orchestrateur, quelques exécutants, un contrôle de chaque résultat et une règle d’arrêt. Cela compte, car chaque élément vu jusqu’ici a un coût, et une équipe sans limite n’a pas de fin.

Cette leçon relie le module en une seule boucle, avec un budget de jetons.

À la fin de cette leçon

Remarque

Je peux faire tourner un orchestrateur et des exécutants avec un budget, un contrôle et une règle d’arrêt.

Mots-clés

MotCe que ça veut dire
Budgetle maximum de jetons qu’une exécution entière peut dépenser
Règle d’arrêtun test qui termine l’exécution avant la fin des consignes
Acceptéun résultat qui a passé tous les contrôles
Refuséun résultat écarté, avec ses raisons
Dépenséles jetons utilisés jusqu’ici, bons résultats et mauvais
Assezle nombre de résultats acceptés qui termine l’exécution

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

Une boucle, trois limites

L’orchestrateur prend les consignes dans l’ordre. Avant chacune, il pose deux questions. En ai-je déjà assez ? Cette consigne pourrait-elle me faire dépasser le budget ?

Puis il interroge l’exécutant et vérifie le résultat. Chaque réponse se paie, donc la dépense compte les bonnes comme les mauvaises.

Exemple travaillé : un tour de boucle

ÉtapeQuestionSi oui
1Assez de résultats sont-ils acceptés ?Arrêt, raison assez
2Dépense plus limite de cette consigne au-dessus du budget ?Arrêt, raison budget
3Interroger l’exécutant, ajouter ses jetons à la dépenseToujours, bon ou mauvais
4Le résultat passe-t-il le contrôle ?L’accepter, sinon le refuser avec ses raisons

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

Pourquoi une limite passe avant l’appel

Vérifier le budget après un appel est trop tard : les jetons sont partis. La boucle réserve donc le pire cas. Elle prend la limite de la consigne elle-même, et s’arrête si elle ne tiendrait pas.

Ce contrôle ne peut pas arrêter un exécutant qui dépasse sa propre limite. C’est ce qui arrive dans le premier Run. La même idée protège le temps et le nombre de tours.

Une erreur fréquente

Attention

Beaucoup ne comptent que les bons résultats dans le budget. Un exécutant qui échoue lit et écrit quand même des jetons. Comptez tout ce que l’exécution a demandé, sinon la facture ne correspondra pas au budget.

É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’équipe de recherche, partie 1

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { demander } = require(\"./model\");' 'const CONSIGNES = [' '  { id: \"b1\", question: \"Combien de visiteurs veulent l’ouverture le dimanche ?\", sources: [\"s1\"], max: 900 },' '  { id: \"b2\", question: \"Que coûterait un dimanche en temps de personnel ?\", sources: [\"s2\"], max: 900 },' '  { id: \"b3\", question: \"Quelle est l’affluence un jour de week-end ?\", sources: [\"s3\"], max: 900 },' '];' '// Les réponses de trois exécutants scriptés, enregistrées.' 'const ENREGISTRE = {' '  b1: { reponse: \"212 visiteurs sur 400 la veulent\", sources: [\"s1\"], jetons: 700 },' '  b2: { reponse: \"108 euros chaque dimanche\", sources: [\"s2\"], jetons: 850 },' '  b3: { reponse: \"310 visites un samedi\", sources: [\"s3\"], jetons: 1200 },' '};' > 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’équipe de recherche, partie 2

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function problemes(c, r) {' '  const sortie = [];' '  if (r.reponse.trim().length === 0) sortie.push(\"réponse absente\");' '  r.sources.forEach(function (s) { if (c.sources.includes(s) === false) sortie.push(\"source inconnue \" + s); });' '  if (r.jetons > c.max) sortie.push(\"hors limite\");' '  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’équipe de recherche, partie 3

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function equipe(budget, assez) {' '  const bilan = { acceptes: [], refuses: [], depense: 0, arret: \"fini\" };' '  for (const c of CONSIGNES) {' '    if (bilan.acceptes.length >= assez) { bilan.arret = \"assez\"; break; }' '    if (bilan.depense + c.max > budget) { bilan.arret = \"budget\"; break; }' '    const r = ENREGISTRE[c.id];' '    bilan.depense += r.jetons;' '    const p = problemes(c, r);' '    if (p.length > 0) bilan.refuses.push(c.id + \" (\" + p.join(\", \") + \")\");' '    else bilan.acceptes.push(r.reponse);' '  }' '  return bilan;' '}' >> 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’équipe de recherche, partie 4

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' '  let premier = null;' '  for (const essai of [[2500, 3], [1500, 3], [4000, 2]]) {' '    const b = equipe(essai[0], essai[1]);' '    premier = premier || b;' '    console.log(\"budget \" + essai[0] + \", assez \" + essai[1] + \" : acceptés \" + b.acceptes.length + \", refusés \" + b.refuses.length + \", dépensé \" + b.depense + \", arrêt \" + b.arret);' '    if (b.refuses.length > 0) console.log(\"   refusés : \" + b.refuses.join(\" ; \"));' '  }' '  const q = [{ role: \"user\", content: \"Écrivez une phrase à partir de ces constats : \" + premier.acceptes.join(\" ; \") }];' '  const r = await demander(q, \"Les visiteurs veulent l’ouverture le dimanche et elle coûte 108 euros par dimanche.\", 40);' '  console.log(\"Résumé : \" + r.texte.trim());' '}' '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’équipe de recherche

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 enregistrés

Les trois exécutants sont des réponses enregistrées, avec leur nombre de jetons, pour que chaque étudiant voie les mêmes totaux. Le seul appel en direct rédige un résumé de ce qui a été accepté.

Une vraie équipe enverrait chaque consigne à un modèle, et la boucle autour reste la même.

Une sortie possible

LigneCe qu’elle montre
budget 2500, assez 3 : acceptés 2, refusés 1, dépensé 2750, arrêt finiLa troisième réponse a coûté 1200 au lieu de 900 : la dépense dépasse donc le budget de 2500
refusés : b3 (hors limite)La raison est gardée
budget 1500, assez 3 : acceptés 1, refusés 0, dépensé 700, arrêt budgetLa deuxième consigne pouvait ne pas tenir
budget 4000, assez 2 : acceptés 2, refusés 0, dépensé 1550, arrêt assezDeux bons résultats suffisaient
Résumé : …Une phrase qui change à chaque exécution

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.