Decision Reference
Jev Primitives: Choice vs. Score vs. Noul Decision Guide
Compare TypeSafe Jev's three decision primitives—Choice, Score, and Noul—including return structures, probability semantics, and selection rules.
TypeSafe Jev does not generate freeform text; it answers typed questions using exactly three primitives: Choice, Score, and Noul.
- Use
Choicewhen you need to select one categorical label from an unordered list of 2 to 255 options (such as routing a ticket to"billing","support", or"security"). - Use
Scorewhen your decision falls on an ordered rubric of 2 to 10 ranked tiers (such as rating an incident severity as"low","medium","high", or"critical"). - Use
Noulwhen evaluating an isolated boolean condition or predicate that returns a calibrated probability between 0.0 and 1.0 (such as"Does this refund request exceed policy limits?").
Primitive Comparison Matrix
| Property | Choice | Score | Noul |
|---|---|---|---|
| Question Type | Categorical classification | Ordinal grading / ranking | Boolean predicate evaluation |
| Answer Space | Unordered set of 2–255 options | Ordered scale of 2–10 levels | Binary state (True / False probability) |
| Return Schema | type: "choice"choice: stringconfidence: floatprobabilities: Record<string, float> | type: "score"score: floatlegend: Record<string, string>confidence: floatprobabilities: Record<string, float> | type: "noul"noul: float (0.0 to 1.0) |
| Probability Semantics | Sum of probabilities across options = 1.0. confidence reflects distribution peakedness. | Sum of probabilities across levels = 1.0. score is the continuous expected level value. | Direct estimated probability of the condition being true. |
| Configuration | instructions: stringcriteria: Record<string, string> | string[] | instructions: stringcriteria: string[] | Record<string, string> | instructions: stringcriteria?: { true?: string, false?: string } |
| Best Used For | Router dispatch, department triage, intent picking | Priority queues, risk assessment, tiered evaluation | Binary flags, guardrail tripwires, fraud alerts |
1. Choice: Categorical Selection
Use Choice when picking from mutually exclusive categories where there is no natural order between options.
What it Returns
{
"department": {
"type": "choice",
"choice": "billing",
"confidence": 0.942,
"probabilities": {
"billing": 0.942,
"support": 0.041,
"sales": 0.017
}
}
}
type: Fixed string identifier"choice".choice: The option key with the highest assigned probability.confidence: The peakedness of probability concentrated on the top option (approaching 1.0 when certain; approaching 0.0 when evenly split).probabilities: A key-value dictionary mapping every option to its assigned floating-point probability.
Python Example
from typesafe_sdk import TypeSafeClient, Choice
client = TypeSafeClient()
response = client.system_one(
model="jev-latest",
state={"lead_role": "VP of Engineering", "company_size": 250},
questions={
"account_segment": Choice(
instructions="Assign this inbound lead to the appropriate sales tier.",
criteria={
"smb": "Companies with under 50 employees",
"mid_market": "Companies with 50 to 500 employees",
"enterprise": "Companies with over 500 employees",
"disqualified": "Students, personal email domains, or non-commercial accounts"
}
)
}
)
segment = response.answers["account_segment"]
print(f"Assigned: {segment.choice} ({segment.confidence:.1%})")
# Example illustrative output: Assigned: mid_market (95.1%)
2. Score: Ordinal Evaluation
Use Score when options have a clear hierarchy, progression, or intensity. While Choice treats options as independent categories, Score evaluates where an input lands along an ordered progression.
What it Returns
{
"bug_severity": {
"type": "score",
"score": 2.85,
"confidence": 0.76,
"legend": {
"0": "p4_minor: internal or cosmetic",
"1": "p3_moderate: non-critical service degraded",
"2": "p2_major: core feature down for partial users",
"3": "p1_critical: company-wide outage or auth failure"
},
"probabilities": {
"0": 0.01,
"1": 0.03,
"2": 0.06,
"3": 0.90
}
}
}
type: Fixed string identifier"score".score: A continuous floating-point number representing the expected level value ($\sum i \times p_i$) across the level indices ($0 \dots N-1$).confidence: The peakedness of probability concentrated on a single level.legend: A key-value dictionary mapping level index strings to their criteria descriptions.probabilities: A key-value dictionary mapping level indices to their assigned probabilities.- Note:
scoreis a continuous float, not a categorical string, and there is no separatescore_indexreturn property.
TypeScript Example
import { score, TypeSafeClient } from "@typesafe-ai/sdk";
const client = new TypeSafeClient();
const result = await client.systemOne({
model: "jev-latest",
state: {
incident: "Primary auth endpoint returning 500 errors to 40% of European traffic",
},
questions: {
urgency: score("Grade incident severity according to blast radius and user impact.", [
"p4_minor: internal or cosmetic",
"p3_moderate: non-critical service degraded",
"p2_major: core feature down for partial users",
"p1_critical: company-wide outage or auth failure",
]),
},
});
const urgency = result.answers.urgency;
console.log(`Expected Score: ${urgency.score.toFixed(2)} (Confidence: ${urgency.confidence.toFixed(2)})`);
3. Noul: Calibrated Predicate Probability
Use Noul when you need an isolated, binary judgment. Jev evaluates a predicate condition directly and returns a calibrated probability between 0.0 and 1.0.
Unlike boolean flags in standard LLMs that generate "true" or "false" strings, Jev returns the direct estimated probability that the stated condition holds true.
What it Returns
{
"requires_legal_review": {
"type": "noul",
"noul": 0.914
}
}
noul: A single floating-point number between 0.0 and 1.0 representing the calibrated likelihood that the instruction is true. Notice that the raw API response does not include a booleanresultfield or a separateconfidenceproperty—application code decides the cutoff threshold.
Python Example
from typesafe_sdk import TypeSafeClient, Noul
client = TypeSafeClient()
response = client.system_one(
model="jev-latest",
state={
"pull_request": "Refactor auth middleware to allow anonymous read tokens",
"author": "external_contributor",
"files_touched": ["auth/jwt.py", "routes/admin.py"]
},
questions={
"is_security_sensitive": Noul(
instructions="Does this pull request modify authentication, authorization, or admin route security logic?"
)
}
)
prob = response.answers["is_security_sensitive"].noul
print(f"Security probability: {prob:.2%}")
# Enforce deterministic gating in application code
if prob > 0.80:
block_merge_and_request_security_review()
Common Overlaps and How to Choose
Should You Use Choice with Two Options or Noul?
If you have a binary question like "Is this spam?", developers often wonder whether to define a Choice with ["spam", "not_spam"] or a Noul.
- Use
Noul: When you need a single calibrated probability to branch on with numerical thresholds (if prob > 0.85:).Noulis simpler to configure and returns an unambiguous likelihood without requiring paired option keys. - Use
Choice: Only when both options have distinct, asymmetric criteria definitions that need separate semantic descriptions.
Should You Use Choice or Score for Priorities?
If you need to rank tickets as "low", "medium", or "high":
- Use
Score:Scoreinforms Jev that options represent an ordered progression. However, per TypeSafe's jaggedness notes,jev-1.13score level calibration is weak: do not assume probabilities always distribute smoothly across adjacent indices or treat the continuous score as a fine-grained measurement. - Do not use
Choicefor ordinal tiers: If you pass["low", "medium", "high"]intoChoice, Jev evaluates them as independent categories without awareness of their progression.
Related Context
Writing Instructions, Criteria, and Answer Spaces for Jev
workflowUnderstanding Confidence Scores and Calibrated Probabilities
conceptJev API Reference & Schema Specification
implementation