The Index Agent
A retrieval system needs to return the evidence a question requires. The shape of the data helps you choose how to search it.
The Index Agent applies that workflow idea to outside knowledge with a developer-defined pipeline. It embeds and indexes a corpus ahead of time, then retrieves matching passages and generates an answer from a bounded context bundle. The build follows that path for unstructured prose before wrapping retrieval as a tool that a surrounding ReAct loop can call. The other data shapes get pointers to where they go deeper.
- Generation alone answers from the model's current context and training.
- Traditional RAG runs a fixed retrieval step before every generated answer.
- Agent-controlled retrieval exposes retrieval as a tool, so the loop decides whether another lookup is needed.
Trace RAG from joint training to retrieval?
Where RAG came from: one system, trained end to end
When Lewis and colleagues named retrieval-augmented generation in 2020, they trained the retriever and generator together on the task. Read the figure from left to right before looking at the arrow across the top.
The design lives in the arrow labelled "End-to-End Backprop through q and pθ". One loss updated both halves at once. The query encoder learned which passages the generator could use, and the generator learned to lean on retrieved evidence over its own memory.
The retriever began as part of the model, shaped by the task it had to perform, well before anyone described it as a search tool placed in front of one.
Using pretrained models for RAG
An inference API does not provide access to update model weights. Jointly training a self-hosted retriever and generator requires the model weights, training data, and compute.
The workflow here uses pretrained models without updating their weights. A retriever selects passages to include in the generation prompt. You can change retrieval and inspect its results without training the generator.
The retrieve-then-generate pipeline you build
A retriever runs in front of the frozen model across two separate timelines. One timeline builds the index ahead of time so the other can serve a live request against it. The figure below traces both.
Offline: build the index once by embedding every passage and storing it for fast lookup.
Live: embed the question, retrieve the top-K passages, and pass them to the model with the question.
The rest of this page builds the live path one stage at a time.
Choose bundles, boundaries, and data shapes?
Naming the context bundle before you pick a store
Before picking a retrieval primitive, you should first define a bundle. The bundle is the complete and bounded set of context that you intend your pipeline to pass around.
- For a simple single-turn question-answering system, the bundle can stay small: the user question, the few chunks retrieved to answer it, and the answer itself.
- For an autonomous agent, the bundle is the working memory it carries across many turns. That memory stores the agent's constraints, prior decisions, partial results, tool surfaces, and operating rules.
- For an arbitrary Index Agent, the bundle returned by the agent may only house the retrieved context chunks along with their chunk sources, relevance scores, and possibly a summary. A separate internal bundle may be the flat live-request-processing pipeline from above, or a ReAct-style loop that iterates, judges retrieval relevance, and retries until it has accumulated enough context.
The bundle principle is a planning discipline: define the bundle before you pick the database. The table below helps check whether your candidate primitive can deliver the bundle for your task.
Where MCP fits in retrieval systems
MCP gives a retrieval system one boundary for discovering and calling external context sources. The agent still needs a runtime that decides when to retrieve, validates the result, and composes it with the rest of the active task state. Other boundaries can carry other parts of the same system: skills package reusable capability instructions, A2A can route work to remote specialists, and UI protocols can stream the generated state back to an application.
The figure below separates those boundaries. Read it left to right to follow MCP context ingress and A2A task delivery. Then read it bottom to top to follow skill brokerage, runtime execution, and generated UX. Choose the boundary that matches the bundle and the system state it must carry.
Matching a retrieval primitive to the shape of your data
The table lists retrieval approaches to consider for different data shapes. Choose using representative questions, the evidence each answer needs, and the cost of retrieving it; evaluate whether the returned results cover that evidence.
| Shape | Examples | Candidate approach |
|---|---|---|
| Unstructured prose | Docs, articles, code comments, transcripts | Dense vector + cross-encoder rerank |
| Hierarchical docs | Legal contracts, technical manuals, nested specs | Tree index with parent pointers |
| Structured / governed tables | Customer records, financial ledgers, HR tables | Semantic layer over the source of truth |
| Relational / graph | Org charts, code dependencies, knowledge graphs | Graph traversal (Cypher, GraphQL, custom) |
The unstructured-prose example retrieves passages from a corpus and asks the model to answer from them. Check whether the answer is supported by those passages.
Every request walks the same four steps:
- Embed the query into a vector.
- Search the passage index for the top-K nearest passages.
- Concatenate those passages onto the prompt.
- Generate an answer with an instruction to use those passages.
Other retrievers can use keyword search or structured queries. Choose the retrieval method for your data, then inspect which evidence it supplies to the generator.
Embedding text for similarity search
This vector retriever represents passages and queries as embeddings. An embedding is a learned numerical representation of a piece of text, a fixed-length vector placed so that semantically similar texts land near each other in vector space. Two practical consequences follow:
Both use the embedding model, called through helpers.embed in this course.
Configure the embedding endpoint and its required credential in the model panel.
The browser sends your text through the selected route. Inspect the request and
returned error if the embedding service is unavailable.
Need the embedding request contract?
The embeddings endpoint takes a JSON request with three fields and returns one array of vectors:
inputis the batch of texts to embed, typedstring[].modelnames the embedding model, typedstring.input_typeis either"query"or"passage".- The response carries a
dataarray whose entries each hold anembeddingofnumber[].
The NVIDIA embedding model uses input_type to distinguish queries from
passages. Its retrieval training aims to match questions with passages that answer them.
Reversing "query" and "passage" can change the scores and reduce
retrieval quality without causing an API error. Check the types and evaluate the returned passages.
A whole retriever in thirty lines of top-K cosine
A "vector database" dresses up a plain job the Index Agent already does. It stores each passage beside its embedding and returns the top-K closest passages to any query embedding by cosine similarity. In the browser that fits in thirty lines of JavaScript.
The cell below builds an Index Agent over a handful of documents and queries it. Edit the corpus and the query, then watch which passages bubble to the top and why.
A vector index is a cache of an embedding model's outputs. Production systems have to defend against a few specific failures:
- Swap the embedding model and every cached vector becomes meaningless until you re-embed every passage.
- The provider silently upgrades the model, and scores drift with no error raised.
- Two services share an index but pin different model ids; the index returns nonsense to one of them.
A reliable index pins the embedding model id alongside each cached vector
and refuses to mix versions. The canonical pin for this course is
nvidia/nemotron-3-embed-1b, served by
integrate.api.nvidia.com through the course relay.
Retrieve small chunks with parent context?
Searching small chunks but returning the parent document
A bare top-K Index Agent has a recall-precision trade-off no embedding model solves. You must choose between short chunks and long documents:
- Short chunks focus the embedding on a narrower passage, but may omit context needed to answer the question.
- Long documents include more surrounding context, but covering several topics in one embedding can dilute the match to a specific question.
One approach indexes at two levels. Small chunks are embedded for retrieval; a match selects the parent document to supply more surrounding context to a later generation step.
The exercise below builds this with three parent docs, each split into short sentence-chunks, and a query that returns the matching parent.
Let the model decide when to retrieve?
Wrapping the index as a tool the model decides to call
A retrieval index on its own only answers when something queries it. It becomes an Index Agent once you wrap it as a tool the model can choose to call, letting the model decide when retrieval is worth running. The cell below does it in five steps:
- A corpus is embedded once and held in an in-memory index.
- A
retrieve(question, k)tool is declared with a JSON schema. - The agent receives the user's question. It chooses whether to call the tool.
- If yes, cosine retrieval runs over the index; the top-K passages are appended as a tool message.
- A second LLM call writes the final answer grounded in the retrieved passages.
You can retain the tool interface while replacing the in-memory cosine search with a server-side FAISS+BM25+rerank pipeline executor. Validate its results and failure behavior before using it in the loop.
Compare the other index shapes?
How the other three shapes are built
You just built the unstructured-prose lane from corpus to answer. The other three are named here so you can recognise them in the wild and reach for the right primitive. Each one has a well-worn production pattern, sketched below.
- Hierarchical docs. A chunker that preserves the heading hierarchy, plus atomic table extraction, parent pointers, and a dual index for structural and semantic search. You index the small child chunks for recall and fetch the enclosing parent on a hit, so the model reads the matched clause together with the section it belongs to.
- Page-image retrieval for figures and charts. A dual-vector setup that embeds the rendered page image alongside its text, so a query can also pull a figure or a slide when the answer lives there.
- Structured / governed tables. Not built in this course. The standard production pattern is a semantic layer sitting between the agent and the row-level data, exposing only the curated metrics the bundle requires.
- Relational / graph data. The agent calls a graph-traversal tool (Cypher, GraphQL, or custom) in place of a vector store. The bundle it gets back is a sub-graph whose explicit edges carry into the prompt, so the relationships between entities reach the model intact.
Explore corpus-wide retrieval with GraphRAG?
When top-K is the wrong tool: GraphRAG and global questions
Every retriever on this page answers a local question whose answer sits in a handful of passages that Top-K similarity can find for the model to read, the way asking what the contract says about termination or which paper introduced HyDE does. A whole different class of question has no answer in any single passage at all. Ask what the main themes are across a thousand documents and you find that the answer is too diffuse to live in any one passage and emerges only from the corpus taken as a whole.
With K set to 3, top-K returns three matches from the thousand-passage example. Generation receives those selected passages; they may not cover themes elsewhere in the corpus. GraphRAG (Edge et al. 2024) changes the shape of that problem instead of raising K. It spends an LLM up front at indexing time to:
- read the corpus and extract entities and the relationships between them into a knowledge graph;
- detect the communities in that graph, the clusters of densely connected entities;
- summarize each community on its own.
A global question is then answered at query time, by summarizing across the relevant community summaries and reducing those partial answers into one. The work is a map-reduce over structure rather than a lookup over similarity.
The cell below makes the difference concrete on a small corpus, and it compares top-K retrieval with the community-summary stage used in GraphRAG. The groups below are authored labels, not a graph extracted by the model. The summary route receives every group and its name; top-K receives only its selected passages. Inspect which claims each answer supports, then change K, the groups, or the question.
Small top-K selections can omit evidence needed for corpus-wide questions. Community summaries can broaden coverage, but their grouping and summaries also need evaluation. This example runs summarization each time; a larger system can build and store summaries ahead of queries.
Before you continue
- Cosine in Part 4 scores any two vectors the same way regardless of which is the
query, yet the NVIDIA embed model used here takes
input_typeto distinguish query from passage. What does that asymmetry buy you that pure cosine could not? - The index build embeds every corpus passage once, while the live path embeds each new question. Which changes require a full re-index, and which require only one new query embedding?
- Top-K always returns K passages, even when every score is weak. What signal should the agent inspect before letting those passages enter the prompt?
Trace the retrieval research sources?
References
- Lewis et al., Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks (NeurIPS 2020). The canonical retrieve-then-generate paper; the figure above is redrawn from it.
- Karpukhin et al., Dense Passage Retrieval (EMNLP 2020). The dual-encoder formulation behind query / passage embedding asymmetry that the NVIDIA embed model enforces.
- Johnson, Douze & Jégou, Billion-scale similarity search with GPUs (FAISS, 2017). A library for similarity search over dense vectors.
- Gao et al., HyDE: Precise Zero-Shot Dense Retrieval without Relevance Labels (2022). Generates a hypothetical answer and embeds it for retrieval.
- Lin et al., Pretrained Transformers for Text Ranking (2020). The reranker pattern that a production retrieval stack uses as its second stage.
- Edge et al., From Local to Global: A Graph RAG Approach to Query-Focused Summarization (2024). Builds an LLM-derived knowledge graph and pre-summarizes its communities so global, corpus-wide questions can be answered; the pipeline figure above is redrawn from it.
Comprehensive list at Going Further · References.
Try it · retrieval, live
Ask a question. The artifact embeds it with the same endpoint from this page and ranks a small built-in corpus by cosine similarity. The bars show every score. It then answers from the top passages and cites them. Change the question and watch the ranking shift.
The corpus is embedded offline and shipped beside the page as a prebuilt index so that only your question gets embedded live. You are watching the indexing-versus-serving split from the diagram above run here. The example questions even carry prebuilt vectors and retrieve before you add a key, while editing a passage re-embeds only that one passage.