Choices, calibration, and review
September 17, 2026 ยท View on GitHub
Choice(question, labels) accepts an ordered mapping from names to descriptions.
For API providers, see provider setup, score modes, and calibration.
The MLX backend assigns and validates a single-token code for each of 2โ26 labels.
The tested default is Qwen3-4B-Instruct-2507, 4-bit MLX on Apple Silicon.
model.choose(text, choice) returns a Decision:
| Field | Meaning |
|---|---|
scores | Normalized scores over supplied candidates |
score_source | next_token_logits, api_token_logprobs, or verbalized_json |
calibrated | Whether a compatible calibration artifact was applied |
raw_winner | The highest-scoring label, before abstention |
selected_winner | The actionable label, or None when abstaining |
candidate_mass | Probability of the exact candidate code tokens; None for JSON estimates |
threshold | Applied threshold, if any |
timings | Preparation, model and total timings |
Use decision.to_dict() for JSON serialization. Large candidate scores can occur
when total candidate mass is small; neither quantity guarantees correctness.
Calibrate on your data
Copy examples/issue_triage.json and replace its question, label descriptions,
provenance and examples. Keep separate calibration and test arrays with unique
IDs and texts, and correct labels. Validate the labels with domain knowledge.
For the local MLX backend, run decisionbridge benchmark --dataset PATH --output reports/my-run.json.
It fits a temperature on calibration examples, writes
reports/my-run.calibration.json, and evaluates the separate test set. Choose a
threshold before inspecting final test labels, or use a separate validation split.
from decisionbridge.calibration import TemperatureCalibration
calibration = TemperatureCalibration.load("reports/my-run.calibration.json")
decision = model.choose(text, choice, calibration=calibration, threshold=0.8)
if decision.abstained:
print("Request review")
else:
print("Route to:", decision.selected_winner)
Here model, text, and choice are your configured model, input, and exact choice
definition. See the complete bundled example.
Model revision, prompt, and label schema must match the artifact. Changing label
order, descriptions or question requires new calibration and evaluation.
A threshold can also be applied to raw scores, which remain uncalibrated. Accepted predictions can still be wrong. The library does not automatically call another model, send messages, or perform a business action.
Offline and input limits
After downloading the default model, use MLXDecisionModel(offline=True) or the
CLI's --offline. Alternative checkpoints must be MLX-compatible and pass code
tokenization checks; universal compatibility is not promised. Offline custom models
require an explicit cached revision. Inputs above 8192 tokens are rejected rather
than silently truncated.