Écrire les questions d'un décideur
Ce guide montre comment construire pas à pas le bloc decision: d'un décideur : quels mots sont imposés, lesquels vous choisissez, quel type prendre pour chaque question, et comment lire les réponses. Il suppose que vous avez déjà un décideur qui tourne — sinon, commencez par Interroger un modèle de décision.
Ce qui est imposé, ce qui est à vous
decision: # imposé
timeout: 60s # imposé (facultatif)
questions: # imposé
hurry: # À VOUS : n'importe quel nom
type: noul # mot imposé, l'un de : choice, noul, score
instructions: The message contains a word asking for speed, such as quick, fast, asap or now. # À VOUS
level: # À VOUS
type: choice
instructions: How familiar is the person with git? # À VOUS
criteria: # mot imposé
beginner: New to git # À VOUS : l'option (la clé) et ce qu'elle veut dire (le texte)
expert: Knows git well
hurry, upset, level, beginner… sont des noms que vous choisissez, pas des mots-clés. Ni mm ni le modèle ne leur donnent de sens : le modèle ne lit que les textes de instructions et de criteria. Le nom est la clé que vous retrouverez dans la réponse (answers.hurry) : choisissez-en un que votre script ou votre prompt pourra utiliser.
Les mots-clés sont decision, timeout, questions, type, instructions, criteria, et les trois noms de types.
Étapes
1. Dire ce que lit le décideur
Le décideur lit un seul message, seul — l'« état » : un ticket, une commande, la description d'une situation de jeu. Pas d'historique, pas de prompt système. Tout ce qu'il doit savoir doit être dans ce message.
2. Découper la décision en questions
Une question par chose que vous voulez savoir. « Ce ticket est-il grave ? » peut devenir trois questions : dans quel délai (un niveau), y a-t-il un signe de danger (oui ou non), qui doit s'en occuper (une option). Toutes les questions reçoivent leur réponse ensemble, en une passe, en une fraction de seconde.
3. Choisir un type pour chaque question
| Vous voulez… | Type | instructions est… |
criteria |
Vous recevez |
|---|---|---|---|---|
| une option dans une liste | choice |
une question | un dictionnaire option: description, au moins 2 |
choice (la clé de l'option), probabilities (une par option), confidence |
| un oui ou un non | noul |
une affirmation sur le message | aucun | noul : la probabilité, de 0 à 1, que l'affirmation soit vraie |
| un niveau sur une échelle | score |
une question | une liste de 2 à 10 niveaux, du plus bas au plus haut | score (de 0 à n−1, peut tomber entre deux niveaux), legend (numéro → niveau), probabilities, confidence |
noul est le type oui-ou-non. Vous écrivez une affirmation — « The message describes chest pain » — et le décideur donne la probabilité qu'elle soit vraie pour ce message : 0.96 veut dire « presque sûrement oui », 0.01 « presque sûrement non ». C'est votre script qui décide où commence le oui (0,5 est un seuil courant, plus haut quand un faux oui coûte cher).
score renvoie un nombre, pas un niveau : 2.81 sur quatre niveaux veut dire « entre today et now, bien plus près de now ». Arrondissez-le pour lire le niveau dans legend.
4. Écrire les instructions
choiceetscore: une question — « Which spell should I cast now? ».noul: une affirmation — « My character is badly hurt. ». Une question fermée marche aussi : sur cinq questions sur git, « Is the person upset? » et « The person is worried, stressed or upset. » ont donné les mêmes verdicts (0,97 et 0,99 sur les deux messages contrariés, 0,14 au plus sur les trois calmes).- Nommez ce qui est dans le texte, pas une intention. Mesuré avec LiquidAI d1-3B : « The person is in a hurry or asks for a short answer » donnait de 0,5 à 0,7 sur des questions calmes aussi ; « The message contains a word asking for speed, such as quick, fast, asap or now » a donné 0,03 sur une question calme et 0,98 sur « quick: … ». De même, « signs of a stroke » a obtenu 0,27 sur un AVC typique, « a sudden weakness of an arm or a leg, slurred speech » 0,96.
Les exemples sont en anglais, comme dans les démos ; d1-3B a aussi bien traité des messages en français dans les démos (decision-only, decision-moderation).
5. Écrire les criteria
choice: la clé est ce que vous recevez (fireball), le texte est ce que le modèle lit pour choisir — dites quand prendre cette option :fireball: Many enemies close together, far enough from my friends.score: les niveaux, du plus bas au plus haut, en phrases courtes :[harmless, risky, deadly].noul: rien.
L'ordre du fichier est conservé : dans la requête, dans la réponse, et dans l'affichage en lignes.
6. L'essayer
Avec spell.yaml de demos/decision-questions/ (le fichier complet est dans les exemples) :
mm -config spell.yaml -p "An ogre is raising its club to hit me right now."
{"model":"hf.co/LiquidAI/d1-3B-GGUF:Q4_K_M","answers":{"spell":{"type":"choice","choice":"shield","probabilities":{"fireball":0.024,"magic_missile":0.043,"shield":0.878,"misty_step":0.043,"sleep":0.011},"confidence":0.848}},"usage":{"input_tokens":109,"output_tokens":0}}
(nombres raccourcis ici ; le serveur les donne en entier.) Sans -p, mm -config spell.yaml affiche une ligne par question pour chaque message tapé, puis le même JSON.
7. Lire les réponses
L'enveloppe est toujours la même — model, answers, usage — et answers a une entrée par question, sous le nom que vous avez choisi, avec les champs de son type (étape 3). D'un décideur à l'autre, seuls changent les noms et le nombre de questions.
choice: lisezchoice; traitez uneconfidencebasse (sous 0,5 environ) comme « incertain ».noul: compareznoulà votre seuil.score: lisezlegend[round(score)], ou comparezscorelui-même (> 2.5).
Exemples
Chaque exemple est un fichier d'agent complet de demos/decision-questions/ : copiez-le, ou lancez-le depuis ce dossier avec mm -config <fichier> -p "<message>". Toutes les réponses ci-dessous ont été mesurées le 2026-10-24 avec LiquidAI d1-3B Q4_K_M sur llmman.
Des tickets de symptômes : à quel point c'est grave ?
symptoms.yaml :
# A decider: Symptom tickets: how serious is it?
# An example of the guide docs/{en,fr}/how-to/write-decision-questions.md.
#
# mm -config symptoms.yaml -p "My father suddenly cannot lift his right arm and his speech is slurred, it started 20 minutes ago."
#
# Pull the model once: llmman pull hf.co/LiquidAI/d1-3B-GGUF:Q4_K_M
provider: llmman
model: hf.co/LiquidAI/d1-3B-GGUF:Q4_K_M
baseUrl: http://127.0.0.1:17434/v1
fallback: http://host.docker.internal:17434/v1
decision:
questions:
severity:
type: score
instructions: How soon should this person see a doctor?
criteria: [it can wait for a usual appointment, within a few days, today, now - call the emergency number]
red_flag:
type: noul
instructions: The message describes a sudden weakness of an arm or a leg, slurred speech, chest pain, trouble breathing, heavy bleeding or fainting.
who:
type: choice
instructions: Who should see this person first?
criteria:
pharmacist: A minor problem a pharmacist can advise on
family_doctor: A usual problem for a general practitioner
specialist: A known long-term condition followed by a specialist
emergency: A problem that cannot wait
# A decider gets no tool: mm turns bash, the file tools, plan, ask_user and
# skills off by itself (no `…: false` lines needed).
agentsMd:
enabled: false
| Ticket | severity | red_flag | who |
|---|---|---|---|
| My father suddenly cannot lift his right arm and his speech is slurred, it started 20 minutes ago. | 2.81 → now (0.81) | 0.96 | emergency (0.86) |
| I have a tight pain in my chest and my left arm since an hour. | 2.60 → now (0.60) | 0.56 | emergency (0.83) |
| I have had a sore throat and a runny nose for two days, no fever. | 0.82 → within a few days (0.49) | 0.01 | pharmacist (0.30) |
Mettez les signes de danger dans un noul à part et faites-le passer avant le score : la douleur thoracique n'a obtenu que 0,56 sur red_flag, un seuil de 0,5 l'attrape, un seuil de 0,8 non. Un décideur trie des tickets ; il ne pose pas de diagnostic, et une personne doit relire ce qu'il range en « peut attendre ».
Le 421 : quels dés relancer ?
dice421.yaml :
# A decider: 421: how many dice to throw again? The script writes what is missing: a decider reads, it does not count.
# An example of the guide docs/{en,fr}/how-to/write-decision-questions.md.
#
# mm -config dice421.yaml -p "Dice: 4, 2, 6. In place for 421: 4 and 2. Missing: 1."
#
# Pull the model once: llmman pull hf.co/LiquidAI/d1-3B-GGUF:Q4_K_M
provider: llmman
model: hf.co/LiquidAI/d1-3B-GGUF:Q4_K_M
baseUrl: http://127.0.0.1:17434/v1
fallback: http://host.docker.internal:17434/v1
decision:
questions:
reroll:
type: choice
instructions: How many dice should the player throw again?
criteria:
none: Nothing is missing
one: One die is missing
two: Two dice are missing
all: All three are missing
# A decider gets no tool: mm turns bash, the file tools, plan, ask_user and
# skills off by itself (no `…: false` lines needed).
agentsMd:
enabled: false
| État envoyé | reroll |
|---|---|
Dice: 4, 2, 6. |
none (0.33) — faux |
Dice: 4, 2, 6. In place for 421: 4 and 2. Missing: 1. |
one (0.80) |
Dice: 4, 5, 6. In place for 421: 4. Missing: 2 and 1. |
two (0.62) |
Dice: 3, 5, 6. In place for 421: nothing. Missing: 4, 2 and 1. |
all (0.76) |
Dice: 4, 2, 1. In place for 421: 4, 2 and 1. Missing: nothing. |
none (0.96) |
Un modèle de décision lit ; il ne compte pas. Avec les dés seuls, il s'est trompé ; dès que le script a écrit ce qui manque dans l'état, il a eu juste quatre fois sur quatre. Mais le script avait alors déjà fait le travail : une règle comme celle-ci s'écrit mieux en code. Gardez le décideur pour ce qu'une règle ne sait pas dire — « le score de mon adversaire vaut-il de prendre le risque ? », décrit en mots.
Donjons et Dragons : quel sort pour mon magicien ?
spell.yaml :
# A decider: Dungeons & Dragons: which spell for my wizard?
# An example of the guide docs/{en,fr}/how-to/write-decision-questions.md.
#
# mm -config spell.yaml -p "An ogre is raising its club to hit me right now."
#
# Pull the model once: llmman pull hf.co/LiquidAI/d1-3B-GGUF:Q4_K_M
provider: llmman
model: hf.co/LiquidAI/d1-3B-GGUF:Q4_K_M
baseUrl: http://127.0.0.1:17434/v1
fallback: http://host.docker.internal:17434/v1
decision:
questions:
spell:
type: choice
instructions: I am the party's wizard. Which spell should I cast now?
criteria:
fireball: Many enemies close together, far enough from my friends
magic_missile: One weak enemy to finish off, or one that is hard to hit
shield: An enemy is about to hit me
misty_step: I am surrounded or grabbed and must get away
sleep: Several weak enemies, and we would rather not kill them
# A decider gets no tool: mm turns bash, the file tools, plan, ask_user and
# skills off by itself (no `…: false` lines needed).
agentsMd:
enabled: false
| Situation | spell |
|---|---|
| Five goblins are standing in a tight group 40 feet away. My friends are behind me. | fireball (0.50) |
| An ogre is raising its club to hit me right now. | shield (0.85) |
| Two wolves have grabbed me and the rest of the party is far away. | misty_step (0.47) |
| One goblin is left, almost dead, hiding behind a crate. | magic_missile (0.58) |
Chaque description dit quand lancer le sort, pas ce qu'il fait : le décideur compare la situation à ces conditions.
Donjons et Dragons : combattre ou fuir ?
fight.yaml :
# A decider: Dungeons & Dragons: fight, flee or talk?
# An example of the guide docs/{en,fr}/how-to/write-decision-questions.md.
#
# mm -config fight.yaml -p "A troll guards the bridge. It says it will let us pass if we pay one gold coin."
#
# Pull the model once: llmman pull hf.co/LiquidAI/d1-3B-GGUF:Q4_K_M
provider: llmman
model: hf.co/LiquidAI/d1-3B-GGUF:Q4_K_M
baseUrl: http://127.0.0.1:17434/v1
fallback: http://host.docker.internal:17434/v1
decision:
questions:
action:
type: choice
instructions: What should my character do now?
criteria:
fight: We can win this fight
flee: We would probably lose, and there is a way out
talk: The enemy might listen, a fight is not needed
danger:
type: score
instructions: How dangerous is this situation for my character?
criteria: [harmless, risky, deadly]
hurt:
type: noul
instructions: My character is badly hurt.
# A decider gets no tool: mm turns bash, the file tools, plan, ask_user and
# skills off by itself (no `…: false` lines needed).
agentsMd:
enabled: false
| Situation | action | danger | hurt |
|---|---|---|---|
| We are four, full health, facing two tired bandits on an open road. | fight (0.17) | 1.15 → risky | 0.18 |
| I am alone with 3 hit points left, a red dragon lands in front of me, the cave exit is behind me. | flee (0.56) | 1.76 → deadly | 0.97 |
| A troll guards the bridge. It says it will let us pass if we pay one gold coin. | talk (0.64) | 0.64 → risky | 0.31 |
Les bandits ont obtenu fight avec une confiance de 0,17 : la bonne option, mais à peine devant talk. Demander aussi danger et hurt permet à votre script de trancher quand action hésite — par exemple, fuir quand hurt dépasse 0,8, quoi que dise action.
Erreurs courantes
| Erreur | Effet | Correction |
|---|---|---|
| Une intention ou un diagnostic (« is in a hurry », « signs of a stroke ») | des probabilités moyennes sur tous les messages | nommez ce qu'on peut lire dans le texte |
Des descriptions choice qui disent ce qu'est une option |
le décideur ne peut pas comparer la situation | dites quand la choisir |
Des niveaux score du plus haut au plus bas |
le score se lit à l'envers | du plus bas au plus haut |
| Du calcul ou du comptage dans la question | des réponses fausses | calculez dans le script, ou mettez le résultat dans l'état |
| Le contexte seulement dans l'historique | le décideur ne le voit jamais | mettez-le dans le message : le décideur ne lit rien d'autre |
Voir aussi
- Référence de la configuration —
decision: chaque clé et chaque champ des réponses - Interroger un modèle de décision : servir le modèle, écrire le fichier d'agent, l'interroger depuis un script, un hook ou un autre agent
- Les modèles de décision — explication : pourquoi un décideur est un agent, ce qui a été mesuré
- Démos :
demos/decision-only/,demos/decision-reviews/,demos/decision-moderation/(un décideur seul),demos/decision-chat/(un décideur avant un agent de chat)
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 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 |
|