Communicating confidence and uncertainty
Communicate uncertainty in AI features honestly: when to hedge, when to abstain, and why raw confidence scores usually confuse users more than they help.
On this page
Why this matters
Every AI feature is sometimes wrong. What decides whether users keep trusting it is whether the feature seemed sure when it was wrong. An assistant that confidently gives a wrong refund policy damages trust far more than one that says “I’m not certain; here’s the policy page.”
Communicating uncertainty well is hard, because models don’t reliably know when they’re wrong, and the obvious solution, showing a confidence percentage, usually backfires. This article explains why, which signals work better, and how to design an answer that says “I’m not sure” and still helps.
Why model confidence is hard to show
It’s tempting to ask the model “how confident are you, from 0 to 100?” and display the number. The problems:
- Self-reported confidence isn’t reliable. A model’s stated confidence can be poorly matched to how often it’s actually right. A “90% confident” label that’s right half the time is worse than no label.
- Users read numbers as precise. “87% confident” sounds measured. Users either over-trust it or learn to ignore it, and both are bad.
- One number hides the reason. Is the answer uncertain because the sources conflict, because the question is ambiguous, or because the information isn’t there? Each needs a different response from the user.
- It doesn’t say what to do. A percentage leaves users to decide whether 72% is good enough, without the information to decide.
Confidence numbers can work when they come from a measured process, such as a classifier calibrated on your own data, and when users are trained to use them. For most product features, there are better signals.
Better signals than percentages
Instead of asking “how sure is the model?”, show users the evidence behind an answer and the reason for any doubt:
| Signal | What users see | Why it works |
|---|---|---|
| Sources | Citations and quoted passages | Users judge the evidence themselves |
| Coverage | “Based on 2 of the 5 documents you selected” | Shows how much was actually considered |
| Explicit caveats | “The policy changed in March; this reflects the new version” | Names the specific reason for caution |
| Agreement | “These two sources disagree on the deadline” | Surfaces conflict instead of hiding it |
| Status | Answered, partly answered, not enough information | A small, clear set of states with a design for each |
The last row is the most practical starting point. Instead of a continuous confidence score, have the model classify its own answer into a few statuses, each tied to something it can check: did the sources contain the answer, part of it, or none of it?
Abstaining well
Abstaining means the feature declines to answer, or answers only part of the question, when it doesn’t have what it needs. Done badly, it’s a dead end. Done well, it’s one of the most trust-building things a feature can do.
Show text descriptionHide text description
A sequence of yes-or-no questions, asked in order. A "yes" answer stops with the outcome shown; a "no" moves to the next question.
- Do the sources fully answer the question, without conflict? If yes: Answer, with citations.
- Do they answer part of it, or conflict? If yes: Answer what is supported, and say clearly what is missing or disputed.
- Is the question ambiguous? If yes: Ask a short clarifying question, or answer the most likely reading and say so.
If the answer to every question is no: Abstain helpfully: say what is missing and offer a next step.
A helpful abstention has three parts:
- What’s missing: “Your documents don’t include the 2027 pricing.”
- What is known: “They do include 2026 pricing, if that helps.”
- What to do next: “You could upload the 2027 price list, or ask sales.”
Here’s a way to make that structure explicit. The model answers through a schema that includes a status and a list of what’s missing, so your interface can treat each case differently instead of guessing from the prose:
import Anthropic from '@anthropic-ai/sdk';
import { zodOutputFormat } from '@anthropic-ai/sdk/helpers/zod';
import { z } from 'zod';
const client = new Anthropic();
const AnswerSchema = z.object({
status: z.enum(['answered', 'partial', 'not_enough_information']),
answer: z.string().describe('The answer, using only the context. Empty if nothing can be answered.'),
missing: z.array(z.string()).describe('Specific information the context lacks, if any'),
});
export type Answer = z.infer<typeof AnswerSchema>;
export async function answerOrAbstain(question: string, context: string): Promise<Answer | null> {
const response = await client.messages.parse({
model: 'claude-opus-5-5',
max_tokens: 4096,
output_config: { effort: 'low', format: zodOutputFormat(AnswerSchema) },
system:
'Answer only from the context. Use "partial" if the context answers part of the question, and ' +
'"not_enough_information" if it answers none of it. List exactly what is missing. Never fill gaps from memory.',
messages: [{ role: 'user', content: `<context>\n${context}\n</context>\n\nQuestion: ${question}` }],
});
// Refused, truncated or otherwise unfinished: the caller shows its error state rather than a guess.
if (response.stop_reason !== 'end_turn') return null;
return response.parsed_output;
} The interface then has three designed states instead of one ambiguous one: a normal answer; an answer with a clearly marked “not covered” note listing missing; and an abstention that shows what’s missing with next steps. Combined with citations, users always know what the answer rests on.
Calibrating with evals
Statuses are only useful if they’re right. “Partial” should mean the answer really is incomplete; “answered” should be wrong rarely. Check that with your eval set:
- Include unanswerable and partly answerable questions alongside answerable ones, with the correct status for each.
- Measure two failure types separately: confident wrong answers (status “answered” but incorrect), which are the dangerous ones, and unnecessary abstentions (status “not enough information” when the answer was there), which make the feature feel useless.
- Tune the trade-off for your context. For a medical or legal feature, prefer more abstentions. For a brainstorming tool, prefer fewer.
Over time, these numbers let you say something precise and honest to users and stakeholders: “when the assistant says it has answered, it’s correct in our evals 96% of the time.” That’s a far better confidence signal than any percentage the model reports about itself. Rubrics and human grading covers how to grade answers consistently.
Common mistakes
- Showing the model’s self-reported confidence as a number. It’s often poorly calibrated and users read it as precise. Show evidence and clear statuses instead.
- Abstaining with a dead end. “I don’t know” alone frustrates users. Say what’s missing, what’s known and what to do next.
- Hiding conflicts between sources. When sources disagree, say so; picking one silently looks confident and may be wrong.
- Measuring only accuracy. Track confident wrong answers and unnecessary abstentions separately; they have very different costs.
- Letting the model fill gaps from memory. If the feature answers from sources, instruct it to stay within them and flag what’s missing.
Try it
Exercise
About 45 min
Design an abstain state for a feature
- Pick a question-answering or assistant feature.
- Write three example questions: one fully answerable from its sources, one partly answerable, and one not answerable.
- Run them through the
answerOrAbstainfunction with suitable context, and check the status for each. - Design the screen for the “not enough information” case: what’s missing, what’s known, and next steps.
Show a hint
The best next step is specific to your product: a link to upload a missing document, a search, a person to contact, or a narrower question the feature can answer.
Show a worked solution
Example for an HR assistant answering from a handbook:
- Answerable: “How many vacation days do new hires get?” → answered, with a citation.
- Partial: “How many vacation days do new hires get, and can they carry them over?” → answers the first part,
missing: ["carry-over rules"]. - Not answerable: “What’s the 2027 bonus policy?” → not enough information.
Abstain screen: “The handbook doesn’t cover the 2027 bonus policy. It does describe the 2026 bonus structure (link). For 2027, contact your HR partner (link) or check the announcements page.”
Check your understanding
Key takeaways
- Users forgive wrong answers more easily than confidently wrong ones.
- Avoid self-reported confidence numbers; show sources, coverage, caveats, conflicts and clear statuses.
- Abstain helpfully: what’s missing, what’s known, what to do next.
- Calibrate with evals: measure confident wrong answers and unnecessary abstentions separately, and tune for your context.
Progress is saved in this browser and lights up the roadmap.
Related articles
- Error, refusal and empty states Design the unhappy paths of AI features, from API errors and refusals to truncated answers, empty results and timeouts, with copy and recovery for each. Level: Intermediate
- Rubrics and human grading Write rubrics that make AI output gradeable, run human grading sessions, and measure agreement between graders before trusting the scores. Level: Advanced
- Streaming and loading states Design streaming responses and loading states for AI features, from when to stream to skeletons, progress, stop buttons and handling a stream that ends early. Level: Intermediate