strands-decider README

The project's README from github.com/strands-labs/strands-decider. As one markdown file: README.md.

Strands

Strands Decider

A small, fast decision model for agentic AI.

Commit Activity Open Issues Open PRs Discord

Strands decider is one of a new class of decision models, or "system one" models. Unlike an LLM, which can generate arbitrary text, a decision model picks between sets of options and rates things on a scale. This class of model works best for problems that fall between LLMs and traditional classification models: it is a general-purpose classification and scoring model that responds faster than an LLM and does not take the time and expertise to train that a traditional classifier does. That makes it a natural fit for the decisions inside agentic workflows built with the Strands Agents SDK.

Getting Started

The easiest place to get started is through the strands-decider cli:

pip install strands-decider

On an Apple-silicon Mac, --device mlx runs the model through MLX, 1.4 to 1.6x faster than MPS. It needs the mlx extra, which ships with the next release; until then, install from a clone with pip install -e ".[mlx]". The cuda, mps and cpu extras name the other devices (docs/inference.md).

Choice question

You can ask the model to choose based on some state and a question:

strands-decider ask StrandsAgents/strands-decider-2B-hobson-v19 \
  --state "Help! My payouts have been failing for 3 days! " \
  --choice "Which team should handle this?=billing,sales,retail" 

Example Output:

choice_0 -> billing (confidence 0.768)
  billing                  0.845
  retail                   0.091
  sales                    0.064

Noul question

You can also ask the model a Yes/No question:

strands-decider ask StrandsAgents/strands-decider-2B-hobson-v19 \
  --state "Help! My payouts have been failing for 3 days! " \
  --noul "Does this convey urgency?" 

Example Output:

noul_0 noul = 0.828

Closer to 1 is leaning more toward Yes

Score question

Or give a question a score:

strands-decider ask StrandsAgents/strands-decider-2B-hobson-v19 \
  --state "Help! My payouts have been failing for 3 days! " \
  --score "How frustrated is the writer?=calm,frustrated,depressed"

Example Output:

score_0 score = 1.10 (confidence 0.518)
  0: calm                                     0.163
  1: frustrated                               0.573
  2: depressed                                0.265

Multiple question types

You can combine multiple questions into a single command. This is more efficient as you only need to load the state for the model once:

strands-decider ask StrandsAgents/strands-decider-2B-hobson-v19 \
  --state "Help! My payouts have been failing for 3 days! " \
  --choice "Which team should handle this?=billing,sales,retail" \
  --noul "Does this convey urgency?" \
  --score "How frustrated is the writer?=calm,frustrated,depressed"
Example Output
noul_0 noul = 0.829
choice_0 -> billing (confidence 0.769)
  billing                  0.846
  retail                   0.090
  sales                    0.064
score_0 score = 1.10 (confidence 0.519)
  0: calm                                     0.163
  1: frustrated                               0.574
  2: depressed                                0.263

Running as a server

You can also run the model as a server, and ask questions via http requests:

strands-decider serve StrandsAgents/strands-decider-2B-hobson-v19 --port 8000
curl -s localhost:8000/v1/systemone \
  -H 'content-type: application/json' \
  -d '{
    "state": "Help! My payouts have been failing for 3 days!",
    "questions": {
      "is_urgent": {"type": "noul", "instructions": "Does this convey urgency?"}
    }
  }'
Example Output
{
  "model": "strands-decider-2B-hobson-v19",
  "answers": {
    "is_urgent": {
      "type": "noul",
      "noul": 0.8277
    }
  },
  "usage": {
    "input_tokens": 86,
    "output_tokens": 1
  },
  "latency_ms": 140.03
}          

About the model

strands-decider-2B, the first model of the family, has 1.9 billion parameters. It answers a question in a median 115 ms on an RTX 3090 and also serves on an Apple-silicon Mac or on CPU, and many questions about one text are cheap, because the text is read once and each question adds only its own tokens (docs/inference.md). Its accuracy and calibration are measured on JevBench, a third-party benchmark for this class of model (Performance).

Model Architecture

The core idea: take a pretrained decoder LLM torso (Qwen3.5-2B-Base), discard its language-modelling head — taking away its ability to generate text — and replace it with a small pointer head of about a million parameters. The head scores each option by comparing the hidden state at the <answer> position against the hidden state at that option's own last token. One forward pass, no generation, no decoding loop. The torso is adapted with a rank-16 LoRA adapter, and the head runs in fp32.

Because the head holds no per-option parameters, nothing can learn that "the first option is usually right", nothing caps how many options a question may carry, and label sets are defined by the request rather than baked into the weights. Three question types come out of the same masked softmax, read back differently: noul (yes/no), choice (one of N) and score (an ordered rubric).

As you browse the research, you will find that this is the second major iteration of the architecture. The first used a slot head, which mapped the final hidden state to a fixed set of slots and performed significantly worse. Every change since is captured in the research so you can follow along with the work. The reference model today is v19; v20 is the most recent experiment and did not displace it (The research). docs/architecture.md has the full design, the training objective, and the decisions behind them.

Performance

Three targets matter: accuracy, calibration and latency. v19 measures:

Measurement v19 Source
JevBench v1 public set, 231 tasks, accuracy 0.723 (167 of 231) evaluation/README.md
JevBench Brier score / expected calibration error 0.342 / 0.052 evaluation/README.md
Tiers (this repository's split of the public tasks): easy / standard / hard 1.000 / 0.875 / 0.505 evaluation/jevbench.md
Latency per JevBench question, RTX 3090 under WSL2, median / 95th percentile 115 ms / 299 ms evaluation/results.md
Latency per question, M3 Pro (Apple silicon), warm median, under 300 tokens / all tasks 153 ms / 234 ms evaluation/results.md

Every task in the easy tier is answered correctly, and the nearest comparison is decider-2b, which shares v19's torso with a different recipe (evaluation/jevbench.md).

The JevBench figures are at the 3072-token window the run was preregistered at; the recipe saves a 4096-token window, at which v19 scores 168. And 231 tasks are few: six retrains of the v17 recipe had a standard deviation of 3.2 tasks, so treat a difference under about 10 tasks between two single runs as unresolved. evaluation/README.md has the scripts and the limitations, and links the results by version and the board position with its caveats.

Why 2B?

Two reasons. First, experimentation: at 1.9 billion parameters you can serve the model, and retrain the whole recipe, on hardware you already have — about 11 hours on one RTX 3090, and serving works on an Apple-silicon Mac. That makes trying an idea fast and low-risk. Second, ~2B parameters looks like a sweet spot: small enough to experiment with, large enough to do meaningful work.

What can I do with it?

The decisions inside an agentic workflow are the natural target:

Trying it in an Agent

The repository includes a worked example of strands decider inside a Strands agent, under examples/strands/: a before_tool_call intervention that gates a weather-tool call on two yes/no decisions, so the agent asks which city instead of guessing. See the example's README for setup and the walk-through.

Training

Two entry points, both on a Linux or WSL2 host with NVIDIA GPUs and the training environment of training/README.md (the train extra, the pinned torch and flash-linear-attention):

About 11 hours on one RTX 3090 (24 GiB), or 1 hour 10 minutes on eight H100s with FAST=1. training/README.md has the setup, the stages, the settings and the hardware notes; data/sources.md lists every source and its licence, and data/README.md states the reproduction contract.

The research

The record of the work is in the repository. Since v9, every training run states its predictions and its failure conditions before training, and the outcome is appended after the run without editing what came before. By that rule, a run that misses its bar does not replace the reference model; five runs were promoted by the maintainers' decision anyway, and the record says so. Most runs missed their bar, v20 among them: 169 of 231 at the 4096-token window against v19's 168, inside the retrain noise, with four predictions failed. research/README.md lists each run and its outcome, and research/history.md tells what moved the benchmark and what did not. To propose an experiment, open an issue with a preregistration (CONTRIBUTING.md).

Community

To ask questions and talk about Strands Decider, join the Strands Decider channel on Discord.

License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

Security

See CONTRIBUTING for more information.

strands-decider (strands-labs/strands-decider)

Searching Database…

What is this?Strands Decider is a small, fast 'system one' decision model built for agentic workflows. Instead of generating free text like an LLM, it picks between a set of options or rates something on a scale, and returns a calibrated confidence score for every decision.
Is this a chatbot or LLM, or something different?It is not generative: the architecture takes a pretrained LLM torso (Qwen3.5-2B-Base), discards its language-modelling head entirely, and replaces it with a tiny 'pointer head' that scores options in one forward pass — it can only choose, rate, or answer yes/no.
How do I get it running?Use the strands-decider CLI to ask choice, yes/no ('noul'), or score questions directly, or run the model as an HTTP server and query it over requests.
How accurate and reliable are its decisions?On JevBench's 231 public tasks the reference model (v19) scores 72.3% accuracy, with a Brier score of 0.342 and expected calibration error of 0.052; answers given at 0.9+ confidence are right about 95% of the time, but differences under roughly 10 tasks between two runs are just retrain noise, not real progress.
Who is this meant for, and where does it fit alongside the Strands Agents SDK?It targets developers building agentic workflows who need fast, cheap decisions — model routing, tool selection, argument checking, triage, or guardrail checks — instead of calling a full LLM for every small choice; it plugs directly into agents built with the Strands Agents SDK.
Can I fine-tune or retrain the model myself?Yes — training/recipe.sh runs the full pipeline (build corpora, train, calibrate, evaluate) on one to eight NVIDIA GPUs, taking about 11 hours on a single RTX 3090 or roughly 70 minutes on eight H100s.
What can I actually use it for inside an agent?Typical uses are model routing, tool selection, argument checking, triage, guardrails/safety classification, and cheaply scoring an LLM's output instead of calling another LLM.
Is there a working example with the Strands Agents SDK?Yes — examples/strands/ shows a before_tool_call hook that uses two yes/no decisions from the decider to stop an agent from guessing a city before calling a weather tool.
Why build a 2B-parameter model instead of something bigger?At ~1.9B parameters the whole recipe can be retrained on hardware you already own (about 11 hours on one RTX 3090), making experimentation fast while staying large enough to do meaningful work.
Size
30 MB
Stars
669
Updated
CommitOct 16
Age
19d
Commits · 90 Days