Create your own
Lesson illustration

Defining Noul Questions for Precise Probability Estimates

Good to see you again. You have now used Choice for mutually exclusive operational paths and Score for an ordered degree such as customer frustration. A Noul addresses the third answer shape: one precise proposition whose useful output is the probability that it is true.

In this lesson, you will design Noul questions for support automation, with particular attention to defining exactly what “yes” and “no” mean. The aim is not merely to produce a boolean-like value, but to produce a probability your TypeScript application can interpret consistently.


Noul: one proposition, one probability

A Noul question asks, in effect: “Given this state, how likely is this proposition to be true?”

Examples:

  • “Does the customer explicitly request a refund?”
  • “Does customer_message ask to speak with a human support agent?”
  • “Does the resume mention production experience with distributed systems?”
  • “Does the message contain personal data?”

The result is a single field, noul, between 0 and 1:

  • Near 1: strong evidence for yes
  • Near 0: strong evidence for no
  • Near 0.5: the supplied evidence leaves yes and no similarly plausible

This differs from the primitives you used previously:

NeedBest primitiveExample
Select one known categoryChoiceWhich team should receive this ticket?
Locate evidence on an ordered scaleScoreHow frustrated does the customer sound?
Evaluate one bounded propositionNoulIs the customer asking for a human?

A Noul is not a vague “rating.” For example, “Is this candidate strong in Python?” is a poor Noul unless strong has an operational definition. A value around 0.5 would mean uncertainty about yes versus no; it would not mean medium skill. If you need levels of skill, use a Score.

Read the official Noul documentation now. It establishes the response semantics and the optional criteria that become important at subtle decision boundaries.

Noul - TypeSafe AI

Read “Noul” from TypeSafe AI for the core contract of this primitive: a binary proposition in, a probability of yes out.

Begin with the opening explanation under “Noul,” then read “Writing a Noul question” and “Response.” In “Writing a Noul question,” focus on the question contract: one question, with criteria only when they clarify a real boundary. In “Noul does not return a separate confidence value,” read how probability is interpreted. Finally, in “Tips and advanced usage,” note the alternative statement phrasing.

The key product-design constraint is that a Noul must have a meaningful no. If the no case is unclear, then the probability will be unclear too.


Start from the application contract

Suppose a support product must honor an explicit request to leave automation and speak to a person. It would be tempting to ask:

“Does this ticket need human escalation?”

That is not yet a well-defined Noul. “Needs escalation” can depend on urgency, account tier, policy, safety risk, sentiment, prior contacts, and available staffing. It hides several independent judgments inside a phrase that your code cannot audit.

Instead, define the narrow linguistic proposition relevant to this stage:

“Does the customer explicitly ask to speak with a human support agent?”

This question has a crisp decision boundary:

MessageIntended answerWhy
“Can I speak to a real person?”YesExplicit request for a human.
“Please connect me to an agent.”Yes“Agent” unambiguously means a support person in this product context.
“I need help as soon as possible.”NoUrgency is not a request for a human.
“Please escalate this bug.”No, under this contractThe customer asks for escalation, not specifically a human conversation.
“This bot is not helping.”Boundary caseIt may imply dissatisfaction, but does not explicitly request a person.

The last two rows are where teams often accidentally change product behavior through vague wording. You may legitimately decide that “escalate” should count as a request for a person—but then state that rule directly in the proposition or criteria.

A useful design sentence is:

Yes means this observable condition is satisfied; no means it is not satisfied by the evidence in the state.

That is more reliable than starting with a hoped-for threshold or a generic classification label.

The Jev Playground evaluates two independent Noul propositions from a Japanese support message: whether the customer is asking for a human agent and whether they have contacted support about the issue before. Each result is a high probability that the proposition is true.

The Playground image also illustrates a valuable pattern: “asking for a human” and “repeat contact” are different claims. They can both be true, but neither logically contains the other. Keeping them separate gives your application evidence it can later combine according to policy.


Build a precise Noul definition in TypeScript

Continue with a compact support-ticket state. This question is about the customer’s wording, so the relevant evidence is the message itself.

const state = {
  customer_message:
    "I've contacted support three times already. Please connect me with a real person.",
} as const;

Now define the question. The question ID, is_human_escalation, is for your application to retrieve the response. It is not a substitute for a complete instruction: Jev still needs the proposition spelled out.

type NoulQuestion = {
  type: "noul";
  instructions: string;
  criteria?: {
    true: string;
    false: string;
  };
};

const questions = {
  is_human_escalation: {
    type: "noul",
    instructions:
      "Does `customer_message` explicitly ask to speak with a human support agent?",
    criteria: {
      true:
        "The customer explicitly asks for a person, human agent, live representative, or equivalent human support contact.",
      false:
        "The customer does not explicitly ask to speak with a person. Requests for help, urgency, a status update, technical escalation, or a different resolution do not by themselves count as a request for a human.",
    },
  },
} as const satisfies Record<string, NoulQuestion>;

Several design decisions make this definition useful:

  1. The question points to the relevant field.
    Backticked paths such as customer_message specify what part of a larger state Jev should judge. In a state containing a full ticket, account record, policy, and event history, this prevents irrelevant data from silently influencing a simple language judgment.

  2. “Explicitly” establishes the intended boundary.
    Without it, an unhappy message might be treated as an implicit request for a person. That may be appropriate in some products, but it should be a deliberate policy choice rather than an accidental interpretation.

  3. The true criterion gives semantic synonyms.
    Customers may say “human,” “representative,” “real person,” “live agent,” or “someone from your team.” The criterion makes the product’s intended meaning visible and reviewable.

  4. The false criterion names tempting but excluded evidence.
    “Urgent,” “help,” and “escalate” are commonly associated with human handoff, but they express different ideas. Naming exclusions is often more valuable than adding more examples of obvious yes cases.

  5. The question does not prescribe the action.
    “Is the customer requesting a human?” is a model judgment. “Route to a human agent” is deterministic application policy. Keeping them apart lets you alter routing policy without rewriting the meaning of the question.

Criteria are optional. For a straightforward proposition, this is sufficient:

const isRefundRequested = {
  type: "noul",
  instructions: "Does `customer_message` request a refund?",
} as const;

Add criteria when your team needs to clarify terminology, inclusions, exclusions, or a policy-sensitive boundary. Adding generic criteria such as “true means yes; false means no” contributes nothing.


Avoid turning a Noul into a disguised workflow

A weak Noul often sounds like a full support-manager decision:

const weakQuestion = {
  type: "noul",
  instructions:
    "Should this customer be escalated because they are angry, urgent, and have contacted us repeatedly?",
} as const;

This has several problems:

  • It combines emotional expression, urgency, contact history, and a business action.
  • A high value does not tell you which condition caused it.
  • Your team cannot change the importance of repeat contact without rewriting the model question.
  • It is difficult to label consistently for evaluation later.

A better Noul isolates one proposition:

const isRepeatContactMentioned = {
  type: "noul",
  instructions:
    "Does `customer_message` state that the customer has previously contacted support about this issue?",
  criteria: {
    true:
      "The customer explicitly mentions a prior contact, prior ticket, previous attempt to get support, or that they have already asked about the same issue.",
    false:
      "The message contains no indication that the customer previously contacted support about this issue.",
  },
} as const;

Notice the deliberate wording: states that. This asks Jev to classify language in the message.

If your backend has a trusted, normalized field such as:

const previousContactCountForSameIssue = 3;

then whether there has been repeat contact is no longer an AI question. It is deterministic application logic:

const isRepeatContact = previousContactCountForSameIssue > 0;

Use Noul for a bounded judgment over unstructured or ambiguous evidence. Use ordinary code when the answer already exists as reliable structured data.


Read the response without inventing confidence

A Noul response has one central value:

const answer = {
  type: "noul",
  noul: 0.98,
} as const;

For the human-escalation proposition, noul: 0.98 means Jev assesses a 98 percent probability that the customer explicitly asked for a human agent.

It does not mean:

  • that the customer is “98 percent escalated”;
  • that 98 percent of all customers need an agent;
  • that the ticket has a separate confidence score of 98 percent;
  • that your application must automatically route the ticket.

Unlike Choice and Score, Noul does not return a separate confidence field or a probability map. Its probability is already the yes-side probability for one binary proposition. A value close to 0.5 is the signal that the supplied state and question leave the two outcomes hard to distinguish.

Keep the raw value even if your immediate business logic needs a discrete action. For example, this is a reasonable shape of a policy:

type EscalationAction =
  | "route_to_human"
  | "manual_review"
  | "continue_automation";

const escalationPolicy = {
  routeToHumanAt: 0.8,
  continueAutomationAt: 0.2,
} as const;

function chooseEscalationAction(noul: number): EscalationAction {
  if (noul >= escalationPolicy.routeToHumanAt) {
    return "route_to_human";
  }

  if (noul <= escalationPolicy.continueAutomationAt) {
    return "continue_automation";
  }

  return "manual_review";
}

The numeric thresholds above are examples, not universal defaults. Their correct values depend on the consequences of ignoring a genuine human request, the cost of unnecessary handoff, and the availability of a review queue. Later in the course, you will select thresholds using labeled examples and explicit error costs.

For now, the important architectural move is to preserve both pieces:

const decisionRecord = {
  human_escalation_probability: answer.noul,
  action: chooseEscalationAction(answer.noul),
} as const;

The probability records Jev’s bounded judgment. The action records the deterministic policy your product applied to that judgment.


A compact review procedure for every Noul

Before sending a Noul into a live workflow, review it from four angles.

1. Proposition check

Can the instruction be answered with exactly yes or no?

Good:

“Does customer_message explicitly request a refund?”

Weak:

“How much does the customer need a refund?”

The weak version has no stable binary boundary.

2. Evidence check

Can the state actually support the claim?

If you ask whether a customer is a repeat contact, provide either the message that mentions prior contact or a structured count. Do not expect Jev to infer unseen ticket history from an isolated message.

3. Independence check

Does the question contain only one proposition?

“Is the customer angry and requesting a refund?” has four possible truth combinations. Split it into two Nouls if both signals matter.

4. Action check

Can your code explain what it does at high, middle, and low probabilities?

The Noul should not hide the policy. Your code should make the policy legible: route, review, continue, flag, or record for analytics.

A small set of boundary cases belongs beside the question definition in your repository or evaluation dataset:

Customer messageExpected tendencyWhat it verifies
“Please connect me to a live agent.”High yesDirect phrasing.
“I need an answer today.”Low yesUrgency is excluded.
“This is my third ticket about the same problem.”Low yesRepeat contact is separate from human request.
“The chatbot cannot solve this. Can I talk to someone?”High yesNatural indirect wording for human handoff.
“Escalate my case to the billing team.”Low or uncertain, by contractTeam escalation is not automatically a request for a human conversation.

These cases make the question’s actual product meaning testable before a threshold turns it into automation.


A Noul is Jev’s primitive for a single, operationally meaningful proposition:

  • write one complete yes-or-no claim in instructions;
  • ensure the state contains evidence relevant to that claim;
  • use optional true and false criteria to define genuine semantic boundaries;
  • read noul as the probability of yes, not as a separate confidence value;
  • let deterministic code own the eventual action and threshold.

You now have two independently defined signals for a support workflow: an explicit request for a human and a stated prior contact. Next, you will generalize this pattern by decomposing compound business judgments into several atomic questions and combining their answers in deterministic application logic.

Can't find a good explanation? Sign up and we'll make it for you

Sign up