Skip to content
KONIGI Patterns

AI Assistants / Starting a request / Prompt starters

‹ 7 of 7

Prompt starters

People need examples of useful requests when they do not know what to ask.

Updated September 12, 2026

Problem

An empty message field does not explain what an assistant can help with. New users have to guess what to ask.

Solution

Show a few specific, useful requests that match the assistant’s capabilities. Selecting one should fill the message field so people can review or change it before sending.

Where appropriate, tailor suggestions to the open document or current task. Only suggest actions the assistant can perform with the access it has.

Keep the list short and make clear that these are examples. Reduce their prominence for returning users, and update them when capabilities change.

Use when

The assistant’s purpose or available actions are not obvious to someone starting a conversation.

Don’t use when

The assistant is invoked on a selection or from a command with an obvious object. Someone who highlighted a paragraph and pressed the assist key already knows what they’re asking about, and a list of unrelated suggestions gets in the way of the thing they meant to do.

Trade-offs

Examples help people begin but can make the assistant seem limited to the listed tasks. Personalized suggestions require access to the current work. Outdated starters can promise actions the product no longer supports.

Checklist

  • Do the examples show what this assistant does better than a general one?
  • Are they specific enough to be believable, or are they placeholders?
  • Do they fill the composer or fire immediately?
  • Are there three or four, or a grid that reads as a menu?
  • Do they use the viewer’s actual context when context is available?
  • What generates them, and does that involve reading the viewer’s content?
  • Do they get out of the way for a returning user?
  • Who owns updating them when the product gains a capability?
  • Is a starter reachable and readable from the keyboard?
  • Does clicking one leave the viewer able to edit before sending?

Compare

ChatGPT uses a small rotating set on the empty state and lets a click populate the composer for editing, so the example stays a starting point instead of a command. Claude leans on its project context, so the suggestions on an empty conversation inside a project are about that project’s material rather than about the product in general. Notion offers its starters at the cursor inside a page, where the options are edits to the thing being written and the context is unambiguous. Perplexity replaces starters with live example queries drawn from what people are searching right now. It teaches the shape of a good question and doubles as a browse surface.

First-run state provides the surrounding introduction. Composer receives the selected prompt. Command menu serves people who know which action they want.

Inline assist can suggest requests for selected content. Refusal should not be the routine result of following a suggested prompt.

Prompt starters anatomy Four specific example prompts on an empty state, drawn from the current project rather than written generically, each filling the composer rather than sending, with a twelve-item grid shown alongside as the version that reads as a menu. Four examples, or a menu that sets the ceiling Summarise the lease, list break clauses Compare Q3 spend against the forecast Draft a reply to the landlord Find every date mentioned drawn from this project reads as the full list of what it can do 1 2 3 4 1 SPECIFIC ENOUGH TO BELIEVE Write a poem about a cat teaches a professional that this is a toy. 2 FILL, DO NOT FIRE A click lands in the composer so the example stays a starting point. 3 USE THE CONTEXT An assistant that can see the work should demonstrate that in its first four lines. 4 TWELVE IS A MENU A grid sets the perceived boundary, and absent capabilities are believed absent. Starters bias the corpus. People ask what was suggested, and the product learns from that.
Wireframe — the pattern's anatomy, not any one product's version of it

Implementation

Four example prompts drawn from the current project rather than written generically, each filling the composer rather than sending. A twelve-item grid of the same idea reads as the full list of what the product can do.

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

PromptStarters.tsxReal buttons that fill the composer. After five conversations it fades to one refresh control.

import { RefreshCw } from "lucide-react";
import { Button } from "@/components/ui/button";

type Props = {
  /** Three or four, drawn from the current project. A grid of twelve reads
   *  as a menu, and a menu is read as the full list of what the thing can do. */
  starters: string[];
  /** Fills the composer. A click lands in the box so the example stays a
   *  starting point, and nothing is sent that the viewer did not read. */
  onPick: (text: string) => void;
  /** After a handful of conversations the viewer has a model, and the examples
   *  become furniture between them and the box. Past this many, fade to one
   *  refresh control. */
  conversations?: number;
  onRefresh?: () => void;
};

const FURNITURE_AFTER = 5;

export function PromptStarters({ starters, onPick, conversations = 0, onRefresh }: Props) {
  if (conversations >= FURNITURE_AFTER && onRefresh) {
    return (
      <Button variant="ghost" size="sm" onClick={onRefresh} className="text-muted-foreground">
        <RefreshCw className="size-4" /> suggest something
      </Button>
    );
  }

  return (
    <div className="flex flex-col gap-2">
      {starters.map((s) => (
        <Button
          key={s}
          variant="outline"
          onClick={() => onPick(s)}
          className="h-auto justify-start whitespace-normal px-3 py-2 text-left font-normal"
        >
          {s}
        </Button>
      ))}
    </div>
  );
}

demo.tsxHow it is called: four starters and a box they fill. Nothing sends.

import { useState } from "react";
import { PromptStarters } from "./PromptStarters";
import { Textarea } from "@/components/ui/textarea";

/** Four starters from the project. Picking one fills the box below it, and nothing is sent. */
export default function Demo() {
  const [draft, setDraft] = useState("");
  return (
    <div className="rounded-lg border bg-card p-4">
      <PromptStarters
        starters={[
          "Summarise the lease, list break clauses",
          "Compare Q3 spend against the forecast",
          "Draft a reply to the landlord",
          "Find every date mentioned",
        ]}
        onPick={setDraft}
      />
      <Textarea
        value={draft}
        onChange={(e) => setDraft(e.target.value)}
        rows={2}
        placeholder="Ask a question"
        aria-label="Ask a question"
        className="mt-4 resize-none"
      />
    </div>
  );
}
What it renders. Identical markup in both panes, with only the token values changing.

Examples

No screenshots yet for this pattern. Browse Products to see other examples.