Skip to content
KONIGI

AI Assistants / Grounding and disclosure / Reasoning disclosure

3 of 5

Reasoning disclosure

The model worked for thirty seconds and the viewer wants to know whether it understood the question.

Updated September 12, 2026

Problem

A hard question produces forty seconds of nothing before the first word of the answer. During that silence the viewer can’t tell whether the model understood the question, misread a key term, or is about to spend the whole answer solving a different problem.

Solution

Stream the intermediate reasoning on a separate track from the answer, collapsed by default, with a one-line summary and a duration visible without expanding.

This does two distinct jobs and the second is the one that justifies it. The first is filling the wait, which any progress treatment could do. The second is letting the viewer catch a misread premise at second three instead of second forty. Someone who sees the model restate their question wrongly can stop and re-ask immediately, and that’s worth more than the entire content of the reasoning.

Collapsed by default is the right posture. The reasoning runs longer than the answer and matters less. A viewer who reads eight hundred words of deliberation to reach a two-hundred-word conclusion has been given a worse product—not a more transparent one. The summary line carries the catchable information; the expansion is for debugging and for the rare case where the path matters more than the destination.

Summarised rather than raw is increasingly the shipped form, and Anthropic’s documentation describes the mechanism directly: a display: "summarized" setting streams a condensed version of the reasoning rather than the full chain, preserving the key ideas with minimal added latency so the summary can still stream as it arrives. Summarising is the right default for a consumer surface. The full trace belongs behind a developer affordance.

The honesty limit needs stating, because this pattern is routinely oversold. The visible reasoning is a narration produced alongside the answer, not an execution trace of the computation that produced it. NN/g is direct about the constraint: models are complex enough that even their engineers can’t always accurately trace the reasons behind an output. Labelling this panel as why the model answered the way it did claims something the system can’t deliver. Labelling it as the model’s working is accurate and still useful.

Naming matters more here than in most patterns. “Thinking” anthropomorphises and sets an expectation of interiority. Something closer to the mechanism reads better and ages better, and a duration next to it does more for trust than an adjective.

Use when

Reasoning takes long enough that the wait needs explaining, and the task has a premise that could be misread. Analysis and multi-step problems qualify, and so does any question loose enough to be read two ways.

Don’t use when

The answer arrives in two seconds, or the task has no interesting intermediate state. A disclosure panel over a lookup manufactures the appearance of deliberation and slows the product’s felt speed for nothing.

Trade-offs

Exposed reasoning invites the viewer to argue with the process rather than evaluate the result, which is usually a worse use of their attention. It leaks the model’s uncertainty in a way the polished answer hides, which is more honest and lowers confidence even when the answer is right. Raw traces occasionally contain content the product would rather not show, which is one reason summarisation wins. Once reasoning is visible, people optimise their prompts against it. They tune for the narration instead of the output.

Checklist

  • Is it collapsed by default?
  • Does the collapsed line carry enough for the viewer to catch a misread question?
  • Is a duration shown, and is it the real one?
  • Does the panel claim to explain why, or to show working?
  • Can the viewer stop generation from inside the reasoning phase?
  • Does reasoning count toward usage limits, and is that visible?
  • Is the reasoning included when the answer is copied, shared, or exported?
  • Does a screen reader get the summary without the whole trace?
  • What happens when reasoning is longer than the answer?
  • Is raw reasoning ever shown, and has anyone read a hundred samples of it?

Compare

Claude streams a summarised version of its reasoning by default and keeps the full trace behind an API setting. The panel is calibration for a reader, not a log for a developer. ChatGPT shows a running progress narration during longer reasoning, so the disclosure doubles as the progress indicator for the pre-answer wait. Gemini presents its reasoning as a structured plan more than a monologue, which is easier to skim and further from what the model actually did. Perplexity mostly spends this space on the search steps instead. Showing what it looked for is more verifiable than showing what it concluded.

Streaming response is the track the answer arrives on while this one runs alongside. Tool call trace is the same disclosure for actions rather than thoughts. Citation chip explains origin where this explains path. Stop generation has to remain reachable during the reasoning phase. Response collapse is the same fold applied to the answer itself.

Reasoning disclosure anatomy A collapsed reasoning panel above an answer, carrying a one-line summary and a duration, expanded below to show a summarised trace rather than a raw chain, with the answer running shorter than the reasoning that produced it. Collapsed, summarised, and honest about what it is Working: restating the question, checking the two dates 38s summarised, not the raw chain 200 words of answer under 800 words of working 1 2 3 4 1 CATCH THE MISREAD Seeing the question restated wrongly at second three is the whole value. 2 A REAL DURATION A number next to the label does more for trust than any adjective. 3 WORKING, NOT WHY This is a narration produced alongside the answer, not a trace of the computation. 4 LONGER THAN THE ANSWER Reading 800 words to reach 200 is a worse product, not a more transparent one. Once reasoning is visible, people tune their prompts against the narration instead of the output.
Wireframe — the pattern's anatomy, not any one product's version of it

Implementation

A collapsed panel carrying a one-line summary and a duration. What expands is a summarised trace rather than the raw chain, because 200 words of answer buried under 800 words of working reads worse than the answer alone.

shadcn
npx shadcn@latest add collapsible button
npm
lucide-react
Tokens
--card--card-foreground--muted-foreground--border
38s

The question is whether the tenant's break date comes before the rent review, and what notice that needs.

The lease starts 1 March 2024. The break is at the end of year two, so 28 February 2026, on six months' written notice. The review is at the third anniversary, 1 March 2027.

The break falls a year before the review, so notice has to be served by 31 August 2025, with rent paid up and vacant possession on the day.

summarised, not the raw chain

Yes. The break on 28 February 2026 comes a year before the review on 1 March 2027. Notice has to be served by 31 August 2025, with rent paid up and the premises returned empty.

ReasoningDisclosure.tsxCollapsed by default, labelled as working rather than thinking, a real duration in the header, stop while it streams.

import { useState } from "react";
import { ChevronRight, Square } from "lucide-react";
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible";
import { Button } from "@/components/ui/button";
import { cn } from "@/lib/utils";

type Props = {
  /** One line the viewer can read without expanding: enough to catch a
   *  misread question at second three. The panel prefixes "Working:", never
   *  "Thinking:"; this is narration produced alongside the answer, not a
   *  trace of the computation. */
  summary: string;
  /** The summarised trace, a paragraph per step. Never the raw chain. */
  trace: string[];
  /** The real one. A duration next to the label does more for trust than any adjective. */
  durationMs: number;
  /** True while the working is still arriving. Shows stop, because the viewer
   *  who has spotted a misread should not have to wait for the answer. */
  streaming?: boolean;
  onStop?: () => void;
  /** Collapsed by default. The working runs longer than the answer and matters less. */
  defaultOpen?: boolean;
};

const duration = (ms: number) => {
  const s = Math.round(ms / 1000);
  return s < 60 ? `${s}s` : `${Math.floor(s / 60)}m ${s % 60}s`;
};

export function ReasoningDisclosure({ summary, trace, durationMs, streaming = false, onStop, defaultOpen = false }: Props) {
  const [open, setOpen] = useState(defaultOpen);
  return (
    <Collapsible open={open} onOpenChange={setOpen}>
      <div className="flex items-center gap-2.5 rounded-lg border px-3 py-2">
        <CollapsibleTrigger className="flex min-w-0 flex-1 items-center gap-2.5 text-left" aria-label={`working: ${summary}`}>
          <ChevronRight className={cn("size-3 shrink-0 text-muted-foreground transition-transform", open && "rotate-90")} aria-hidden />
          <span className="truncate text-xs text-card-foreground">Working: {summary}</span>
        </CollapsibleTrigger>
        {streaming && onStop ? (
          <Button variant="ghost" size="sm" className="h-6 px-1.5 text-[11px]" onClick={onStop}>
            <Square className="size-2.5 fill-current" aria-hidden /> stop
          </Button>
        ) : (
          <span className="text-[11px] tabular-nums text-muted-foreground">{duration(durationMs)}</span>
        )}
      </div>
      <CollapsibleContent>
        <div className="mt-3 rounded-lg border border-dashed p-3">
          {trace.map((step, i) => (
            <p key={i} className="text-xs leading-relaxed text-muted-foreground [&+p]:mt-2">{step}</p>
          ))}
          {/* Say what it is. The full chain belongs behind a developer affordance. */}
          <p className="mt-3 text-right text-[11px] text-muted-foreground">summarised, not the raw chain</p>
        </div>
      </CollapsibleContent>
    </Collapsible>
  );
}

demo.tsxHow it is called: the summary line, the summarised trace, the duration, opened so the trace shows.

import { ReasoningDisclosure } from "./ReasoningDisclosure";

/**
 * The working for one lease question, opened so the summarised trace shows.
 * A product would leave `defaultOpen` off and let the viewer expand it.
 */
const TRACE = [
  "The question is whether the tenant's break date comes before the rent review, and what notice that needs.",
  "The lease starts 1 March 2024. The break is at the end of year two, so 28 February 2026, on six months' written notice. The review is at the third anniversary, 1 March 2027.",
  "The break falls a year before the review, so notice has to be served by 31 August 2025, with rent paid up and vacant possession on the day.",
];

export default function Demo() {
  return (
    <div className="rounded-lg border bg-card p-4">
      <ReasoningDisclosure
        summary="restating the question, checking the two dates"
        trace={TRACE}
        durationMs={38_000}
        onStop={() => console.log("stop")}
        defaultOpen
      />
      <p className="mt-4 border-t pt-4 text-sm leading-relaxed text-card-foreground">
        Yes. The break on 28 February 2026 comes a year before the review on 1 March 2027. Notice has to be served by 31 August 2025, with rent paid up and the premises returned empty.
      </p>
    </div>
  );
}
What it renders. Identical markup in both panes, with only the token values changing.

Examples

No captures reference this pattern yet. Captures arrive product by product; see Products for what's in the gallery so far.