Écrire les risques pour n’en oublier aucun
Un registre des risques est un tableau. Il dit ce qui pourrait mal tourner avec une fonction, avec quelle probabilité, et ce que vous ferez pour y remédier.
Une équipe qui parle seulement des risques en oublie. Un registre est écrit : on peut y chercher des trous et classer les pires d’abord.
À la fin de cette leçon
Remarque
Je peux écrire les risques d’une fonction d’IA pour que rien ne soit oublié.
Mots clés
| Mot | Ce que ça veut dire |
|---|---|
| Risque | ce qui pourrait mal tourner pour une personne |
| Probabilité | la chance que cela arrive, de 1 à 3 |
| Gravité | l’ampleur du mal, de 1 à 3 |
| Mesure | ce que vous faites pour réduire un risque |
| Domaine | une partie du trajet des données, comme le stockage |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Chaque risque a un score et une mesure
Donnez à chaque risque une probabilité et une gravité, chacune de 1 à 3. Le score est leur produit : on les multiplie. Un score de 2 ou moins est faible, 3 ou 4 est moyen, et 6 ou 9 est élevé.
Chaque ligne a aussi besoin d’une mesure. Un risque sans plan n’est qu’une inquiétude.
Exemple détaillé : probabilité fois gravité
| Risque | Probabilité | Gravité | Score | Niveau |
|---|---|---|---|---|
| Le message contient un courriel | 3 | 2 | 6 | Élevé |
| Le journal garde les messages entiers | 2 | 3 | 6 | Élevé |
| La sauvegarde garde des données supprimées | 2 | 2 | 4 | Moyen |
| Le personnel lit toutes les discussions | 1 | 3 | 3 | Moyen |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Trous et erreurs possibles dans un registre
Une ligne peut être fausse : une probabilité de 5, ou une mesure vide. Un registre peut aussi être incomplet. Vérifiez que chaque domaine du trajet des données a au moins une ligne.
Les domaines usuels sont la collecte, l’envoi, le stockage, l’accès, la suppression et l’entraînement (l’usage des données pour entraîner un modèle). Un domaine sans ligne est un trou.
Une erreur courante
Attention
Beaucoup pensent que le score est une mesure exacte. C’est un jugement écrit sous forme de nombre, et deux personnes peuvent différer. Servez-vous-en pour ordonner la discussion, jamais pour prouver qu’une fonction est sûre. Un registre court n’est peut-être qu’un registre incomplet.
É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 contrôleur de registre, partie 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { demander } = require(\"./model\");' 'const requis = [\"collecte\", \"envoi\", \"stockage\", \"accès\", \"suppression\", \"entraînement\"];' 'const registre = [' ' { risque: \"Le message contient un courriel\", domaine: \"envoi\", p: 3, g: 2, mesure: \"Masquer d’abord\" },' ' { risque: \"Le journal garde les messages entiers\", domaine: \"stockage\", p: 2, g: 3, mesure: \"Ne journaliser que la longueur\" },' ' { risque: \"La sauvegarde garde des données supprimées\", domaine: \"suppression\", p: 2, g: 2, mesure: \"\" },' ' { risque: \"Le personnel lit toutes les discussions\", domaine: \"accès\", p: 1, g: 3, mesure: \"Limiter les lecteurs\" },' ' { risque: \"Le fournisseur garde les messages\", domaine: \"collecte\", p: 0, g: 3, mesure: \"Vérifier le contrat\" },' '];' > registre.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 contrôleur de registre, partie 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function niveau(s) { return s <= 2 ? \"faible\" : s <= 4 ? \"moyen\" : \"élevé\"; }' 'function problemes(r) {' ' const sortie = [];' ' if (r.p < 1 || r.p > 3) sortie.push(\"probabilité hors échelle\");' ' if (r.g < 1 || r.g > 3) sortie.push(\"gravité hors échelle\");' ' if (r.mesure.trim().length === 0) sortie.push(\"pas de mesure\");' ' return sortie;' '}' >> registre.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 contrôleur de registre, partie 3
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function couvert(domaine) {' ' return registre.some(function (r) { return r.domaine === domaine; });' '}' 'async function main() {' ' const classes = registre.slice().sort(function (a, b) { return b.p * b.g - a.p * a.g; });' ' classes.forEach(function (r) {' ' const s = r.p * r.g;' ' console.log(s + \" \" + niveau(s) + \" | \" + r.risque + \" | \" + JSON.stringify(problemes(r)));' ' });' ' console.log(\"domaines manquants : \" + JSON.stringify(requis.filter(function (d) { return couvert(d) === false; })));' ' const q = \"Donnez en une courte phrase une mesure pour ce risque : une sauvegarde garde des données après une demande d’effacement.\";' ' const echantillon = \"Fixez une courte durée de sauvegarde et dites à la personne quand elle disparaît.\";' ' const r = await demander([{ role: \"user\", content: q }], echantillon, 60);' ' console.log(\"le modèle dit : \" + r.texte);' '}' 'main();' >> registre.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 contrôleur de registre
docker exec -w /home/node/project agent node registre.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 |
|---|---|
| 6 élevé | Le message contient un courriel | [] | Le pire risque, sans problème |
| 4 moyen | La sauvegarde garde des données supprimées | ["pas de mesure"] | Une ligne à qui il manque une partie |
| 0 faible | Le fournisseur garde les messages | ["probabilité hors échelle"] | Une ligne avec un mauvais nombre |
| domaines manquants : ["entraînement"] | Un domaine sans ligne |
| le modèle dit : ... | Une phrase. Les mots changent à chaque exécution |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.