choice. The model also returns a probability for every option in probabilities, and a confidence value for the selected option.
Example questions:
Request structure
The POST request body to the TypeSafe API has a specific structure. The top level has three fields:state, the content to evaluate; model; and questions, a map from question ids you choose to question objects. Each Choice question has the following fields:
type: Always"choice".instructions: The question the model answers.criteria: The answer options, as a map. Each key is an option name and each value is a description of that option.
department in this case. The answer is returned under the same id. The model never sees the question id. The option names and their descriptions are both sent to the model, so write descriptions that separate the options from each other.
Our client SDKs provide typed questions. In Python, the same question is a Choice:
system_one method or the https://api.typesafe.ai/v1/systemone endpoint to call a System One model. The model field selects which model handles the request. How to build with TypeSafe covers where in your code to call it.
Use one of our client SDKs or call the HTTP API directly. If a coding agent is writing the integration for you, install the TypeSafe agent skill first so it knows the request and response shapes.
instructions and each entry in criteria can be a string, an object, or an array. Start with a string. Use an object when a description needs several kinds of guidance, such as what an option covers, what it doesn’t cover, and some examples. See Structured instructions and criteria below and the API reference.Response structure
The response has one entry inanswers per question, under the ids from the request. This is the response to the example request above:
type, each Choice answer has three values:
choice: The option with the highest probability.probabilities: The full probability distribution across every option. The sum of all values is 1.confidence: A number from 0 to 1 computed from howprobabilitiesis spread. A flat shape, with probability spread across several options, means low confidence. A single peak on one option means high confidence.
returns and confidence is 1.0. A ticket that mentions a wrong size and a missing refund would split probability between returns and billing, and confidence would drop.
Good practice: ask more than one question per call
Ask every Choice your code might need in a single request rather than one request per question. Questions are evaluated in parallel. Adding questions barely changes the response time, and the code can ignore answers it doesn’t need. Extra questions still cost tokens. Ask multiple questions together explains this in full; the next section shows five Choices in one call. The same logic applies to the options inside a single Choice. A Choice accepts up to 255 options, and adding options costs a few tokens each, so give the model the full list of teams, categories, or products rather than a shortlist. Add another or none of the above option when the list might not cover every input, so the model can say none of the others fit.
To classify documents through a deep hierarchy or large taxonomy, chain Choice questions level by level. The Hierarchical Classification cookbook shows how to run a beam search over Choice probabilities, keeping the best K candidate paths at each level instead of committing to a single greedy path.
A more complex example
The basic example above routes a ticket to a team. A bigger support system might also need the return reason, the delivery problem, what the customer wants, and the customer’s tone. The request below asks five Choice questions about a ticket that is more ambiguous than the first: it involves three teams and doesn’t say what the customer wants. Two of these Choice questions are speculative:return_reason only matters if the department is returns, and shipping_issue only matters if it’s shipping. The tone question uses null descriptions because the option names are clear on their own.
The TypeSafe response:
- The
departmentanswer isreturnswith a 0.60 probability, butbillinghas 0.38 probability because of the double charge. This lowers the confidence to 0.39. The top option is clear enough to act on, but the second option is not noise. - The
return_reasoniswrong_sizewith a confidence of 1.0, which is expected because it says this clearly in the ticket. - The
shipping_issueanswer is split betweendelayedandother. It’s a speculative question anddepartmentdidn’t come back as shipping, so it can be ignored by the code, as shown in the example code snippet below. - The
requested_resolutionconfidence is 0.16 because of the flat probability distribution of the answers. This is because the customer didn’t say what they want. - The
toneanswer isfrustratedwith a probability of 0.92 and a confidence of 0.88.
wrong_size, sends the billing team a copy, and asks the customer what they want. The code does not use the shipping_issue answer.
One request, five answers, and the routing logic is ordinary if statements. If you later need to know the customer’s language, or which product the ticket is about, add another Choice to TRIAGE_QUESTIONS; the request count stays at one.
The smart home assistant demo evaluates every user request against a long list of Choice questions in one call: the request category, the room, the device, and the action. Most of those questions are irrelevant to any one request and the code ignores them.
Structured instructions and criteria
Start with a one-line description per option. When two options are similar and the model keeps confusing them, describe each one with an object instead of a string. Give it fields for what the option covers, what belongs to a neighboring option instead, and a few example inputs. The two answer options below, return_policy and return_status, are easy to confuse. A ticket about either one can mention returns and refunds, so each option says what it is not for. The response isreturn_status at confidence 1.0:
question, focus, what, not_for, and examples are not part of the API, and none are reserved. You choose them, the same way you choose option names. The model sees the names along with the values, so use short names that label what follows.
