Trier les commandes avec un modèle de décision
Ce guide montre comment laisser un modèle de décision répondre à votre place à la demande de confirmation quand une commande bash ne fait clairement que lire : la commande s'exécute sans question, et toutes les autres demandent comme avant. Il suppose que vous avez un fichier d'agent décideur (voir Interroger un modèle de décision) et que vous tournez avec yolo: false (voir Confirmer les appels d'outils). Les fichiers complets sont dans demos/decision-commands/.
Étapes
-
Donnez au décideur deux questions sur une commande, dans son bloc
decision::decision: timeout: 60s questions: risk: type: choice instructions: How risky is running this shell command in the project directory? criteria: read-only: Only reads files or prints information local-change: Changes files inside the project, easy to rebuild or revert dangerous: Deletes or changes things outside the project, uses sudo, the network, git push or force destructive: type: noul instructions: The command deletes data that cannot be rebuilt. -
Écrivez un hook
preToolCallqui interroge le décideur et répondallowquand il est sûr. En Node.js,hooks/triage.js:const { execFileSync } = require("child_process"); const path = require("path"); const input = JSON.parse(require("fs").readFileSync(0, "utf8")); const command = input.tool.input.command || ""; let a; try { const out = execFileSync("mm", ["-config", path.join(process.env.MM_CONFIG_DIR, "agent.decider.yaml"), "-p", `Command the agent wants to run in ${input.cwd}: ${command}`], { encoding: "utf8" }); a = JSON.parse(out).answers; } catch { process.exit(0); // pas de verdict : on demande à l'utilisateur } if (a.risk.choice === "read-only" && a.risk.confidence >= 0.8 && a.destructive.noul < 0.3) { console.log(JSON.stringify({ action: "allow" })); }N'afficher rien vous laisse la décision. Le hook de la démo répond aussi
denypour une commande jugée dangereuse et destructrice. -
Déclarez le hook dans l'agent qui vous répond :
yolo: false displayHooks: true hooks: preToolCall: - matcher: ^bash$ command: node "$MM_CONFIG_DIR/hooks/triage.js" timeout: 20s -
Demandez quelque chose qui lit, puis quelque chose qui modifie. La première commande s'exécute sans question, la seconde demande :
> show the content of notes.txt, then delete the build folder 🛠️ bash: cat notes.txt │ notes about the playground 🛠️ bash: rm -rf build 🔐 bash: rm -rf build [a] allow once · [s] allow bash for this session · [r] reject · [n] never bash ?Avec
displayHooks: true, la liste après la réponse dit ce que le hook a décidé pour chaque appel :preToolCall bash · node "$MM_CONFIG_DIR/hooks/triage.js" → allow, puis→ continue.
Variantes
- Dans un script (
mm -p) : personne ne peut répondre, donc avecyolo: falsechaque appel qui demanderait est refusé. Un appel que le hook a autorisé s'exécute. Cela laisse un agent scripté lire librement sans rien modifier. - Plus strict ou plus souple : les seuils de la démo sont des variables d'environnement,
TRIAGE_ALLOW_CONFIDENCE(0,8) etTRIAGE_ALLOW_DESTRUCTIVE(0,3). Mesurez sur vos propres commandes avant de les assouplir. - Un décideur froid : le premier appel charge le modèle (2 à 13 s). Au-delà du
timeoutdu hook, le hook échoue,onError: warnle signale, et la question vous est posée comme d'habitude. - mm n'est pas dans le PATH : donnez le chemin du binaire dans
MM_BINpour le hook de la démo. - Toutes les commandes demandent, même
ls: le hook lance le décideur dans le dossier de votre projet. AvecskillsDir: "", le décideur y lit./skills, déclareread_skillet refuse de démarrer — le hook n'a donc pas de verdict. Donnez au décideurskillsDir: no-skills.
Voir aussi
- L'action
allow, et ce qu'elle ne renverse jamais : Référence des hooks - Pourquoi le décideur ne fait que retirer des questions, sans jamais ajouter de permission : Modèles de décision
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
|