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

Modéliser les menaces d’un agent IA

Après cette leçon: Je peux cartographier où un agent peut être attaqué et nommer le mélange de trois éléments qui le rend dangereux.

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

Où peut-on attaquer un agent IA

Un modèle de menaces liste ce qu’un attaquant pourrait atteindre, et comment. Pour un agent, c’est plus important que pour un simple chat, car l’agent agit. Il lit le courrier, appelle des outils et envoie des choses à l’extérieur.

Le module « Sécuriser les applications LLM » vous a donné l’injection et les risques principaux. Cette leçon les transforme en carte d’un agent, dessinée avant d’écrire du code.

À la fin de cette leçon

Remarque

Je peux cartographier où un agent peut être attaqué et nommer le mélange de trois éléments qui le rend dangereux.

Mots clés

MotCe que ça veut direExemple
Actifce qui mérite d’être protégé, comme un fichier clients ou un outil de paiement
Frontière de confiancela ligne où du texte ou des appels passent d’une source que vous contrôlez à une autre que vous ne contrôlez pas
Contenu non fiabledu texte lu par l’agent qu’un inconnu a pu écrireune page web
Voie de sortietoute route par laquelle l’agent peut envoyer des données loin de son propriétaire
Jambel’un des trois éléments du mélange dangereux

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

Le mélange dangereux de trois éléments

Trois éléments réunis sont dangereux. L’agent détient des données privées. Il lit du contenu non fiable. Il a une voie de sortie pour envoyer des données ailleurs.

Avec deux éléments sur trois, l’attaque cale. Le texte peut orienter l’agent, mais rien ne sort, ou rien de privé n’est à prendre. Avec les trois, une seule ligne cachée peut faire sortir des données.

Exemple guidé : trois agents

AgentDonnées privéesContenu non fiableVoie de sortie
Résumé de courrierLa boîte mailCourrier d’inconnusAucune : il affiche seulement un résumé
Commis webAucuneN’importe quelle page webIl peut publier dans un salon
Aide de boîte mailLa boîte mailCourrier d’inconnusIl peut envoyer des réponses

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

Le Run liste les jambes, il n’attaque rien

Le premier script contient quatre agents inventés sous forme de simples données. Il affiche les jambes de chacun et marque ceux qui ont les trois.

Aucun modèle n’est appelé et aucune attaque n’est menée. Un modèle de menaces raisonne sur ce qui est possible, donc une liste dans un script suffit pour s’exercer.

Écrire le script des jambes, partie 1

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' '// Quatre agents inventés. Chaque drapeau dit ce que l’agent peut faire.' 'const agents = [' '  { nom: \"resume-courrier\", donnees: true, externe: true, sortie: false },' '  { nom: \"commis-web\", donnees: false, externe: true, sortie: true },' '  { nom: \"robot-rapports\", donnees: true, externe: false, sortie: true },' '  { nom: \"aide-boite\", donnees: true, externe: true, sortie: true },' '];' > jambes.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 des jambes, partie 2

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function jambes(a) {' '  const trouvees = [];' '  if (a.donnees) trouvees.push(\"données privées\");' '  if (a.externe) trouvees.push(\"contenu non fiable\");' '  if (a.sortie) trouvees.push(\"une voie de sortie\");' '  return trouvees;' '}' 'for (const a of agents) {' '  const toutes = jambes(a).length === 3;' '  console.log(a.nom + \" : \" + jambes(a).join(\", \") + (toutes ? \"  <- les trois\" : \"\"));' '}' >> jambes.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 script des jambes

Commande
docker exec -w /home/node/project agent node jambes.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 qu’affiche le script

LigneCe qu’elle montre
resume-courrier : données privées, contenu non fiableDeux jambes, et aucune voie de sortie
commis-web : contenu non fiable, une voie de sortieDeux jambes, et aucune donnée privée
robot-rapports : données privées, une voie de sortieDeux jambes, et seulement des entrées de confiance
aide-boite : les trois jambes, puis <- les troisLe seul agent à corriger en premier

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

Retirez une jambe, ne demandez pas poliment

La correction consiste à retirer une jambe. Supprimez la voie de sortie, ou ne lisez que des sources de confiance, ou gardez les données privées hors de portée. Choisissez la moins coûteuse.

Un prompt qui dit « ne divulgue jamais » n’est pas une correction. Il baisse les chances pour une exécution et ne garantit rien pour la suivante.

Une erreur fréquente

Attention

Beaucoup ne comptent comme entrée que ce que tape l’utilisateur. Chaque résultat d’outil, fichier, page et message précédent est aussi une entrée. Chacun est un endroit où un inconnu a pu écrire le texte.

Écrire le script du modèle, partie 1

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { demander } = require(\"./model\");' '' 'const texte = \"Un assistant lit la boîte mail des clients, la résume et peut publier un lien dans un salon de discussion public.\";' 'const messages = [' '  { role: \"system\", content: \"Réponds par exactement trois lignes. La ligne 1 commence par donnees:, la ligne 2 par externe:, la ligne 3 par sortie:. Après les deux-points, écris oui ou non.\" },' '  { role: \"user\", content: \"Cet agent détient-il des données privées, lit-il du contenu non fiable, a-t-il une voie de sortie ? \" + texte },' '];' '// Échantillon enregistré, utilisé seulement quand aucun modèle ne répond.' 'const echantillon = \"donnees: oui\nexterne: oui\nsortie: oui\";' > jambes2.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 du modèle, partie 2

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function lire(reponse) {' '  const trouve = {};' '  for (const ligne of reponse.split(\"\n\")) {' '    const morceaux = ligne.split(\":\");' '    if (morceaux.length === 2) trouve[morceaux[0].trim().toLowerCase()] = morceaux[1].trim().toLowerCase().startsWith(\"oui\");' '  }' '  return trouve;' '}' '' 'async function main() {' '  const reponse = await demander(messages, echantillon, 60);' '  console.log(\"Réponse :\n\" + reponse);' '  const f = lire(reponse);' '  const cles = [\"donnees\", \"externe\", \"sortie\"];' '  const forme = cles.every(function (c) { return c in f; });' '  console.log(\"Forme correcte : \" + forme);' '  if (forme) console.log(\"Les trois, selon le modèle : \" + (f.donnees && f.externe && f.sortie));' '  console.log(\"Le programme se fie à sa propre liste d’outils, pas à cette réponse.\");' '}' 'main();' >> jambes2.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 1

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const base = process.env.AI_URL || \"http://ai:4000\";' '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 || 200 }),' '      signal: AbortSignal.timeout(30000),' '    });' '    if (res.ok === false) throw new Error(\"statut \" + res.status);' '    return (await res.json()).choices[0].message.content;' > 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' '  } catch (erreur) {' '    console.log(\"Échantillon enregistré : aucun modèle n’a répondu (\" + erreur.message + \").\");' '    const liste = [].concat(echantillon);' '    const tour = messages.filter(function (m) { return m.role === \"assistant\"; }).length;' '    return liste[Math.min(tour, liste.length - 1)];' '  }' '}' '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.

Lancer avec le modèle

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

Une sortie possible

LigneCe qu’elle peut montrer
RéponseTrois lignes qui commencent par donnees, externe et sortie. Les mots après les deux-points changent à chaque exécution
Forme correctetrue quand les trois lignes sont là. false veut dire que le programme doit redemander ou refuser
Échantillon enregistréAffiché en premier quand aucun modèle n’a répondu. Le script continue avec l’échantillon

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.