Skip to content

Questions and answers

A Curva request has a state (the data to judge) and one or more typed questions (up to 64). Every question gets a typed answer with probabilities. Answers are only ever mapped onto the labels you declared, never parsed from free text, so there is nothing to validate on your side. Extraction questions (Text, Number, Integer) answer with a value instead, checked against its type and bounds, plus the probability that it is correct.

Type Asks Answer
Choice Pick exactly one option choice (the option key), probabilities per option, confidence
Score Place on an ordered scale score (the expected level, 0 = lowest), probabilities per level, confidence
Noul Yes or no noul = P(yes)
Multi Pick any subset selected (options at or above the threshold), probabilities per option

The four label question types. Choice picks exactly one option and returns a probability for each. Score places the state on an ordered scale and returns the expected level. Noul returns the probability of yes. Multi scores every option on its own and selects those at or above the threshold.

The Choice, Score and Noul values in the picture are the ones in the response below. The Multi bars are an illustration.

Choice("Which team should handle this?",
{"billing": "payments, refunds", "technical": "bugs", "sales": "pricing"})
Choice("Which team?", ["billing", "technical"]) # a list of keys also works

Options map a key to a description (the description may be empty). A Choice takes 2 to 255 options. By default Curva also adds a none_of_these option, so the model is never forced into a wrong pick (see escape option).

Score("How frustrated is the customer?", ["calm", "annoyed", "angry"])

Levels go from lowest to highest (2 to 20 levels). The score is the expected level: with probabilities [0.36, 0.62, 0.02] the score is 0.65, between “calm” and “annoyed”. This keeps the uncertainty visible instead of rounding it away.

Noul("The customer explicitly asks for a refund")

A yes/no question. The answer is a single number, noul, the probability of yes. Internally a Noul is asked as a normalised two-option choice, so P(x) and P(not x) are consistent.

Multi("Which apply?", ["refund", "bug", "complaint"], threshold=0.5)

Each option is scored as its own yes/no, all in the same model call. The probabilities are independent, so they don’t sum to 1. Options with a probability at or above threshold (default 0.5) are in selected. A Multi takes 1 to 20 options.

Type Asks Answer
Text Copy or write a short text value (a string, at most max_length characters, default 200), confidence
Number Read a number, optionally within min..max value (a number), confidence
Integer Read a whole number, optionally within min..max value (an integer), confidence
Text("Who issued the invoice?", max_length=100)
Number("Total amount charged", min=0)
Integer("How many line items?", min=1, nullable=True) # value may be None

confidence is the model’s probability that the value is correct, and it is calibrated from your feedback like any other answer (the feedback label is the true value). nullable=True lets the answer be null when the state has no such value. A reply of the wrong type, out of range, or too long counts as no answer: value: null, confidence: 0.

Extraction questions are answered in verbal mode (there is no label token to read), and they share one call with the label questions of the same request. See the extraction guide.

Curva reads probabilities from the model in one of two modes:

  • logprobs: the model answers with one label token per question, and Curva reads each label’s probability from the token log-probabilities. One request covers every question. If the declared labels hold less than half of the probability at a position, that question is retried on its own.
  • verbal: the model returns a JSON object constrained to the declared labels, with a probability for each one.

The default, auto, uses logprobs when the model returns them and switches to verbal when it doesn’t. The response’s mode field says which one actually answered. Choices with more than 20 options are always answered in verbal mode, because providers return at most 20 logprobs, and so are requests with a Text, Number or Integer question.

{
"id": "dec_19294a3c1f2000000",
"model": "inclusionai/ling-3.0-flash-fin:free",
"mode": "logprobs",
"latency_ms": 1144,
"cost_usd": 0.0,
"cached": false,
"answers": {
"department": { "choice": "billing", "probabilities": { "billing": 0.9999, "technical": 0.0, "sales": 0.0001 }, "confidence": 0.9999 },
"frustration": { "score": 0.65, "probabilities": [0.36, 0.62, 0.02], "confidence": 0.62 },
"refund_requested": { "noul": 0.999 }
}
}

Every answer also carries calibrated, which becomes true once your feedback has fitted a calibrator for that exact question (Probabilities and calibration).

Identical requests are served from a decision cache: cached: true, no model call, and zero latency and cost.

© 2026 Tarkova Private Limited.