Open Decision Lab

An open, local model for typed decisions.

We are building a small open model that makes typed decisions. You send it a situation as JSON plus a few questions, for example "which team gets this ticket?" or "does this need to happen today?". Each question is yes/no, pick one of a few options, or a score on a scale. For every option you get back a probability.

Under the hood it is Qwen2.5-7B-Instruct with a LoRA adapter and a linear head on top. Each option gets scored against the situation and the scores are turned into probabilities, so there is no free text you have to parse afterwards.

Contents: Example | Numbers | Lures | Limits | Status


Example

A request looks like this:

POST /v1/systemone
{
  "state": {"ticket": "Server down since 3am, customers cannot log in"},
  "questions": {
    "team":   {"type": "choice",
               "instructions": "Which team handles this?",
               "criteria": {"billing": null, "technical": null, "sales": null}},
    "urgent": {"type": "noul",
               "instructions": "Does this need action today?"}
  }
}

And the response. The numbers here are made up, it is only to show the shape:

{
  "answers": {
    "team":   {"type": "choice", "choice": "technical",
               "probabilities": {"billing": 0.03, "technical": 0.95, "sales": 0.02}},
    "urgent": {"type": "noul", "noul": 0.97}
  }
}

We use the same request format as TypeSafe's System One API. If you already have code for their Python SDK, you can point the base URL at a local server and it keeps working.


Numbers

We test on the public benchmark LocalLLaMA/typed-decisions, official test split: 400 cases with 2000 decisions from four workflows (agent traces, customer service, invoices, security incidents). A decision counts as correct if our most likely option matches the label. To make sure our setup is fair, we ran Laya ourselves on the same split and got its published numbers back to the third decimal.

modeltrained on these four workflows?accuracy
always the most common answern/a46.1 %
Laya 421M, zero-shotno36.2 %
ours, zero-shotno53.7 %
TypeSafe Jev (closed)unknown72.7 %
ours, adaptedyes (5370 decisions)75.2 %
Laya 421M, fine-tunedyes76.6 %

The 75.2 % needs a caveat. That model saw training data from the same four workflows. To check how much of it carries over to something new, we trained a second version with the invoice workflow left out completely. On invoices it got 50.0 %. Without any adaptation the model gets 48.2 % there, and the fully adapted one gets 80.4 %. So almost all of the gain came from having seen invoices during training.

What we can say right now: if you have around 1300 labelled examples from your own workflow, an open model on your own machine gets to about the level of a closed API on that workflow.

On workflows it has never seen we are well behind Jev (53.7 % vs 72.7 %). That gap is what we are working on now.


Lures

A lure is a word in the input that points toward the wrong answer. Say a ticket mentions an invoice, but the actual problem is that someone can't log in. Small classifiers and keyword rules get caught by this a lot. We wrote 104 of these cases by hand, split over three sets, and we never train on them.

modelaccuracy on lure cases
Laya 421M (first set, 42 cases)26-29 %
ours (all 104 cases)80-84 %

We like this result a lot. The sets are small though, so we would not read too much into the exact numbers yet.


Limits


Status

This is a research preview. Weights and code are not public yet. We keep a lab notebook where every number on this page is written down along with how we measured it, failed runs included.

Next we want to train on many more workflows and see whether a 7B model can learn to handle workflows it hasn't seen before. If it can't, we will write that up too.


Open Decision Lab, Berlin. Last updated 27 September 2026.