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

Aiguiller des requêtes entre plusieurs modèles

Après cette leçon: Je peux aiguiller chaque requête vers le modèle le moins cher qui suffit et vérifier ce choix sur des cas enregistrés.

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

Envoyer chaque requête au moins cher qui suffit

Aiguiller les modèles, c’est choisir, pour chaque requête, le modèle le moins cher qui suffit. C’est utile parce que le plus cher coûte plusieurs fois le plus petit, et que la plupart des requêtes n’en ont pas besoin.

Un outil d’assistance classe des tickets, répond à des questions courtes et rédige de longues réponses. Classer n’exige pas le modèle qui rédige. Tout envoyer à un grand modèle paie une puissance que presque aucune requête n’emploie.

À la fin de cette leçon

Remarque

Je peux aiguiller chaque requête vers le modèle le moins cher qui suffit et vérifier ce choix sur des cas enregistrés.

Mots clés

MotCe que ça veut dire
Aiguilleurla règle qui choisit un modèle pour une requête
Niveauun groupe de modèles par taille et par prix
Suffisantjuste assez souvent pour cette tâche
Cas enregistréune requête avec le niveau choisi par une personne
Désaccordun cas où l’aiguilleur et la personne diffèrent
Enveloppele code autour d’un appel qui y ajoute les règles

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

Un aiguilleur est une règle simple

Commencez par une règle lisible. Un texte court ou une tâche de classement va au niveau petit. Un texte long ou une tâche de raisonnement va au niveau grand. Le reste va au niveau moyen.

Une règle sur la taille et la tâche est bon marché, instantanée et facile à expliquer. On peut aussi demander à un petit modèle de choisir, mais cela ajoute un appel à chaque requête : essayez d’abord la règle.

Exemple détaillé : la règle sur quatre requêtes

RequêteTâcheTailleNiveau
Classer un ticketclasser150 signespetit
Résumer une pagerésumer1500 signesmoyen
Planifier une migrationraisonner900 signesgrand
Résumer un long rapportrésumer5000 signesgrand

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

Vérifier la règle sur des cas

Un aiguilleur fait économiser de l’argent et peut coûter de la qualité : testez-le. Gardez des cas enregistrés : une requête, sa taille et sa tâche, et le niveau qu’une personne juge nécessaire. Passez l’aiguilleur sur ces cas. Listez les désaccords et totalisez le coût.

Un désaccord n’est pas toujours un défaut de la règle. Lisez chacun. Puis changez la règle, ou changez le cas.

Une erreur courante

Attention

Beaucoup pensent que le modèle le moins cher est toujours la meilleure économie. Un modèle bon marché qui répond mal coûte un nouvel essai, une plainte ou un utilisateur perdu. Descendez de niveau seulement là où les cas enregistrés montrent que la réponse reste suffisante.

É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 la vérification, partie 1

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { demander } = require(\"./model\");' '' '// Prix inventés : des euros par million de jetons, donc jetons fois prix = micro-euros.' 'const PRIX = { petit: { entree: 1, sortie: 4 }, moyen: { entree: 3, sortie: 12 }, grand: { entree: 10, sortie: 40 } };' 'function aiguiller(requete) {' '  if (requete.tache === \"classer\" || requete.signes <= 200) return \"petit\";' '  if (requete.tache === \"raisonner\" || requete.signes > 2000) return \"grand\";' '  return \"moyen\";' '}' 'function cout(niveau, c) { return c.entree * PRIX[niveau].entree + c.sortie * PRIX[niveau].sortie; }' > route6.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 la vérification, partie 2

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' '// Des cas enregistrés : ce qu’est chaque requête, et le niveau qu’un relecteur juge nécessaire.' 'const CAS = [' '  { id: 1, tache: \"classer\", signes: 150, entree: 60, sortie: 5, attendu: \"petit\" },' '  { id: 2, tache: \"question\", signes: 180, entree: 70, sortie: 40, attendu: \"petit\" },' '  { id: 3, tache: \"resumer\", signes: 1500, entree: 500, sortie: 150, attendu: \"moyen\" },' '  { id: 4, tache: \"raisonner\", signes: 900, entree: 400, sortie: 600, attendu: \"grand\" },' '];' >> route6.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 la vérification, partie 3

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const SUITE = [' '  { id: 5, tache: \"resumer\", signes: 5000, entree: 1400, sortie: 300, attendu: \"grand\" },' '  { id: 6, tache: \"classer\", signes: 3000, entree: 800, sortie: 5, attendu: \"petit\" },' '  { id: 7, tache: \"question\", signes: 700, entree: 250, sortie: 120, attendu: \"moyen\" },' '  { id: 8, tache: \"resumer\", signes: 190, entree: 80, sortie: 30, attendu: \"moyen\" },' '];' >> route6.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 la vérification, partie 4

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' '  const tous = CAS.concat(SUITE);' '  let total = 0, cher = 0, ecarts = [];' '  for (const c of tous) {' '    const niveau = aiguiller(c);' '    total = total + cout(niveau, c);' '    cher = cher + cout(\"grand\", c);' '    if (niveau === c.attendu) console.log(\"#\" + c.id + \" \" + c.tache + \" : \" + niveau + \" ok\");' '    else { ecarts.push(c.id); console.log(\"#\" + c.id + \" \" + c.tache + \" : \" + niveau + \", attendu \" + c.attendu); }' '  }' '  console.log(\"Désaccords : \" + ecarts.length + \" sur \" + tous.length + \", cas \" + ecarts.join(\", \"));' '  console.log(\"Coût aiguillé : \" + total + \". Tout sur grand : \" + cher + \". Économisé : \" + (cher - total));' >> route6.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 la vérification, partie 5

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' '  const r = await demander([{ role: \"user\", content: \"Classe en facturation, bogue ou autre : j’ai été débité deux fois.\" }], \"facturation\", 10);' '  console.log(\"Aiguillé vers \" + aiguiller(tous[0]) + \", réponse : \" + r.texte.slice(0, 40));' '}' 'main();' >> route6.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 la vérification

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

Le labo n’a qu’un modèle

Dans le labo, un seul modèle répond quel que soit le niveau choisi par la règle, et la plateforme le choisit. Le Run montre donc le choix et le coût, et l’unique appel réel montre seulement qu’une requête aiguillée reçoit une réponse.

Les prix et les huit cas sont inventés et enregistrés, donc chaque étudiant affiche les mêmes lignes.

Une sortie possible

LigneCe qu’elle montre
#1 classer : petit okL’aiguilleur et la personne sont d’accord
#8 resumer : petit, attendu moyenUn désaccord à lire et à trancher
Désaccords : 1 sur 8, cas 8Le nombre et les numéros de cas
Coût aiguillé : 60820. Tout sur grand : 85600. Économisé : 24780Le total, en micro-euros
Aiguillé vers petit, réponse : ...Un appel réel. Les mots changent à chaque Run

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.