Skip to content
KONIGI

AI Assistants / Turn and response / Regenerate

3 of 6

Regenerate

The answer is wrong or flat, and the only obvious recourse is retyping the question.

Updated September 12, 2026

Problem

The answer is technically responsive and useless. The viewer can’t point at what’s wrong well enough to write a correction, and their instinct is to ask again. Retyping the question means retyping the question, which is the part they were trying to avoid.

Solution

Re-run the same prompt against the same context and show what comes back. Because sampling is stochastic, the second answer differs from the first, sometimes substantially. Being honest about that mechanism matters: this is a dice roll rather than a repair, and an interface that presents it as a repair is overselling.

The design question is what happens to the answer that was already there. Three options, and the choice determines whether the pattern is useful:

  1. Replace it. Cheapest to build and the worst outcome. The viewer regenerated because the first answer was partly right, and now the part that was right is gone with no way back.
  2. Append a new turn. Preserves everything and fills the transcript with near-duplicate answers to the same question, which makes the conversation unreadable after the third try.
  3. Keep both and page between them. A counter on the turn, 2/3, with arrows. The transcript stays linear, the comparison survives, and the viewer can land on whichever attempt was best.

The third is the strongest and carries a consequence worth naming: once a turn holds several responses, the conversation is a tree rather than a list. Continuing from response two produces a different future than continuing from response three. Most products keep the tree and hide it, letting the current selection define the visible thread, which is the right default and means the branch point needs to be discoverable when someone goes looking for it.

The far more useful version gives the retry a direction. Try again with a different model, shorter, more formal, without the code. This converts a reroll into a directed edit, which is HAX guideline 9 in its proper form: make it easy to steer the system when it gets things wrong. A bare retry gives the model nothing it didn’t already have.

Regeneration is also the loudest implicit feedback signal a product receives. It’s coarser than a thumbs-down and far more honest, because nobody clicks retry to be polite.

Use when

Output varies meaningfully between runs and the viewer can judge quality in a few seconds of reading. Drafting, summarising and naming things all qualify.

Don’t use when

The task has a right answer the model either reached or didn’t. Rerolling an arithmetic error or a factual lookup is superstition, and offering the control there teaches a bad habit. Also avoid it where a response has already caused a side effect, since the second answer can’t undo the first one’s consequences.

Trade-offs

Regenerate is cheap to offer and teaches the viewer to reroll instead of writing a better prompt, which makes their outcomes worse over time while feeling productive. Every retry is a full billed generation of the entire response. Keeping alternates makes the transcript a tree the viewer can’t see the shape of. And the pager itself is easy to miss, so a product that preserves three answers and shows the arrows at low contrast has paid the storage cost for nothing.

Checklist

  • Does the previous response survive, and can the viewer get back to it?
  • Is the count of alternates visible without hovering?
  • Can the viewer give the retry a direction rather than rerolling blind?
  • What happens to turns that came after the one being regenerated?
  • Does the model know it is being asked again, or does it see an identical fresh request?
  • Is a retry recorded as a quality signal anywhere?
  • Does each regeneration bill, and does the viewer know that?
  • Is the control offered on tasks where rerolling cannot help?
  • Can the viewer compare two alternates side by side, or only one at a time?
  • When the conversation is shared or exported, which alternate goes with it?

Compare

ChatGPT keeps earlier attempts on the turn behind a small pager, so the transcript stays linear while the branch is preserved underneath it. Gemini has historically gone the other way and surfaced multiple drafts as a first-class thing to look at rather than something to page through, which treats variation as information instead of an accident. Claude attaches retry to the response and lets the model be switched at the same time, so the second attempt is a different question rather than the same one asked twice. Perplexity frames the rerun around the source set rather than the prose, so trying again is closer to searching again than to rewriting.

Stop generation is the other correction control and fires earlier in the same sequence. Response actions is the row this button sits in. Edit and resend is the version that changes the question instead of rerolling the answer, and is usually the better move. Model picker is what makes a directed retry worth having. Usage meter is where the cost of three attempts becomes visible.

Regenerate anatomy One assistant turn holding three alternate responses behind a pager, with a directed retry offering a different model or a shorter answer, and a branch marker showing that continuing from a different alternate produces a different conversation. Three answers to one question, in one turn 2 of 3 try shorter other model from answer 1 from answer 2 the thread the viewer is on is whichever alternate is selected 1 2 3 4 1 THE PAGER Earlier attempts survive and the transcript stays linear. Replacing destroys the compare. 2 A DIRECTED RETRY Shorter, or another model. A bare reroll gives the model nothing it did not have. 3 THE BRANCH POINT Keeping alternates makes the conversation a tree. Most products hide it and should. 4 EACH ONE IS BILLED Every retry regenerates the whole response. Three attempts cost three answers. Rerolling is a dice throw. Editing the question is the correction that addresses the cause.
Wireframe — the pattern's anatomy, not any one product's version of it

Implementation

One turn holding three alternates behind a pager, with a directed retry that asks for a different model or a shorter answer. Continuing from a different alternate produces a different conversation, and the thread the reader is on is whichever one is selected.

shadcn
npx shadcn@latest add button
Tokens
--card--card-foreground--background--accent--accent-foreground--muted-foreground--border--input--chart-1

Five-year term from 1 March 2024 at £42,000 a year, with an upward-only review at the start of year three. The tenant can break at the end of year two on six months' notice, provided the rent is paid up to date and the premises are handed back empty. The deposit is three months' rent, returned within 30 days of the end of the term.

2 of 3

the thread below continues from answer 2

Regenerate.tsxOne turn, every answer it has produced, a pager between them, and two retries that carry a direction.

import { useEffect, useRef, useState } from "react";
import { Button } from "@/components/ui/button";

/** A retry with a direction. A bare reroll gives the model nothing it did not
 *  already have; "shorter" or "another model" turns the dice roll into a
 *  steer. */
export type Retry = { shorter?: boolean; otherModel?: boolean };

type Props = {
  /** Every answer this turn has produced, oldest first. Kept, never replaced:
   *  the viewer retried because the first one was partly right. */
  alternates: string[];
  onRetry: (direction: Retry) => void;
  /** Which alternate the conversation continues from. Once a turn holds
   *  several answers the transcript is a tree, and the selection is the
   *  branch. */
  onSelect?: (index: number) => void;
  /** Which alternate shows first. Defaults to the newest. */
  defaultIndex?: number;
};

export function Regenerate({ alternates, onRetry, onSelect, defaultIndex }: Props) {
  const n = alternates.length;
  const [i, setI] = useState(defaultIndex ?? n - 1);
  const go = (next: number) => { setI(next); onSelect?.(next); };

  // A retry lands on the new answer. The viewer asked for it; it is what they
  // want to see, and the earlier ones are one keypress back.
  const seen = useRef(n);
  useEffect(() => {
    if (n > seen.current) go(n - 1);
    seen.current = n;
  }, [n]);

  return (
    <div>
      <p className="text-sm leading-relaxed text-card-foreground">{alternates[i]}</p>

      <div className="mt-3 flex flex-wrap items-center gap-2">
        {n > 1 && (
          <div className="flex items-center gap-1 text-xs">
            <Button variant="ghost" size="sm" className="h-7 w-7 p-0" onClick={() => go(i - 1)} disabled={i === 0} aria-label="previous answer">‹</Button>
            <span className="tabular-nums text-chart-1" aria-live="polite">{i + 1} of {n}</span>
            <Button variant="ghost" size="sm" className="h-7 w-7 p-0" onClick={() => go(i + 1)} disabled={i === n - 1} aria-label="next answer">›</Button>
          </div>
        )}
        <Button variant="outline" size="sm" className="h-7 rounded-full text-xs" onClick={() => onRetry({ shorter: true })}>try shorter</Button>
        <Button variant="outline" size="sm" className="h-7 rounded-full text-xs" onClick={() => onRetry({ otherModel: true })}>other model</Button>
      </div>

      {/* The tree is kept and hidden; the selection defines the visible
          thread. This line is what makes the branch point findable. */}
      {n > 1 && (
        <p className="mt-2 text-xs text-muted-foreground">the thread below continues from answer {i + 1}</p>
      )}
    </div>
  );
}

demo.tsxHow it is called: three answers, opened on the second. A retry appends a fourth in the direction asked for.

import { useState } from "react";
import { Regenerate, type Retry } from "./Regenerate";

const ANSWERS = [
  "The lease is for five years from 1 March 2024. Rent is £42,000 a year and is reviewed at the third anniversary, upward only, to the open market figure or the passing rent, whichever is higher. The tenant may end the lease at the end of the second year by giving six months' written notice, on condition that all rent has been paid and the premises are returned with vacant possession. A deposit of three months' rent is held in a separate account and returned within thirty days of the end of the term, less any agreed deductions for dilapidations.",
  "Five-year term from 1 March 2024 at £42,000 a year, with an upward-only review at the start of year three. The tenant can break at the end of year two on six months' notice, provided the rent is paid up to date and the premises are handed back empty. The deposit is three months' rent, returned within 30 days of the end of the term.",
  "Five years from March 2024, £42,000 a year, upward-only review at year three. Tenant break at year two on six months' notice if rent is paid and the premises are empty. Deposit of three months' rent, back within 30 days.",
];

/** Three answers to one question. Retry appends a fourth in the asked-for direction. */
export default function Demo() {
  const [alternates, setAlternates] = useState(ANSWERS);
  const retry = (d: Retry) => {
    const next = d.shorter
      ? "Five years, £42,000 a year, reviewed upward at year three. Break at year two on six months' notice. Three months' deposit."
      : "The lease runs 1 March 2024 to 28 February 2029. Annual rent £42,000, upward-only review on 1 March 2027. A tenant-only break on 28 February 2026 needs six months' notice and rent paid up to date. Deposit is three months' rent, refunded within 30 days.";
    setAlternates([...alternates, next]);
  };
  return (
    <div className="rounded-lg border bg-card p-4">
      <Regenerate alternates={alternates} defaultIndex={1} onRetry={retry} />
    </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.