Une liste de contrôle avant livraison
Une revue de sécurité compare la conception d’un agent à une liste de contrôle avant son emploi. Chaque point est une question à réponse oui ou non, donc deux relecteurs trouvent le même résultat.
C’est utile, car les leçons de ce module ne servent que si elles sont toutes en place. Une conception avec un bon dossier mais sans moyen de l’arrêter reste risquée.
À la fin de cette leçon
Remarque
Je peux revoir la conception d’un agent avec une liste de contrôle.
Mots clés
| Mot | Ce que ça veut dire |
|---|---|
| Liste de contrôle | une liste fixe de questions oui ou non |
| Conception | les outils, les données et les limites d’un agent |
| Limite | un plafond sur les étapes ou sur le coût |
| Interrupteur | un moyen pour une personne d’arrêter l’agent |
| Journal | une trace de ce que l’agent a fait |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Six domaines, huit questions
La liste couvre six domaines : les outils, les données, les dossiers, les limites, un moyen d’arrêt et une trace. Chaque domaine a une ou plusieurs questions oui ou non.
Une conception ne réussit que si chaque question réussit. Signalez chaque échec avec son domaine, pour trouver facilement la correction.
Exemple détaillé : trois conceptions
| Conception | Échecs | Lesquels |
|---|---|---|
| assistant | 0 | Aucun : elle réussit |
| bâtisseur | 4 | A un terminal, écrit partout, sans limite d’étapes, sans journal |
| éclaireur | 5 | Pas de liste d’outils, secrets dans la consigne, sans limites, sans arrêt |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Une erreur courante
Attention
Beaucoup pensent qu’un seul contrôle fort rend une conception sûre. Ce n’est pas vrai. Le bâtisseur a un interrupteur mais écrit partout et sans journal. La sécurité se fait par couches, et la couche manquante la plus faible cède la première.
Un nombre a besoin d’un bord
Une limite n’est un contrôle que si elle a un bord. Ici, une exécution peut faire 20 étapes au plus. Une conception à 20 réussit. Une conception à 21, ou sans limite du tout, échoue.
Dites où est le bord, testez-le des deux côtés, et comptez une valeur absente comme un échec.
Écrire l’assistant du modèle, partie 1
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
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 vérificateur de conception, partie 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { demander } = require(\"./model\");' 'const controles = [' ' [\"outils : pas de liste autorisée\", function (c) { return c.listeAutorisee === false; }],' ' [\"outils : a un terminal\", function (c) { return c.outils.indexOf(\"terminal\") >= 0; }],' ' [\"dossiers : écritures non confinées\", function (c) { return c.peutEcrire && (c.racine === \"\" || c.racine === \"/\"); }],' ' [\"données : secrets dans la consigne\", function (c) { return c.secrets; }],' > revue.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 vérificateur de conception, partie 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' ' [\"limites : pas de limite d’étapes\", function (c) { return c.maxEtapes === null || c.maxEtapes > 20; }],' ' [\"limites : pas de limite de coût\", function (c) { return c.maxCout === null; }],' ' [\"arrêt : aucun moyen d’arrêter\", function (c) { return c.interrupteur === false; }],' ' [\"trace : pas de journal\", function (c) { return c.journal === false; }],' '];' 'function echecs(c) { return controles.filter(function (x) { return x[1](c); }).map(function (x) { return x[0]; }); }' >> revue.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 vérificateur de conception, partie 3
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const conceptions = [' ' { nom: \"assistant\", outils: [\"lire\", \"ecrire\"], listeAutorisee: true, peutEcrire: true, racine: \"travail/\", secrets: false, maxEtapes: 10, maxCout: 5, interrupteur: true, journal: true },' ' { nom: \"bâtisseur\", outils: [\"lire\", \"ecrire\", \"terminal\"], listeAutorisee: true, peutEcrire: true, racine: \"/\", secrets: false, maxEtapes: null, maxCout: 20, interrupteur: true, journal: false },' ' { nom: \"éclaireur\", outils: [\"chercher\"], listeAutorisee: false, peutEcrire: false, racine: \"\", secrets: true, maxEtapes: 50, maxCout: null, interrupteur: false, journal: true },' '];' >> revue.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 vérificateur de conception, partie 4
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' ' conceptions.forEach(function (c) {' ' const f = echecs(c);' ' console.log(c.nom + \" : \" + f.length + \" échecs\" + (f.length > 0 ? \" : \" + f.join(\"; \") : \"\"));' ' });' ' const q = \"En une courte phrase, pourquoi un agent doit-il avoir un moyen d’être arrêté ?\";' ' const echantillon = \"Si tout tourne mal, une personne doit pouvoir l’arrêter tout de suite et voir ce qu’il a fait.\";' ' const r = await demander([{ role: \"user\", content: q }], echantillon, 60);' ' console.log(\"le modèle dit : \" + r.texte);' '}' 'main();' >> revue.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 vérificateur de conception
docker exec -w /home/node/project agent node revue.jsAffiché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 que le Run affiche
| Ligne | Ce qu’elle montre |
|---|---|
| assistant : 0 échecs | Elle réussit chaque contrôle |
| bâtisseur : 4 échecs : outils : a un terminal; ... | Elle échoue dans quatre domaines |
| éclaireur : 5 échecs : outils : pas de liste autorisée; ... | Elle échoue le plus |
| le modèle dit : ... | Une phrase. Les mots changent à chaque exécution |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.