ML Scoring (ONNX)
Score records with an ONNX model inside a rule using model_score.
ONNX (Open Neural Network Exchange) is a portable format for trained models. The model_score operator runs a registered ONNX model over the batch as a derived column and compares its output with an op and value. Model output can therefore participate in the same rule tree as deterministic predicates.
The model_score leaf
model_score leafName the registered model, list the input features in order, and set the threshold:
- model_score:
model: fraud_logreg
features: [amount, account_age_days, merchant.risk.score]
op: gt
value: 0.7This leaf matches when the model's score for a record is greater than 0.7. Features may use dotted names like merchant.risk.score for nested input.
features must reference numeric BlazeRules fields. Categories and text required by a model must be encoded upstream into numeric feature columns before model_score evaluation.
Register the model
Register the ONNX artifact with the engine by name, then reference that name from the rule.
import blazerules
engine = blazerules.RuleEngine()
engine.register_model("fraud_logreg", "models/fraud_logreg.onnx")
engine.load_rules("rules.yaml")
result = engine.evaluate_ndjson(batch_bytes)blazerules eval \
--rules rules.yaml \
--model fraud_logreg=models/fraud_logreg.onnx \
--path events.ndjsonRepeat --model name=path for each model. Model paths may be local or s3://.
- model_score:
model: fraud_logreg
features: [amount, account_age_days, merchant.risk.score]
op: gt
value: 0.7Model files can be loaded from a local path or an s3:// URL, the same as rule files.
register_model(...) can be called before or after load_rules(...). Models are resolved by name when the derived model channel is scored; re-registering a model name swaps the model used by later batches.
One backend, many model types
BlazeRules consumes the .onnx artifact and nothing else. XGBoost, LightGBM, scikit-learn, and neural networks all export to ONNX, so the model author's framework is irrelevant at inference time — export to .onnx and register it.
Both classification and regression models work, and the meaning of value follows the model's output:
- A logistic/classification model ends in a sigmoid (or softmax) and emits a probability in
[0,1], soop: gte, value: 0.8means "≥ 80% confident." - A regression model emits a continuous value in its own units (dollars, a count, a latency), so
op: gt, value: 120compares against that raw prediction.
Multiple models may be registered. Each model_score leaf names one model, and independent models are scored in parallel over the batch.
Predictions are logged and visualized
When the agent receives --model and the ruleset uses model_score, each model's raw per-record prediction is written alongside the decision. Arrow output uses a model.<name> float column; NDJSON output uses a model_scores object. The dashboard presents these values on the Models page as prediction-distribution histograms and filterable per-record tables.
Derived columns are computed once per batch
model_score is a derived column. It is computed once per batch, and only when a rule actually references it. Rules that don't use the model add no inference cost, and there is no per-record interpreter overhead inside the rule tree.
ONNX support is a build option
model_scorerequiresBLAZERULES_ENABLE_ONNX(defaultON). A build with this option disabled rejectsmodel_scorerules during compilation and causesregister_modelto throw. See Error Reference and Troubleshooting.
Model scores are internal derived columns, not public input fields. The rule only sees the model_score predicate result. Missing or null numeric features are passed to ONNX as NaN; if a model is not registered, its feature count does not match, or inference fails, that model channel yields zero scores for the batch instead of throwing mid-batch.
The current ONNX integration feeds a numeric tensor in the exact order listed in features. It does not tokenize text, one-hot encode strings, or build categorical embeddings inside BlazeRules.
Related documentation
Updated about 2 months ago