> ## 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.

# Abstention

> When Krun One declines to choose, how to handle it, and what calibrated and advisory abstention status mean.

Krun One can decline to answer a question. When it abstains, `choice` is `null` and `abstain` is `true`:

```json theme={null}
{
  "type": "choice",
  "choice": null,
  "confidence": 0.009176,
  "probabilities": {
    "transaction_charged_twice": 0.330275,
    "card_arrival": 0.330275,
    "lost_or_stolen_card": 0.339451
  },
  "abstain": true,
  "abstention_status": "calibrated"
}
```

This answer comes from the context `"What is the weather like on Mars?"` with three banking intents. None of them applies, the probabilities are almost flat, and `confidence` is close to 0.

## When the model abstains

The model abstains when `confidence`, the margin between the two best options, is below the threshold configured for that kind of question. Typical reasons:

* **None of the options applies.** The request is out of scope for your option set.
* **Two options are hard to tell apart.** The context fits both, or the options overlap.
* **The context is too vague** to pick an option.

Abstention is decided per question. In a request with several questions, some answers can abstain while others don't.

## Handling abstention

`probabilities` is still returned when the model abstains, so you can see its best guess. Krun and the SDKs never replace `null` with that guess: what to do is your decision.

<CodeGroup>
  ```python Python theme={null}
  answer = result.answers["intent"]

  if answer.abstain:
      best_guess = max(answer.probabilities, key=answer.probabilities.get)
      escalate(context, suggestion=best_guess)  # human, LLM, or default flow
  else:
      handle(answer.choice)
  ```
</CodeGroup>

Common fallbacks:

* send the request to a human or a general-purpose flow,
* ask the user a clarifying question,
* pass the request and the best guess to an LLM,
* add a missing option to your option set, if abstentions show a gap.

## Abstention status

Every answer includes `abstention_status`. It tells you how much to trust `abstain` for that kind of question:

| Question                                                 | `abstention_status` |
| -------------------------------------------------------- | ------------------- |
| Intent, label-only options (`""` or `null` descriptions) | `calibrated`        |
| Intent, options with descriptions                        | `advisory`          |
| Tool routing (`task_type: "tool"`)                       | `advisory`          |

### Calibrated

For intent questions with label-only options, the abstention threshold was validated on held-out data at a target of 98% accuracy on the answers the model does not abstain on. On data similar to Krun One's evaluation data, answers with `abstain: false` should be correct at about that rate. Your traffic can differ, so monitor it with [feedback](/guides/feedback).

### Advisory

<Warning>
  **Advisory abstention is a hint, not a guarantee.** When `abstention_status` is `advisory`, `abstain: false` does not mean the answer was validated to meet an accuracy target. For tool routing in particular, Krun One v0 still picks a tool for a significant share of requests where no tool applies. Keep your own safeguards, such as argument validation, a confirmation step before side effects, or a "none of these" path.
</Warning>

Advisory status applies to:

* **Tool routing.** Abstention was measured on real "no tool applies" requests and does not yet meet the bar for calibrated. See [Benchmarks](/benchmarks#read-these-numbers-carefully).
* **Intents with descriptions.** This setup has not been calibrated yet.

The status stays advisory until these setups are recalibrated. It is reported per answer, so a request can mix `calibrated` and `advisory` answers.

<Tip>
  For intent routing with the strongest abstention guarantee, use label-only options with descriptive ids, like `transaction_charged_twice`. See [Intent routing](/guides/intent-routing).
</Tip>
