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

Envoyer une image à un modèle

Après cette leçon: Je peux construire une requête qui porte une image, et refuser un fichier qui enfreint une règle avant de l’envoyer.

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

Un utilisateur envoie vacances.png

Un utilisateur ajoute un fichier nommé vacances.png dans votre zone de discussion. Vous ne savez pas ce qu’il contient. Ce peut être une photo, ou un programme qui porte un nom d’image.

Envoyer une image à un modèle sans danger, c’est la vérifier avant qu’elle quitte votre serveur. Cette leçon montre les contrôles.

À la fin de cette leçon

Remarque

Je peux construire une requête qui porte une image, et refuser un fichier qui enfreint une règle avant de l’envoyer.

Mots clés

MotCe que ça veut direExemple
Base64une façon d’écrire des octets avec des lettres et des chiffres
Type de médiaune étiquette qui dit quelle sorte de fichier c’estimage/png
Premiers octetsle début d’un fichier, qui dit ce qu’il est vraiment
Charge utileles données que porte une requête
Limitele maximum que le service accepte

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

Une image voyage sous forme de texte

Une requête est en général du texte, mais une image est faite d’octets. Le base64 transforme chaque groupe de 3 octets en 4 caractères simples. La requête reste ainsi du texte.

Cela a un prix. Le texte est d’un tiers plus long que les octets. Une limite sur les octets n’est donc pas une limite sur la requête.

Comment le base64 agrandit un fichier

OctetsCaractèresPourquoi
34Un groupe de 3 devient 4
48Un deuxième groupe est entamé
2840Dix groupes de 4
3 0004 000Environ un tiers de plus

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

Fiez-vous aux premiers octets, pas au nom

Un nom n’est que ce que quelqu’un a tapé. Les premiers octets d’un fichier sont fixés par son format. Un PNG commence toujours par les mêmes 8 octets, un JPEG par 3.

Décidez donc du type de média en lisant les premiers octets. Si le nom n’est pas d’accord, refusez le fichier ou au moins signalez-le.

Une erreur courante

Attention

Beaucoup se fient au nom du fichier et au type que signale le navigateur. Les deux sont tapés par l’expéditeur. Contrôlez les premiers octets sur votre propre serveur : un programme nommé vacances.png passerait un contrôle fait sur le nom.

Contrôler d’abord, envoyer ensuite

Faites tous les contrôles avant qu’un seul octet parte. Rassemblez tous les problèmes dans une liste, dans un ordre fixe, pour que l’utilisateur corrige tout d’un coup. Seul un fichier sans problème est encodé et mis dans la charge utile.

Un appel refusé fait perdre du temps, et le modèle ne voit jamais un fichier que vous n’avez pas contrôlé.

É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 de contrôle, partie 1

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { demander } = require(\"./model\");' 'const entete = [137, 80, 78, 71, 13, 10, 26, 10];' 'const png = Buffer.concat([Buffer.from(entete), Buffer.alloc(40, 7)]);' 'const faux = Buffer.concat([Buffer.from(\"MZ\"), Buffer.alloc(40, 7)]);' 'const enorme = Buffer.concat([Buffer.from(entete), Buffer.alloc(142, 7)]);' 'const LIMITE = 100;' > envoi2.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 de contrôle, partie 2

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function flairer(b) {' '  if (b.length >= 8 && b[0] === 137 && b[1] === 80 && b[2] === 78 && b[3] === 71) return \"png\";' '  if (b.length >= 3 && b[0] === 255 && b[1] === 216 && b[2] === 255) return \"jpeg\";' '  return \"inconnu\";' '}' 'function verifier(b) {' '  const problemes = [];' '  if (b.length > LIMITE) problemes.push(\"trop gros\");' '  if (flairer(b) === \"inconnu\") problemes.push(\"type refusé\");' '  return problemes;' '}' >> envoi2.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 de contrôle, partie 3

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function afficher(liste) {' '  for (const element of liste) {' '    const b = element[1];' '    console.log(element[0] + \" : \" + flairer(b) + \", \" + b.length + \" octets, base64 \" + b.toString(\"base64\").length + \" caractères\");' '    console.log(\"  problèmes : \" + JSON.stringify(verifier(b)));' '  }' '  const partie = { type: \"image\", media_type: \"image/png\", data: png.toString(\"base64\").slice(0, 12) + \"...\" };' '  console.log(JSON.stringify({ messages: [{ role: \"user\", content: [{ type: \"text\", text: \"Décrivez-la.\" }, partie] }] }));' '}' >> envoi2.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 de contrôle, partie 4

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' '  afficher([[\"chaton.png\", png], [\"devoirs.png\", faux], [\"enorme.png\", enorme]]);' '  const q = \"Écrivez une phrase courte et aimable qui dit à un utilisateur que son image est trop grosse pour être envoyée.\";' '  const reponse = await demander([{ role: \"user\", content: q }], \"Cette image est trop grosse pour être envoyée, merci d’en choisir une plus petite.\", 40);' '  console.log(\"réponse : \" + reponse.texte);' '}' 'main();' >> envoi2.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.

Contrôler trois fichiers

Commande
docker exec -w /home/node/project agent node envoi2.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 lignes affichées

LigneCe qu’elle montre
chaton.png : png, 48 octets, base64 64 caractèresDe vrais octets PNG : 48 octets sont devenus 64 caractères
devoirs.png : inconnu ... type refuséLe nom dit png, les octets non
enorme.png : png, 150 octets ... trop grosLe bon type, mais au-dessus de la limite de 100
{"messages":[...]}Le corps de la requête, avec les données coupées

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.