AI Research Assistant
A research flow that shows search tool calls, reasoning, sources and a cited final answer.
research-assistant.tsx158 lines4 componentsReact + Tailwind, no dependencies
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
Pattern code
This file composes the components above. Copy each component from its page, then this pattern file wires them together.
"use client";
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 (
<div className="rounded-2xl border border-zinc-200 bg-white dark:border-zinc-800 dark:bg-zinc-900">
{/* Question header */}
<div className="border-b border-zinc-200 px-5 py-4 dark:border-zinc-800">
<p className="text-[11px] font-medium uppercase tracking-wide text-zinc-500 dark:text-zinc-400">Research Question</p>
<h3 className="mt-1 text-lg font-semibold text-zinc-900 dark:text-zinc-100">
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-zinc-200 p-4 dark:border-zinc-800">
<p className="flex items-center gap-1.5 text-[11px] font-medium uppercase tracking-wide text-emerald-700 dark:text-emerald-400">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" width="12" height="12">
<path d="M20 6 9 17l-5-5" />
</svg>
Final Answer
</p>
<p className="text-[15px] leading-7 text-zinc-700 dark:text-zinc-200">
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 uppercase tracking-wide text-zinc-500 dark:text-zinc-400">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>
</div>
);
}
Usage Guidelines
- 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.
Common UX Mistakes
- 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.