# Choice

Select one option from a defined set. The answer has the chosen option, a probability for every option, and a confidence.

## Request

```json
{"state": "My running shoes arrived in the wrong size.",
 "model": "jepela-latest",
 "questions": {"department": {"type": "choice", "instructions": "Which team should handle this?",
                              "criteria": {"returns": "Exchanges, wrong or damaged items",
                                           "shipping": "Delivery status, delays, lost packages",
                                           "billing": "Charges, invoices, payment problems"}}}}
```

`criteria` is a map of 1 to 255 option names to descriptions. Descriptions may be strings or JSON objects.

Up to 20 options are read in one pass by the engine. **With more than 20, Jepela matches instead of reading** (`"method": "auto"`, the default): the state and each option are turned into vectors by a small embedding model, the options once and then cached, and the closest option wins. The answer has `"method": "match"`, `probabilities` from the similarities, and `similarity` (the best and second-best cosine). Measured on 2026-09-26 on BANKING77 (600 real bank messages, 77 intents that are close to each other) through the gateway: matching 65.2% right in a median of 2 ms, 23 tokens billed; the engine reading all 77 options 62.2% in 209 ms, 812 tokens. On public data matching also picked the right function among 672 far more often than the engine (63.8% against 37.3%, `experiments/stanford/RESULTS.md`).

- `"method": "engine"` makes the engine read every option; above 20 it asks in two rounds, the options in groups of up to 20, then the group winners against each other (8 of 8 right at 40, 80 and 255 options, measured 2026-09-23). The answer then has `"rounds": 2`.
- `"method": "match"` matches every choice question, whatever its size (not score or noul questions).
- Matching reads the state with its memory lines placed first, as the engine would. For short choices read in context (a handful of options, yes/no, scores), the engine stays the default: it judges the situation; matching finds the closest label.
- Write options as short descriptions of what they mean (`"card_arrival": "card has not arrived"`); an option without a description is matched by its name.

The engine is sensitive to the order of the options: the engine's authors report 15 to 23% of answers changing when the options of a 20-option choice are reordered. `"robust": true` asks each choice in up to three fixed orders built from the sorted option names and averages them, so the caller's order no longer matters; the answer has `orders` and `agreement` (the share of orders that picked the winner). A 2-option choice has only 2 orders; `{"orders": n}` sets 1 to 5. Each order is billed as an answer. This applies to choices of up to 20 options: a larger choice is matched (the order does not matter there), or with `"method": "engine"` answered in two rounds, in groups that follow the order you wrote, and is not asked in several orders.

## Answer

```json
{
 "department": {
  "type": "choice",
  "choice": "returns",
  "confidence": 0.249,
  "probabilities": {
   "returns": 0.623,
   "shipping": 0.319,
   "billing": 0.058
  }
 }
}
```

`choice` is the option with the highest probability. `confidence` is reported when the engine computes it (Jepela does); it summarises how concentrated the probabilities are.

## Guidance

- Include `other` or `none_of_these` when the options may not cover the state.
- Keep options mutually exclusive; overlapping descriptions split the probability.
- For deep hierarchies, chain Choice questions level by level, or put the children inside each parent's description so the engine sees the subtree.
- Gate actions on confidence; see Confidence.
- Do not name a forbidden option in a rule you put in memory; see Rules in memory.
