Browse all patterns
AI Research Assistant
A research flow that shows search tool calls, reasoning, sources and a cited final answer.
research-assistant.tsx159 lines4 componentsReact + Tailwind + shadcn/ui
npx shadcn@latest add @scrimui/research-assistantAgent promptClaude Code · Cursor · any agent
Add the AI Research Assistant pattern from the Scrim UI registry to this project — a complete screen, not a single component.
AI Research Assistant — A research flow that shows search tool calls, reasoning, sources and a cited final answer.
## 1. Install
```bash
npx shadcn@latest add @scrimui/research-assistant
```
This writes the screen to `components/blocks/research-assistant.tsx` and pulls in the components it is built from, each landing at `components/ui/`. Everything is plain React + Tailwind with no runtime dependencies. The imports in the block already point at those paths, so it compiles as installed.
## 2. What it is made of
- `search-tool-call` — Search Tool Call
- `reasoning` — Reasoning
- `citation-ui` — Citation UI
- `source-card` — Source Card
Each is a separate file you can edit or replace on its own; the block is the arrangement, not a monolith.
## 3. Rules this layout depends on
Keep these when adapting the screen — they are the reasons it works, and they are easy to break while restyling:
- Show search and reasoning as they happen — research credibility comes from transparency.
- Keep sources persistent in a sidebar while the answer streams in the main column.
- Distinguish 'final answer' from intermediate reasoning visually.
- Let users verify any claim by clicking its citation.
- Collapse the search/tool trail once the answer lands so it doesn't dominate.
## 4. Do not do these
- Hiding the tool trail after answering — users can't audit how you got there.
- Answering before all searches complete, then revising confusingly.
- No way to see the full source, only a truncated snippet.
- Auto-scrolling the sources panel on every token, making it unreadable.
The demo content in the file — messages, file names, model names — is placeholder. Replace it with this project's real data and wire the handlers to real state rather than shipping the stubs.
Reference: https://scrimui.dev/patterns/research-assistantInstalls the screen and every component it is built from, and carries the layout rules from this page so an agent does not restyle them away.
Live Preview
Research Question
Which Claude 5 model is most cost-effective for a high-volume support bot?
- 1
Parsed the question
The user asks for the latest Claude 5 tier and its pricing.
- 2
Formulated queries
Ran two searches: model capabilities and per-tier pricing.
- 3
Cross-checked sources
Matched official docs against release notes.
- 4
Synthesized the answer
Combined 3 sources into a single recommendation.
Built from these components
A web search the model ran — the query it chose, how many results came back, and previews of the sources it read.
A collapsible chain-of-thought panel — show the model's reasoning trace with elapsed time, folded away by default.
Inline citation markers in generated text — numbered footnotes that reveal the source in a hover preview card.
A cited source as a card — favicon, page title, domain, and the snippet the answer actually drew from.
Pattern code
This file composes the components above. Copy each component from its page, then this pattern file wires them together.
"use client";
import { Card } from "@/components/ui/card";
import * as React from "react";
import { SearchToolCall, type SearchResult } from "../../search-tool-call/search-tool-call";
import { Reasoning } from "../../reasoning/reasoning";
import { SourceCard } from "../../source-card/source-card";
import { InlineCitation, CitationList, type Citation } from "../../citation-ui/citation-ui";
/* ------------------------------------------------------------------ */
/* Data */
/* ------------------------------------------------------------------ */
const SEARCH_RESULTS: SearchResult[] = [
{
title: "Claude Fable 5 and Mythos 5 — Anthropic",
url: "https://www.anthropic.com/news/claude-fable-5-mythos-5",
snippet: "Fable 5 is the most advanced generally available Claude model to date.",
},
{
title: "Claude 5 family: model overview",
url: "https://docs.anthropic.com/models/overview",
snippet: "Capabilities, context windows and pricing for the Claude 5 line.",
},
{
title: "Anthropic model pricing",
url: "https://docs.anthropic.com/pricing",
snippet: "Per-token pricing for Opus, Sonnet and Haiku tiers.",
},
];
const REASONING_STEPS = [
{
title: "Parsed the question",
detail: "The user asks for the latest Claude 5 tier and its pricing.",
},
{
title: "Formulated queries",
detail: "Ran two searches: model capabilities and per-tier pricing.",
},
{
title: "Cross-checked sources",
detail: "Matched official docs against release notes.",
},
{
title: "Synthesized the answer",
detail: "Combined 3 sources into a single recommendation.",
},
];
const SOURCES: Citation[] = [
{
id: 1,
title: "Claude Fable 5 and Mythos 5",
url: "https://www.anthropic.com/news/claude-fable-5-mythos-5",
domain: "anthropic.com",
snippet: "Fable 5 is the most advanced generally available Claude model.",
},
{
id: 2,
title: "Claude 5 family: model overview",
url: "https://docs.anthropic.com/models/overview",
domain: "docs.anthropic.com",
},
{
id: 3,
title: "Anthropic model pricing",
url: "https://docs.anthropic.com/pricing",
domain: "docs.anthropic.com",
},
];
/* ------------------------------------------------------------------ */
/* ResearchAssistantPattern */
/* ------------------------------------------------------------------ */
export function ResearchAssistantPattern() {
const [phase, setPhase] = React.useState<0 | 1 | 2>(0);
React.useEffect(() => {
if (phase !== 0) return;
const t = window.setTimeout(() => setPhase(1), 3200);
return () => window.clearTimeout(t);
}, [phase]);
React.useEffect(() => {
if (phase !== 1) return;
const t = window.setTimeout(() => setPhase(2), 3600);
return () => window.clearTimeout(t);
}, [phase]);
return (
<Card className="gap-0 py-0 rounded-xl border border-border bg-card">
{/* Question header */}
<div className="border-b border-border px-5 py-4">
<p className="text-xs font-medium text-muted-foreground">Research Question</p>
<h3 className="mt-1 text-lg font-semibold text-foreground">
Which Claude 5 model is most cost-effective for a high-volume support bot?
</h3>
</div>
<div className="grid gap-5 p-5 lg:grid-cols-[1fr_260px]">
{/* Main column */}
<div className="min-w-0 space-y-4">
{/* Search tools */}
<div className="space-y-2">
<SearchToolCall
query="Claude 5 model comparison"
status={phase >= 1 ? "done" : "searching"}
results={SEARCH_RESULTS.slice(0, 2)}
elapsed={phase >= 1 ? "2.4s" : "1.4s"}
/>
<SearchToolCall
query="Claude 5 pricing per token"
status={phase >= 1 ? "done" : "searching"}
results={SEARCH_RESULTS.slice(2)}
elapsed={phase >= 1 ? "1.9s" : "0.8s"}
/>
</div>
{/* Reasoning */}
<Reasoning steps={REASONING_STEPS} elapsed="3.1s" isThinking={phase === 0} />
{/* Answer */}
{phase === 2 && (
<div className="space-y-3 rounded-xl border border-border p-4">
<p className="flex items-center gap-1.5 text-xs font-medium text-emerald-700 dark:text-emerald-400">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" width="12" height="12">
<path d="M20 6 9 17l-5-5" />
</svg>
Final Answer
</p>
<p className="text-sm leading-7 text-foreground">
For high-volume support traffic, <strong>Claude Haiku 4.5</strong> is the most
cost-effective tier: it keeps per-token cost a fraction of Opus while still handling
the routine routing and drafting that support bots handle best{" "}
<InlineCitation citation={SOURCES[0]} />. Reserve Opus{" "}
<InlineCitation citation={SOURCES[1]} /> for escalation paths where reasoning quality
outweighs cost. At scale, streaming with Haiku keeps first-token latency low and the
bill predictable <InlineCitation citation={SOURCES[2]} />.
</p>
<CitationList citations={SOURCES} />
</div>
)}
</div>
{/* Sources sidebar */}
<aside className="hidden lg:block">
<p className="text-xs font-medium text-muted-foreground">Sources</p>
<div className="mt-2 space-y-2">
{SEARCH_RESULTS.map((r, i) => (
<SourceCard key={i} title={r.title} url={r.url} snippet={r.snippet} index={i + 1} />
))}
</div>
</aside>
</div>
</Card>
);
}
When to use it
- Show search and reasoning as they happen — research credibility comes from transparency.
- Keep sources persistent in a sidebar while the answer streams in the main column.
- Distinguish 'final answer' from intermediate reasoning visually.
- Let users verify any claim by clicking its citation.
- Collapse the search/tool trail once the answer lands so it doesn't dominate.
What breaks in production
- Hiding the tool trail after answering — users can't audit how you got there.
- Answering before all searches complete, then revising confusingly.
- No way to see the full source, only a truncated snippet.
- Auto-scrolling the sources panel on every token, making it unreadable.
More Patterns
The canonical chat interface — sidebar, streaming messages, prompt input with model selector, and sources.
AI Coding AgentA coding run with agent status, tool calls, diffs and a human-in-the-loop approval gate.
AI Voice AssistantA voice-first conversation — live waveform states, a recording input, a spoken transcript and a typed fallback.
Model & Memory PreferencesA preferences screen that picks the model, reasoning level and tools, and manages persistent memory.
Artifact WorkspaceChat on the left, generated output on the right — artifacts open from the answer, stream, version, and fail without breaking the conversation.
Document Q&A WorkspaceAsk your own documents — upload and parse, cited answers with inspectable passages, an honest not-found state, and a visible context budget.
Structured Extraction & ReviewUpload a document, watch fields fill in, then review the flagged ones — per-field confidence, corrections that keep the original, export earned.
Image Generation StudioA one-screen generation studio — prompt composer and model picker beside a feed of queued, staged, blocked and ready image results with variants.
Multi-agent Ops ConsoleWatch a fleet of agents at once — parallel statuses, an inspectable handoff, a waiting approval, a failed child run, and per-run plus fleet cost.
Customer Support CopilotGrounded reply drafts with citations, honest low-confidence answers, inline corrections, an approval gate on refunds, and a rating row on every draft.
Generative UI DashboardThe model assembles a dashboard from a controlled widget registry — streamed props, an unsupported-request fallback, and widget clicks that re-enter the chat.