Sections in this lesson
Abstention & Uncertainty
Use ABSTAIN when authorized evidence is insufficient, ask a clarifying question when ambiguity can be resolved, and route to a human when the task exceeds the product scope.
Reviewed: · Content owner: Interview Preparator
What you will learn
- Make abstention a product decision
- Read risk together with coverage
- Do not disguise other failures
Before you start
The flow
- 1.Identify scope
- 2.Inspect evidence
- 3.Apply host control
- 4.Run negative cases
- 5.Compare benign behavior
- 6.Review remaining risks
Does the evidence actually support the claim?
Closed-world experiment: fixed field/value comparison. No natural-language entailment or live model call is performed.
What is the approved retention in days for synthetic plan 1?
Candidate claim
[
{
"key": "retentionDays",
"value": "7",
"sourceId": "DOC-1"
}
]Retrieved source
[
{
"id": "DOC-1",
"tenant": "tenant-a",
"readers": [
"alice"
],
"approved": true,
"deleted": false,
"expiresAt": 2000,
"facts": {
"retentionDays": "7"
}
}
]Make abstention a product decision
Use ABSTAIN when authorized evidence is insufficient, ask a clarifying question when ambiguity can be resolved, and route to a human when the task exceeds the product scope. These are different outcomes, not interchangeable error strings.
A confident-sounding answer is not a calibrated probability. Do not display a numerical confidence badge unless it is tied to a validated measurement process on the relevant domain and population.
Read risk together with coverage
The teaching policy refuses any response containing an unsupported or contradicted structured claim. Its low answer coverage illustrates why eliminating observed answered errors by refusing almost everything is not useful quality optimization.
Measure unnecessary refusal on independently answerable cases and inspect errors in the answered subset. Select thresholds against the task risk and annotation guide rather than copying a universal groundedness percentage.
Do not disguise other failures
Authorization denial is not merely uncertainty. A provider outage or malformed output also needs an operational error path, not a fabricated “no evidence” message. Preserve classifications for diagnosis while keeping sensitive details out of the UI.
The closed-world lab models ANSWER/ABSTAIN only; its source validation and host traces are separate. A real service should explicitly model clarification, human handoff and infrastructure failure before external exposure.
Try it
// Closed-world fact fixtures only. Equality of structured facts is NOT an NLI judge.const object = value => value !== null && typeof value === 'object' && !Array.isArray(value);export function authorizedSources(sources, scope, now) { if (!object(scope) || typeof scope.tenant !== 'string' || typeof scope.user !== 'string' || !Number.isFinite(now)) throw new Error('Invalid trusted scope/time'); return sources.filter(source => source.tenant === scope.tenant && source.approved === true && !source.deleted && source.expiresAt > now && source.readers.includes(scope.user));}export function verifyClaims(claims, sources, scope, now) { if (!Array.isArray(claims) || claims.length > 20) throw new Error('Invalid claims'); const evidence = authorizedSources(sources, scope, now); return claims.map(claim => { if (!object(claim) || Object.keys(claim).sort().join(',') !== 'key,sourceId,value' || ![claim.key,claim.sourceId,claim.value].every(value => typeof value === 'string' && value.length > 0 && value.length <= 200)) throw new Error('Invalid structured claim'); const source = evidence.find(item => item.id === claim.sourceId); const value = source?.facts[claim.key]; return { ...claim, label: value === undefined ? 'INSUFFICIENT_EVIDENCE' : value === claim.value ? 'SUPPORTED' : 'CONTRADICTED' }; });}export function answerPolicy(claims, sources, scope, now) { const labels = verifyClaims(claims,sources,scope,now); return { status:labels.length > 0 && labels.every(item => item.label === 'SUPPORTED') ? 'ANSWER' : 'ABSTAIN', claims:labels };}export function retrievalRecall(relevantIds, retrievedIds) { if (!relevantIds.length) return null; return [...new Set(relevantIds)].filter(id => retrievedIds.includes(id)).length / new Set(relevantIds).size;}export function judgeAgreement(human, judge) { if (human.length !== judge.length) throw new Error('Unpaired annotations'); return human.length ? human.filter((label,index) => label === judge[index]).length / human.length : null;}Run npm run examples:security and npm run eval:security. This source is a deterministic teaching fixture; it does not prove live model safety, NLI, production auth or OS/network isolation.
Interview questions
When should the product abstain or ask a question?
A confident-sounding answer is not a calibrated probability. Do not display a numerical confidence badge unless it is tied to a validated measurement process on the relevant domain and population.
Why is zero answered error insufficient?
Measure unnecessary refusal on independently answerable cases and inspect errors in the answered subset. Select thresholds against the task risk and annotation guide rather than copying a universal groundedness percentage.
Should an outage be presented as no evidence?
The closed-world lab models ANSWER/ABSTAIN only; its source validation and host traces are separate. A real service should explicitly model clarification, human handoff and infrastructure failure before external exposure.
Practice
Extend one negative scenario and its authorized positive counterexample for Abstention & Uncertainty.
Check your solution
- State the trusted input and effect boundary.
- Assert the expected status and observed effect.
- Report coverage and limitations without claiming production readiness.
Official references
Continue learning
Category sequence
AI Reliability & Hallucinations
Lesson 5 / 10
Was this lesson useful?
Change notes: 2026-10-31: security/reliability curriculum and source-bound fixture.