Confidence Answer UI
An answer that says how sure it is — a warning badge only when there is something to warn about, and a hedge that names what to verify.
npx shadcn@latest add https://scrimui.dev/r/confidence-answer.jsonAgent promptClaude Code · Cursor · any agent
Add the Confidence Answer UI component from the Scrim UI registry to this project and use it in the configuration described below.
Confidence Answer UI — An answer that says how sure it is — a warning badge only when there is something to warn about, and a hedge that names what to verify.
## 1. Install
```bash
npx shadcn@latest add https://scrimui.dev/r/confidence-answer.json
```
This writes a single file to `components/ui/confidence-answer.tsx`. It is plain React + Tailwind with no runtime dependencies — no Radix, no CVA, nothing to add to package.json. If this project does not use the shadcn CLI, copy the source from https://scrimui.dev/components/confidence-answer to the same path by hand; nothing in the file depends on shadcn.
## 2. Use it
```tsx
import { ConfidenceAnswer } from "@/components/ui/confidence-answer";
<ConfidenceAnswer
confidence="medium"
text="The library's `createStream` helper was deprecated in version 3.2 in favour of `streamText`, which takes the same options object."
hedge="I may be off by a minor version — check the changelog for the exact release."
/>
```
## 3. The configuration that matters
This is the component's "Worth double-checking" state — The common case: probably right, with the hedge naming the specific thing that might be off — a version, a date, a number.
Every prop is at its default value. Keep the call site minimal — do not write out default values.
Reference: https://scrimui.dev/components/confidence-answerFollows the props below — change a control and the prompt changes with it, so an agent reproduces that configuration instead of the defaults.
The library's `createStream` helper was deprecated in version 3.2 in favour of `streamText`, which takes the same options object.
I may be off by a minor version — check the changelog for the exact release.
Presets
Props
Component source
Single-file React + Tailwind component. No dependencies — drop it into any project with Tailwind configured.
"use client";
import * as React from "react";
/**
* An answer that says how sure it is.
*
* Language models are wrong in the same tone of voice they are right, and a
* reader has no way to tell which they just got. The fix is not a disclaimer
* under the whole chat ("AI can make mistakes" — invisible by day two); it is
* a qualifier attached to *this* answer, calibrated to *this* claim.
*
* **Badge the uncertainty, not the certainty.** A "high confidence" mark on
* every solid answer trains the eye to skip the badge row entirely, and the
* one answer that needed scrutiny gets it least. High confidence renders as
* quiet text; the badge appears when there is something to warn about.
*
* **The hedge belongs at the claim, not the footer.** `hedge` sits directly
* under the answer, one sentence saying *what specifically* might be off —
* a number, a date, a version. "This might be wrong" is noise; "I may be
* confusing this with the 2023 edition" is information.
*
* **Never a bare percentage.** "73% confident" borrows the vocabulary of
* measurement for a number that is not one. Three honest levels — phrased as
* guidance on what to do next — beat a false-precision score every time.
*/
export type ConfidenceAnswerProps = {
/** How sure the answer is. Drives both the badge and its wording. */
confidence: "high" | "medium" | "low";
/** The answer itself. */
text: string;
/** The specific thing to double-check, in one sentence — shown for medium and low. */
hedge?: string;
className?: string;
};
const LEVELS = {
medium: { label: "Worth double-checking", dot: "bg-amber-500", text: "text-amber-700 dark:text-amber-400" },
low: { label: "Treat as a guess", dot: "bg-red-500", text: "text-red-700 dark:text-red-400" },
} as const;
/* ------------------------------------------------------------------ */
/* ConfidenceAnswer */
/* ------------------------------------------------------------------ */
export function ConfidenceAnswer({
confidence,
text,
hedge,
className = "",
}: ConfidenceAnswerProps) {
const warn = confidence !== "high";
const level = warn ? LEVELS[confidence] : null;
const surface =
confidence === "low"
? "border-red-200 bg-red-50/50 dark:border-red-900/40 dark:bg-red-950/20"
: confidence === "medium"
? "border-amber-200 bg-amber-50/50 dark:border-amber-900/40 dark:bg-amber-950/20"
: "border-zinc-200 bg-white dark:border-zinc-800 dark:bg-zinc-900";
return (
<div className={`rounded-2xl rounded-tl-md border px-4 py-3 ${surface} ${className}`}>
<p className="text-sm leading-6 text-zinc-900 dark:text-zinc-100">{text}</p>
{/* High confidence renders as a plain answer — badging certainty trains
the eye to skip the badge row, and the warning that matters gets
ignored with the rest. */}
{level && (
<div className="mt-2 flex items-center gap-1.5">
<span className={`h-1.5 w-1.5 shrink-0 rounded-full ${level.dot}`} />
<span className={`text-xs font-medium ${level.text}`}>{level.label}</span>
</div>
)}
{/* zinc-600 on the amber surface: zinc-500 measures under AA at 13px. */}
{warn && hedge && (
<p className="mt-1 text-[13px] leading-5 text-zinc-600 dark:text-zinc-400">{hedge}</p>
)}
</div>
);
}
When to use it
- Badge the uncertainty, not the certainty — a 'high confidence' mark on every solid answer trains the eye to skip the badge row entirely.
- Put the hedge at the claim: one sentence naming the specific thing that might be off — a number, a date, a version.
- Phrase levels as guidance on what to do next ('Worth double-checking'), not as a verdict on the model.
- Never show a bare percentage; '73% confident' borrows the vocabulary of measurement for a number that is not one.
What breaks in production
- A blanket 'AI can make mistakes' footer — invisible by day two, and it tells the reader nothing about this answer.
- Badging every answer regardless of confidence, so the one reply that needed scrutiny gets it least.
- Hedging with vague worry ('this might be wrong') instead of saying what specifically to verify.
Related Components
How to say no without ending the conversation — the refusal, a plain-language reason, and one redirect the reader can click.
What to show when the content filter fires — a stopped stream that keeps its partial text, or a blocked prompt, with a false-positive path.
The message input at the heart of an AI chat app — file attachments, model picker, tool toggles, voice, and a send button that turns into stop.
A chat input that accepts file uploads — attachment chips with upload progress, type icons, and one-click removal.