Knowledge base
ProA retrieval knowledge base in one card: add sources and watch them parse, chunk, embed and index, then test a question and see which chunks come back and why.
- Admin screens for a RAG or support assistant where people add documents, watch them index, and check what a question retrieves.
- Explaining or tuning chunking, hybrid search and reranking with a working test bench instead of a diagram.
- Debugging why an assistant answered from the wrong source by looking at scores, matches and neighbouring chunks.
- Use vector-search to illustrate how embeddings and nearest neighbours work; this block is the working product surface.
- Use document-extract to pull structured fields out of a single document.
- Use agent-memory to show what an agent remembers about a user or a project.
- Use ai-answer or research-run to show the cited answer a model writes from retrieved sources.
Installation
Pro source and install commands unlock with a Pro plan.
Usage
Pass sources, onAdd and search to connect your ingestion and retrieval; with no props it ingests sample sources and answers test queries.
import { KnowledgeBase } from "@/components/arc/blocks/knowledge-base/knowledge-base"; export function SupportKnowledge({ sources, upload, retry }) { return ( <KnowledgeBase title="Support knowledge base" sources={sources} onAddSource={({ kind, file }) => upload(kind, file)} onRetrySource={retry} onQuery={async (query, settings) => { const res = await fetch("/api/retrieve", { method: "POST", body: JSON.stringify({ query, ...settings, candidates: 20 }) }); if (!res.ok) throw new Error("The retriever did not respond"); return res.json(); // [{ id, sourceId, text, location, similarity, relevance, before, after }] }} /> );} // With no props the card runs a full simulation with sample documents.<KnowledgeBase />KnowledgeBase
A retrieval knowledge base in one card. The Sources view lists PDFs, Notion pages, Google Drive docs and website crawls, each with a four step ingestion pipeline (parse, chunk, embed, index) that fills as it runs while page, chunk and token counts climb. Add source and a drop zone bring in new sources that ingest live; a failed source names its reason and offers Retry. The Test retrieval view runs a query and lists the top k chunks with similarity bars and scores, highlighted matching words, the source and page. Turning on Rerank reorders the same results in place and shows how far each chunk moved, and opening a result shows the chunk between its neighbours. A settings popover holds chunk size, overlap, top k, hybrid search, reranking and the embedding model, and asks for a re-index when chunking changes.
titlestring"Support knowledge base"Heading at the top of the card.sourcesKnowledgeSource[]–Live sources: { id, name, kind ("pdf" | "notion" | "drive" | "web" | "file"), pages, chunks, tokens, status, progress?, failedStep?, error?, note? }. status is "queued", "parse", "chunk", "embed", "index", "indexed" or "failed"; progress is 0 to 1 within the current step. Omit to run the built-in simulation with sample company documents.chunksKnowledgeChunk[]–Chunks the built-in retriever searches when onQuery is not set: { id, sourceId, index, location, text, overview? }. index orders chunks inside a source so neighbours can be shown. Defaults to the sample corpus in the simulation.settingsRetrievalSettings–Controlled settings: { chunkSize, overlap, topK, hybrid, rerank, embeddingModel }. Pair with onSettingsChange.defaultSettingsPartial<RetrievalSettings>{ chunkSize: 512, overlap: 64, topK: 4, hybrid: true, rerank: false, embeddingModel: "general-v2" }Starting settings when uncontrolled.onSettingsChange(settings: RetrievalSettings) => void–Called on every settings change, including the Rerank switch above the results. Overlap is clamped to half the chunk size.embeddingModels{ value: string; label: string }[]four generic sample modelsOptions for the embedding model select. The text before the first comma also shows in the card summary.suggestionsstring[]–Questions offered before the first search. Defaults to sample questions for sources that are indexed, so a new suggestion appears when its source finishes.onQuery(query: string, settings: RetrievalSettings) => Promise<RetrievedChunk[]> | RetrievedChunk[]–Runs a retrieval test. Return candidates ({ id, sourceId, text, location?, similarity, relevance?, before?, after? }), ideally more than top k so the reranker can pull one up. The card orders by similarity, or by relevance while Rerank is on, and slices to top k. Throw to show the error state.onAddSource(request: { kind: SourceKind; file?: File }) => void–Called by the Add source menu and for dropped or picked files. In the simulation the card also adds a sample source of that kind and ingests it.onRetrySource(id: string) => void–Called by Retry on a failed source. The simulation resumes from the failed step.onRemoveSource(id: string) => void–Called by Remove on a source that cannot be retried, such as an unsupported file type.onReindex(settings: RetrievalSettings) => void–Called by Re-index after chunk size, overlap or the embedding model changed. Search keeps using the current index until each source finishes.defaultView"sources" | "retrieval""sources"The view shown first.classNamestring–Class on the root element.- Tab
- Moves through settings, Add source, the view switch, each Retry or Remove button and browse in Sources; and through the query field, Search, the Rerank switch and each result in Test retrieval.
- Arrow leftorArrow right
- On the view switch, moves between Sources and Test retrieval. On a settings slider, changes the value by one step; Shift moves a larger step.
- Enter
- In the query field, runs the search. On a suggestion, runs that question. On a result, opens or closes the chunk in context.
- Escape
- In the query field, clears the query and returns to suggestions. In the settings popover or the Add source menu, closes it and returns focus to its trigger.
- Space
- Toggles the Rerank, Hybrid search and Reranking switches and activates buttons.
- The card is a labelled section. Each pipeline is a progressbar with the overall percent and a value text that names the step, such as Embed, step 3 of 4, or Failed at embed.
- Status never relies on color: indexed rows show a check with a label, failed rows an alert icon with the reason in text, and working rows a named step and a percent.
- Each result is a button with aria-expanded and aria-controls; its similarity or reranker score and any rank change (for example, Up 2 after reranking, was 3) are in its accessible name.
- Matching words are wrapped in mark elements, so assistive technology can report highlighted text.
- Ingestion milestones, failures, search results, reranking and simulated actions are announced through one polite status region; simulated uploads say that files stay in the browser.
- Icon-only controls (settings, clear query) have specific names. The settings toggles are full labels, so the text toggles the switch too.
- Pointer focus draws no ring; keyboard focus shows Arc's shared focus ring.
- Turning on Rerank shows a short reranking state, then moves each result to its new rank with a critically damped layout animation (no bounce) while score bars and numbers roll to the reranker's values and a rank change fades in.
- Opening a result springs its height open: the previous chunk slides in above, the excerpt grows from two lines to the full chunk, and the next chunk slides in below, all on the smooth spring.
- Pipeline segments fill from a single animation-frame clock while counts climb; the meta line crossfades when a step changes. Active labels use a finite text shimmer that settles when the step ends.
- New sources open in at the top of the list on a height spring; removed ones close their gap. Views crossfade without moving.
- Reduced motion places results, heights and values immediately, stops the spinner and the skeleton pulse, and keeps every label and announcement.
- The card is container aware: from about 720px down to 320px it keeps one column, with no horizontal scroll.
- Below 560px the pipeline moves under each source name at full width, step labels drop, the page or path beside a result shortens, and the chunk-in-context rail moves inline.
- Below 440px the gutters tighten, the header actions wrap under the title, meta lines wrap instead of truncating, and the indexing summary beside the view switch hides.
- Long source names truncate with the full name in a title; failure reasons always wrap so they stay readable.
- The simulation advances all sources from one requestAnimationFrame loop that only runs while something is queued or working.
- Scores and counts roll through motion values without React re-renders; excerpt heights are measured once with a ResizeObserver and only re-measured when their width changes.
- The local retriever scores a few dozen chunks with plain string matching; real deployments pass onQuery and skip it.
Notes for AI
Give your coding assistant the Markdown reference instead of screenshots.
- Pass sources from your ingestion job and update status and progress as events arrive; the card only renders them when sources is set. Leave sources unset for a self-running demo.
- Return more candidates than top k from onQuery (for example 20) with both similarity and relevance. That is what lets the reranker pull a chunk up from below the cut, which is the point of the comparison.
- Scores are expected between 0 and 1. Map cosine similarity or a reranker logit into that range before returning it.
- Give each result before and after neighbours (or index plus a chunks prop) so opening a result can show it in context.
- location is free text: a page such as "p. 3" for documents, a heading for Notion, or a path for a crawled site.
- The embedding model labels are generic placeholders. Replace them with the models your stack actually uses.
The full library index for assistants is at /llms.txt.