local models · decision models · sbx · tiny language models · 7 min read

One day, one feature: Decision models & Wizardry

Use a small decision model with Mini Me: a decider agent that picks the best spell for a D&D wizard, with a probability for each option, in one pass.

K
k33gOct 24, 2026 · 7 min
One day, one feature: Decision models & Wizardry

I added support for decision models in version 1.0.0 of Mini Me. So today, let's see how we can use them.

Decision Models?

A decision model is a small model fine-tuned to choose, not to write. It reads a state:

  • a request,
  • a command,
  • a document
  • ...

And it answers typed questions in a single pass: which option from a list (choice), what probability for a statement (noul), which level on a scale (score), with a probability for each option. For example:

raw
I'm facing a werewolf, I have 5 hit points left, what's my best next action?

llamacpp, llmman and Ollama serve these models through the same route, POST /v1/systemone (you'll need a recent version to get it). mm uses it in two ways: as an agent you query (decision:), and as a step before each turn of a chat agent (skillRouting:, toolRouting:). Today we'll only look at the decision: part.

Prerequisites

I'm going to use the decision model LiquidAI/d1-3B-GGUF:Q4_K_M. Liquid AI positions it for routing, intent classification, moderation, reranking, answer evaluation and agent guardrails.

So download the model with llmman:

bash
llmman pull hf.co/LiquidAI/d1-3B-GGUF:Q4_K_M

Now, let's go for a 1st example, a fun one (it's the weekend, let's forget about work).

I'm a wizard in Dungeons & Dragons

I'm a beginner wizard, and I have a list of spells:

  • Fireball
  • Arcane bolt
  • Shield
  • Misty step
  • Sleep

But I'm not very good at using them at the right time. So I'm going to use a "decider agent" (a Mini Me agent dedicated to decision making).

Agent configuration: spell.yaml

Let's start by defining the settings of the "decider agent". It's actually very simple.

Setting up the decider

**spell.yaml**:

yaml
# A decider: Dungeons & Dragons: which spell for my wizard?
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
        arcane_bolt: 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 declares no tool: its model never calls one.
bashTool: false
editTools: false
planTool: false
fetchContentTool: false
askUserTool: false
skillsDir: no-skills
agentsMd:
  enabled: false

And now all that's left is to use it.

Asking a friend for advice

Let's give our agent a situation and see which spell it advises us to cast. Run the following command:

bash
mm -config spell.yaml -p "An ogre is raising its club to hit me right now." | jq .

The output should look like this:

json
{
  "model": "hf.co/LiquidAI/d1-3B-GGUF:Q4_K_M",
  "answers": {
    "spell": {
      "type": "choice",
      "choice": "shield",
      "probabilities": {
        "fireball": 0.024439615441757868,
        "arcane_bolt": 0.04355627733740044,
        "shield": 0.8782501602485459,
        "misty_step": 0.04297835734219251,
        "sleep": 0.01077558963010329
      },
      "confidence": 0.8478127003106822
    }
  },
  "usage": {
    "input_tokens": 109,
    "output_tokens": 0
  }
}

So you get:

  • "choice": "shield", the agent's suggestion
  • "confidence": 0.8478127003106822, the agent's confidence in its suggestion
  • "probabilities": {...}, and the probability for each spell of being the best choice

But now, I'd like to interact through a chat agent (the dungeon master, for example).

A dungeon master with a hook

First of all, we need a model for the chat agent:

bash
llmman pull hf.co/unsloth/Qwen3.5-4B-GGUF:Q4_K_M

Then we need a preGeneration hook, to send the question to the decision agent before passing it on to the chat agent.

A decision hook

Next, we're going to define a hook in Go (you can of course choose another language). This hook is a small program that Mini Me runs before each question, before sending it to the Dungeon Master.

Its role: ask the decider for its opinion and slip its answer under the question. Here's how it works, step by step:

  1. It receives the question. Mini Me (mm) starts it and sends it, on its standard input, some JSON containing the player's question:
json
 {"prompt": "An ogre is raising its club to hit me right now.", ...}
  1. It queries the decider. It runs mm a second time, in decider mode, with the file given as an argument (spell.yaml):
bash
 mm -config spell.yaml -p "An ogre is raising its club to hit me right now."

and gets the decider's JSON back: 3. It turns this JSON into readable lines, one per decider question, depending on its type:

  • choice -> spell: "shield" (confidence 0.85)
  • noul -> hurt: yes (0.97)
  • score -> danger: "deadly" (score 1.76) It doesn't know the names of the questions: it reads their type. That's why the hook works with any decider.
  1. It sends the result back to mm on its standard output:
json
 {"context": "spell: shield (confidence 0.85)"}
  1. mm adds this text under the question, and the Dungeon Master receives:
raw
 An ogre is raising its club to hit me right now.

 [context added by a hook]
 spell: shield (confidence 0.85)

Its system prompt explains what this line means.

A few remarks:

  • If something fails (decider not found, server stopped, etc. ...), the hook writes nothing. mm then sends the question as is, and the conversation carries on without the decider's opinion.
  • DECIDER_DUMP=.mm/decider: for each question, the hook also writes a timestamped JSON file. This file contains the question, the decider's full answer and the line passed on, or the error if the decider failed. It's handy to understand what happened, and also to check that the models aren't doing just anything while you're fine-tuning your system instructions.

The hook's code is available here: 03-decision-models/hooks/ask-decider

  • main.go: steps 1 to 4.
  • dump.go: the JSON backup.

To sum up, the hook is a kind of translator between the decider, which answers in JSON with probabilities, and the chat model, which reads text.

Visually, it works like this:

decision flow
decision flow

Let's test our Dungeon Master

Run:

bash
mm tui dungeon_master.yaml

And try the following questions:

Situationspell
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.arcane_bolt (0.58)
Six kobolds are sneaking toward our camp; the paladin wants to question them alive.fireball (0.44) — wrong, sleep would be a better fit
Five goblins
Five goblins
An ogre is raising its club
An ogre is raising its club
Two wolves
Two wolves
One goblin is left
One goblin is left
Six kobolds
Six kobolds

And you can go and check the answers in JSON format in .mm/decider, for example 20261024-090453.972-spell.json:

bash
{
  "time": "2026-10-24T09:04:53.972098+02:00",
  "decider": "spell.yaml",
  "prompt": "Six kobolds are sneaking toward our camp; the paladin wants to question them alive.",
  "response": {
    "model": "hf.co/LiquidAI/d1-3B-GGUF:Q4_K_M",
    "answers": {
      "spell": {
        "type": "choice",
        "choice": "fireball",
        "probabilities": {
          "fireball": 0.5558058331416994,
          "arcane_bolt": 0.029942227003669688,
          "shield": 0.02634446128431945,
          "misty_step": 0.043737821211561646,
          "sleep": 0.3441696573587497
        },
        "confidence": 0.4447572914271242
      }
    },
    "usage": {
      "input_tokens": 115,
      "output_tokens": 0
    }
  },
  "context": "spell: fireball (confidence 0.44)"
}

And voilà, that's all for today. The decision model concept is brand new and I'm still working on interesting use cases for Mini Me, like smart skill routing, better tool selection, etc... So stay tuned. But already, combined with the hook system, the possibilities are endless.

The complete code is available here: /03-decision-models.

Don't forget that you need Mini Me v1.0.0, a recent llmman (0.1.571) and a recent llamacpp (0.7.0), or if you're using Ollama, you'll need version 0.40.8.

See you tomorrow for a new feature.

K

Written by

k33g

Keep reading

One day, one feature: Mini Me's built-in tools and declared tools

How Mini Me runs tools for a local model: the agent loop, the built-in tools led by bash, and how to declare your own tools in a few lines of YAML.

Oct 23, 2026
One day, one feature: Mini Me's built-in tools and declared tools

Hello Mini Me: an agent born while preparing a talk for Devoxx

Meet Mini Me, a coding agent born from a Devoxx talk on the agent loop, built for small local models with guardrails against loops and hallucinations.

Oct 3, 2026
Hello Mini Me: an agent born while preparing a talk for Devoxx

How to use a "guardrail" model with Mini Me

Use IBM's Granite Guardian 3B as a guardrail model with Mini Me, checking prompts and responses for harm, bias and jailbreak attempts.

Oct 20, 2026
How to use a "guardrail" model with Mini Me

Responses

0 Comments

No comments yet. Be the first to comment!

Related reading

From other blogs

Docker Agent and Tiny Language Models: One Tool to Rule Them All

k33g_org's Blog