Decisions and probabilities

Every capability returns a typed decision plus the numbers behind it: probability, confidence, score, and character offsets.

A capability never returns prose. It returns a decision your code can branch on, plus the numbers behind that decision. This page explains each number, and what it does not tell you.

The API rounds every probability and score to three decimals. Offsets and level stay integers.

The four numbers

NumberReturned byRangeMeaning
probabilityyes-no, classify, answer, verify, and each entity in entities0 to 1How strongly the text supports this decision
confidenceclassify, rate0 to 11 − normalized entropy over all options. 1 is one clear winner, 0 is a flat distribution.
scorerate0 to scale.length − 1Probability-weighted position on the scale
start / endanswer, entitiescharacter offsetsWhere the span sits in your text

scores accompanies classify (an object keyed by label name) and rate (an array in scale order). Both sum to 1.

Probability

probability measures how strongly the text supports one decision. The formula differs per capability.

CapabilityHow probability is produced
yes-no, no hintsThe raw score for the statement. It is not normalized against anything.
yes-no, with when_true / when_falsep_true / (p_true + p_false) over the two hint labels
classifyThe winning label’s share after normalizing all label scores
answer, entitiesThe span’s own confidence. answer returns 0 when the answer is null.
verifyThe confidence of the matching span, or 0 when nothing matches

Two booleans come straight from probability. yes-no sets answer to true at probability >= 0.5. verify sets matches the same way.

A real response, classify over a support ticket, three labels:

{"label":"billing","probability":0.942,"confidence":0.797,"scores":{"billing":0.942,"shipping":0,"account":0.058}}

A yes-no probability without hints is an independent score, not a share of a pair. Do not compare it to a normalized classify probability on the same scale. Set a threshold per capability and per action.

Confidence

confidence is 1 − H(p) / ln(n). H is the Shannon entropy of the normalized scores, and n is the number of options. It measures the shape of the whole distribution, not the strength of the winner.

  • Confidence near 1: one option dominates. The rest are near zero.
  • Confidence near 0: the options split the mass. The winner won by very little.
  • confidence returns 1 when fewer than two options exist.

Read probability and confidence together. A high probability with low confidence means two labels both scored high, and normalization gave one of them the lead.

yes-no, answer, entities, extract and verify do not return confidence. Use probability on those capabilities.

Score and level (rate)

rate returns two views of the same distribution. level is the index of the most likely level. score is Σ p_i · i, the probability-weighted position across the whole scale. rate returns no probability field.

A real response, scale ["Calm","Annoyed","Frustrated","Threatening to leave"]:

{"score":1.585,"level":2,"confidence":0.371,"scores":[0,0.471,0.472,0.057]}

level is 2, but it beat level 1 by 0.001. score 1.585 sits between the two, and confidence 0.371 reports the ambiguity. Use score for trends and sorting. Use level only when confidence is high.

Spans

answer and entities return spans of your input text, never generated words. start and end are character offsets into the text you sent, so you can highlight or redact the exact characters.

A real response, answer over a batch of questions, including one the text cannot answer:

{
"results": [
{"question":"Who announced the product?","answer":"Tim Cook","probability":0.999,"start":0,"end":8},
{"question":"How much does it cost?","answer":"$999","probability":0.989,"start":85,"end":89},
{"question":"What is the CEO salary?","answer":null,"probability":0,"start":null,"end":null}
]
}

When nothing fits, answer, start and end are all null, and probability is 0. Check for null before you slice the text.

entities sorts its spans by start ascending. An entity always carries start and end, never null.

verify returns no offsets. It returns found, the raw spans the model read for that field. Compare found against your value when matches is false.

A real response, verify of the value 4417 against a text that says #4471:

{"matches":false,"probability":0,"found":["#4471"]}

Read the numbers in code

curl -s https://api.milliseconds.ai/v1/decision-machine-1/classify \
-H "Content-Type: application/json" \
-d '{
"text": "I was charged twice for my subscription this month and support has not replied.",
"labels": {"billing": "payments, invoices, charges, refunds", "shipping": "delivery, tracking, returns", "account": "login, password, profile settings"}
}'

That call returns:

{"label":"billing","probability":0.995,"confidence":0.972,"scores":{"billing":0.995,"shipping":0,"account":0.005}}

These numbers differ from the capture at the top of the page, because the label descriptions differ. Label wording moves every number.

No API key is required during the launch period.

What the numbers do not mean

  • They are not measured accuracy. A probability of 0.94 is the model’s score for that decision. It is not a promise that 94 of 100 such decisions are correct. Measure your own rates on a labelled set.
  • They do not transfer between capabilities. A 0.8 from yes-no and a 0.8 from classify come from different formulas. Tune each one separately.
  • They do not transfer between label sets. Change a label, a description, or a hint, and every number moves. Re-check your thresholds after any wording change.
  • confidence is not correctness. It reports the shape of the distribution. A confident wrong label is still wrong, and usually means the label text describes the wrong case.
  • A high classify probability with a tiny label set proves little. Normalization spreads the mass over the labels you sent, and nothing else.
  • extract returns no probabilities. It returns data with null for any value the text does not carry. Use verify when a field must be trusted.

Next