How to ask a decision model
This guide shows how to make an mm agent out of a decision model — a model that reads a situation and answers typed questions with a probability per option, without writing text — and how to read its answers from the command line, from a script, from the terminal and from another agent. It assumes you know how to write an agent file. The examples use LiquidAI d1-3B on llama-server; the finished files in demos/decision-skills/ use the llmman variant below.
Steps
1. Serve a decision model
Start a server that has the /v1/systemone route, with a model it accepts as a decision model:
llama-server -hf LiquidAI/d1-3B-GGUF:Q4_K_M --port 8090
2. Write the decider agent
A decider is an agent file with a decision: block. Each question has a name, a type and its criteria (step by step, with examples: How to write the questions of a decider):
# agent.decider.yaml
provider: llamacpp
model: LiquidAI/d1-3B-GGUF:Q4_K_M
baseUrl: http://127.0.0.1:8090/v1
decision:
questions:
risk:
type: choice # one option out of the criteria
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 # the probability that the statement is true
instructions: The command deletes data that cannot be rebuilt.
urgency:
type: score # a level, lowest first
instructions: How carefully should a person review this command before it runs?
criteria: [no review needed, a quick look, a careful review]
# A decider gets no tool and ignores AGENTS.md: mm handles both by itself.
The message you send is the state the questions are about. Write the instructions in English: that is what the models seen so far were trained on.
3. Ask it from the command line or a script
mm -config agent.decider.yaml -p "rm -rf ~/.config && git push --force origin main"
stdout carries the server's JSON and nothing else, so a script can parse it:
{"model":"LiquidAI/d1-3B-GGUF:Q4_K_M","answers":{"risk":{"type":"choice","choice":"dangerous","probabilities":{"read-only":0.007,"local-change":0.034,"dangerous":0.959},"confidence":0.939},"destructive":{"type":"noul","noul":0.882},"urgency":{"type":"score","score":1.887,"legend":{"0":"no review needed","1":"a quick look","2":"a careful review"},"probabilities":{"0":0.029,"1":0.056,"2":0.916},"confidence":0.830}},"usage":{"input_tokens":172,"output_tokens":0}}
The exit status is 0 when the server answered, 1 otherwise (the reason is on stderr). In a hook, run this command and read answers.<name>, the same way the guard demo reads Granite Guardian's verdicts.
4. Ask it from another agent
Declare it in the asking agent's mmConfigs:
mmConfigs:
decider: agent.decider.yaml
Then /ask-decider git push --force origin main in the terminal, the window or an editor, or mm --ask decider -p "…" from a skill, shows one line per question followed by the JSON:
risk: dangerous (confidence 0.94) — dangerous 0.96 · local-change 0.03 · read-only 0.01
destructive: 0.88
urgency: 1.89 → a careful review (confidence 0.83) — a careful review 0.92 · a quick look 0.06 · no review needed 0.03
mm -config agent.decider.yaml on its own does the same for every line you type.
Variants
- llmman or Ollama:
provider: llmman(orollama),baseUrl: http://127.0.0.1:17434/v1(or:11434/v1),model: hf.co/LiquidAI/d1-3B-GGUF:Q4_K_M— pull it first. All three servers gave the same answers for the same request. - Another OpenAI-compatible server:
provider: openaiand itsbaseUrl; mm posts to/v1/systemoneat the server's root (baseUrlwithout its trailing/v1), and a server without the route answers 404. - From a sandbox: add
fallback: http://host.docker.internal:8090/v1. - Before every question of a chat agent: a
preGenerationhook runsmm -config agent.decider.yaml -pon the question and returns the answers as acontext, which the chat model reads under the question; its system prompt says what to do with them.demos/decision-chat/does this with a hook that turns any answer into a line, so the questions can change without touching it. To see the decider's answers yourself before the chat model answers, adddisplay: trueto the decider'sdecision:block:-pthen marks its JSON, and the demos' hooks return the answers, indented, as the reply'sdisplay— mm shows them in their own colour (demos/decision-dnd/has it on). - Without any chat model:
demos/decision-only/triages a folder of support messages with onemm -pcall per message, read by a short Node.js script that prints a table, most urgent first.demos/decision-reviews/(customer reviews) anddemos/decision-moderation/(blog comments) do the same and check every answer against a file of expected answers. - A smaller decision model:
model: hf.co/LiquidAI/d1-omni-600M-GGUF:Q8_0(no Q4_K_M build is published). On the three demos above it was about five times faster than d1-3B (0.1 s per call against 0.55 s,mmstart-up included) and less accurate: 26/28 against 28/28 on the reviews, 24/32 against 31/32 on the comments, five support categories out of six against six.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
HTTP 501: This model is not a decision model (llmman, llama-server) or HTTP 400: model "…" is not a llama.cpp decision model (Ollama) |
the server does not treat the model as a decision model (evalengine's decision-4b is refused) |
use a model the route accepts, such as LiquidAI d1 |
decision: dmr: no /v1/systemone route at start-up |
Docker Model Runner has no such route | serve the model with llama-server, llmman or Ollama |
decision cannot be used with tools — this agent declares: … |
the decider file sets mcp, lsp.servers, mmConfigs or tools: |
remove the entries the message lists |
| the first answer takes ~13 s | the server loads the model on the first call | nothing: later calls take 0.2–0.5 s |
See also
- Every key and every answer field: Configuration reference
- Choosing the names, the types and the wording of the questions: How to write the questions of a decider
- Using a decider to pick the skill before each turn: How to route skills with a decision model
- Why it is built this way: Decision models
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 |
|