How a decision model works

You send the situation and the answers you will accept. It sends back how likely each answer is.

The whole idea in two sentences

You send the model the situation, and the list of answers you are willing to accept.

It sends back how likely each of those answers is. It never writes a sentence, and it can never answer with something that was not on your list.

First, one word that confuses everyone

The API calls your input the state. That word means the situation: what is happening right now. It does not mean the answers.

So there are two different lists in every call, and it helps to name them apart:

What it isWho writes it
stateThe situation, in wordsYou, fresh on every call
optionsThe answers the model may pick fromYou, usually the same every call

Walk through one real decision

Every block below is read straight out of one recorded game: highway, seed 4, decision 1. Nothing here is typed out by hand.

The state: describe the situation in words

This is a car driving on a four lane highway. Before asking anything, you write down what is happening, as plain phrases:

Reading the recording…

Three things worth noticing.

The keys are yours. your_lane and left_lane are names this project invented. The model was never trained on them. You can call them anything, in any structure, as long as a person could read it and understand the situation.

There are no pixels and no raw coordinates. The simulator knows the car is at x=179.63, y=8.0. The model is told “lane 3 of 4” and “car close ahead (20 m)” instead. Turning the raw world into short phrases is your job, and it is the part you control most.

This is the only part that changes between decisions. One second later, left_lane reads “car ahead (36 m), 6 m/s slower than you”.

The question: say what you want decided

A question has a name, a type, and an instruction:

Reading the recording…

action is the name you will read the answer back by. choice is the type, which decides what shape the answer comes back in. The instruction is what you would tell a person who had to make this call for you.

The criteria: list the answers you will accept

For a choice question, the criteria are the options, each with a short description of what it means:

Reading the recording…

This is the part that makes a decision model different from a chatbot. The answer is guaranteed to be one of these five keys. Not a sentence containing one of them. Not a near miss like LEFT or turn left. One of these five, every time.

The options live in the request, not in the model. Nobody trained it on highway driving. You can swap in a completely different set of options on the next call and it will work the same way.

What comes back

Reading the recording…

Read it as a sentence: it wants to keep its lane, it is half considering moving left, and it has essentially ruled out moving right.

That last part is the interesting one. LANE_RIGHT is at 0.01 because the state said there is a car close ahead on the right, 20 metres away. The numbers are not decoration. They are what the model read.

What your code does with it

The simplest thing is to take the highest and act on it. But the numbers let you do better:

  • Act on it when the top option is above a threshold you choose.
  • Ask a human when nothing clears the bar, which is the useful case a chatbot cannot give you.
  • Fall back to a safe default when the call fails or takes too long. In this project the fallback is IDLE: keep the lane, keep the speed.

The whole call, in one place

The same decision, unedited, both halves together. The whole game is replayable in the Arena.

Loading a real decision…

That is the entire interface. Everything else on this site is that call, repeated.

The diagram

One request in, one probability per option out.

Three types of question

These are not three questions. They are three shapes a question can take, and each one changes what you send and what you get back.

TypeUse it forcriteria you sendWhat comes back
choicePick one of NA map of option to descriptionThe chosen key, plus a probability for every option
scoreHow much, on a scaleAn ordered list of rungs, low to highA number on that scale, for example 1.84 out of 2
noulIs this true, yes or noNothing. You send no criteriaA single probability, for example 0.892
A real example of each, from Laya's own documentationmodel card
{
  "department": {
    "type": "choice",
    "instructions": "Which department should handle this request?",
    "criteria": {
      "billing": "invoices, payments, refunds",
      "technical": "bugs, outages, system errors"
    }
  },
  "urgency": {
    "type": "score",
    "instructions": "How urgent is this request?",
    "criteria": [
      "not urgent",
      "soon",
      "critical deadline or blocking issue"
    ]
  },
  "refund_requested": {
    "type": "noul",
    "instructions": "Does the user explicitly request a refund?"
  }
}

All three can go in a single call, and they are answered together.

Why probabilities instead of a sentence

Asking a language model the same thing gets you text you then have to parse, and text can say anything. Here:

  • It cannot answer off the list. No parsing, no retries, no regex that breaks when the wording changes.
  • You get the runner up. “IDLE 0.58, LANE_LEFT 0.31” tells you it was a close call. “IDLE” alone does not.
  • You can set a bar. Act above 0.8, ask a person below it. That is a product decision you can only make if you have a number.
  • It is fast and cheap. No tokens are generated, so there is nothing to wait for. Laya answers in about 33 ms on a GPU.

The two models

Everything above is the interface. The differences are in the models behind it, and both pages answer the same six questions in the same order.

Jev, the closed one you rent. Laya, the open one you download. Side by side, the same answers in two columns.

Both models are days old and changing. Everything here was checked on 23 September 2026 against the sources listed above.