The Decision model.
A small model trained to answer a typed question with calibrated probabilities over a fixed set of options. It writes no prose. It cannot cite a nonexistent option, add commentary around the answer, or forget to answer the question it was asked.
The shape has a name and the name is decision model. Loomcycle ships one as a memory reranker (v1.104) and as a general tool any agent can call (v1.107). Three question types: choice (pick one of 2 to 26), noul (yes-or-no probability), score (ordered levels). One to sixty-four questions per call. The output is a vector of probabilities, never prose.
Three question types
Two to twenty-six labelled options. Returns one probability per option. Use for classification, routing, re-ranking.
Returns the probability of "yes". Use for verification, filters, "did this chunk answer the question" gates.
An ordinal scale (low / medium / high / critical). Returns the expected position. Use for severity, priority, confidence buckets.
Where loomcycle uses one
Memory reranker
The reranker that re-orders a memory recall. Measured LoCoMo recall@5 lifted from 0.588 to 0.740 against the prose reranker it replaced; ConditionalQA R@5 0.944 vs 0.935 at about a third of the latency.
v1.104 ·memory.reranker.kind: decision
Decision tool
Any agent that holds a Context grant gets a Decision tool. Also POST /v1/_decide on HTTP, Decide on gRPC, decision on MCP, decide() on the TypeScript and Python clients.
Team decision nodes
A team graph node of kind: decision asks a decision model itself and routes the walk by the answer. No sub-run is started, no prose is written; the walk picks the next edge from the probabilities.
TeamDef + LoomBoard canvas
Model aliases carry kind
Every model alias is tagged chat | decision | embedder. A chat model wired into a decision slot refuses config load with a named error, not three turns into a run.
What the shape costs
- Only Ollama 0.35+ serves decision models today. Four models have the typed-answer API:
nimble,clef,clef-flash,tev1. Other backends serve the usual chat API; the prose reranker remains the fallback. - Probabilities are not cross-call calibrated. A 0.8 on one question is not the same confidence as a 0.8 on another. Compare within one answer; measure your corpus before gating.
- Context plus options plus question must fit the model's input budget. Loomcycle's runtime retries at half, then a quarter character budget on refusal; the chain is logged.
The call looks like this
// a classification call
await Decision.ask({
question: "What is the sentiment of this review?",
context: "The waiter was slow but the food was great.",
type: "choice",
options: ["negative", "neutral", "positive"],
})
// returns: { probabilities: { negative: 0.08, neutral: 0.19, positive: 0.73 } }
// a yes/no gate
await Decision.ask({
question: "Does this chunk answer the user's question?",
context: "...retrieved chunk...",
type: "noul",
})
// returns: { probability_yes: 0.91 }
Reading
- A model that cannot say the wrong word — the primitive, the reranker number, the Decision tool, v1.104 → v1.107.
- Local decision model as a memory search reranker — a 9B typed-answer model vs a 27B general one on 800 ConditionalQA questions; recall@5 matched, recall@1 lost, abstention gate didn't work.
- Teams as one definition — the Team file; decision nodes route the walk by a typed answer.
- A canvas for state-machine workflows — the LoomBoard canvas; the "triage → billing / support / sales" layout in the illustration above is the decision-node routing pattern.
Code
- github.com/denn-gubsky/loomcycle — the runtime. Apache-2.0.
- docs/DECISION-MODELS.md — the operator reference.
Why the page exists
Multiple projects arrived at the same shape in 2026, from different directions. Loomcycle shipped the primitive first and uses it in four slots. The shape deserves a settled name. This page is that name: a decision model, singular, lowercase, the way one would say "an embedder" or "a chat model".
Maintained by Dennis Gubsky. Comments to [email protected].