> ## Documentation Index
> Fetch the complete documentation index at: https://docs.krun.ai/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Krun API base URL: https://api.krun.ai. Authenticate server-side with `Authorization: Bearer $KRUN_API_KEY`; never put a Krun API key in browser code.
> Prefer the Python SDK in examples: `pip install krun-ai`, `from krun import Krun`. The TypeScript SDK `@krun-ai/sdk` is not published on npm yet: do not tell users to `npm install` it.
> The only question type is `choice`. `confidence` is the top-1 minus top-2 probability margin, not the probability that the answer is correct. `choice` is null when `abstain` is true.
> Usage reports `input_tokens` only. There are no output tokens.

# Noul

> The probability that a yes/no proposition about the context holds.

**Noul answers a probabilistic yes/no proposition.** You send a context and a proposition about it; Krun returns the
probability that the proposition holds.

## Complete example

<CodeGroup>
  ```bash cURL theme={null}
  curl https://api.krun.ai/v1/decide \
    -H "Authorization: Bearer $KRUN_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "context": "Hi, I have been waiting for 20 minutes. Please let me talk to a real person.",
      "questions": {
        "needs_human": {
          "type": "noul",
          "instructions": "Is the customer asking to speak with a human?",
          "criteria": {
            "true": "Explicitly requests a person or human agent",
            "false": "Does not request human assistance"
          }
        }
      }
    }'
  ```

  ```python Python theme={null}
  from krun import Krun, NoulQuestion

  client = Krun()  # reads KRUN_API_KEY

  result = client.decide(
      context="Hi, I have been waiting for 20 minutes. Please let me talk to a real person.",
      questions={
          "needs_human": NoulQuestion(
              "Is the customer asking to speak with a human?",
              criteria={
                  "true": "Explicitly requests a person or human agent",
                  "false": "Does not request human assistance",
              },
          ),
      },
  )

  print(result.noul("needs_human").noul)  # 0.9967
  ```
</CodeGroup>

Response:

```json theme={null}
{
  "model": "krun-one-v0.3",
  "answers": {
    "needs_human": {
      "type": "noul",
      "noul": 0.996722
    }
  },
  "usage": {
    "input_tokens": 57
  }
}
```

The body always has a `context` (the text to decide on) and a `questions` map. Each question is keyed by an id you
choose (`needs_human` here), and the answer comes back under the same id in `answers`. A request can mix `noul`
questions with [`choice`](/concepts/primitives/choice) and [`score`](/concepts/primitives/score) questions, up to 16.

| `noul`         | Meaning                          |
| -------------- | -------------------------------- |
| close to `0.0` | the proposition is clearly false |
| around `0.5`   | uncertain                        |
| close to `1.0` | the proposition is clearly true  |

Typical propositions:

* **Should retrieve?** "Does answering this question require looking up the knowledge base?"
* **Needs human?** "Is the customer asking to speak with a person?"
* **Likely fraud?** "Does the message describe a payment the customer did not make?"
* **Should retry?** "Did the tool call fail for a temporary reason?"

## Question fields

A `noul` question is one entry of `questions`:

| Field          | Required | Description                                                                                                               |
| -------------- | -------- | ------------------------------------------------------------------------------------------------------------------------- |
| `type`         | Yes      | `"noul"`                                                                                                                  |
| `instructions` | Yes      | The proposition, phrased as a yes/no question (1–1,000 characters).                                                       |
| `criteria`     | No       | `{"true": "...", "false": "..."}`: what counts as true and as false. Either key may be omitted; each is 1–500 characters. |

Without `criteria`, the model decides from the proposition alone:

```json theme={null}
{
  "context": "How do I change the email address on my account?",
  "questions": {
    "needs_human": {
      "type": "noul",
      "instructions": "Is the customer asking to speak with a human?"
    }
  }
}
```

Use `criteria` when the boundary is not obvious from the question alone, for example what counts as "urgent" in your
support policy.

## Reading the answer

`noul` **is** the probability: there is no separate `confidence` field. To act on it, choose a threshold for your
use case: a high threshold (say 0.9) when a false "yes" is expensive, a lower one when a missed "yes" is worse.

```python theme={null}
if result.noul("needs_human").noul >= 0.9:
    hand_off_to_agent()
```

<Warning>
  Krun One's noul probabilities are calibrated on the kinds of propositions it was trained and evaluated on (intents,
  tool fit, moderation and quality properties). On propositions and texts far from those, the ranking usually holds but
  the probabilities can be over-confident. Validate your threshold on a sample of your own data, and send
  [feedback](/guides/feedback) with `expected: {"type": "noul", "value": true | false}`.
</Warning>

## Writing good propositions

* Ask one thing per question. "Is the customer angry and asking for a refund?" is two propositions: use two questions.
* Phrase it about the context, not about the model: "Does the message mention a delivery date?".
* Prefer concrete wording over labels: "Is the customer reporting a card they do not recognise?" beats
  "card\_payment\_not\_recognised?".
