Build document loaders, indexes, retrievers, and query engines with LlamaIndex.
A query engine is only as good as the nodes and index behind it.
Learners map source data into LlamaIndex vocabulary.
Why this matters: This keeps RAG quality work separate from model personality work.
Problem anchor: a lesson assistant must answer from curated KB notes with citations. The risky part is not the final sentence style; it is loading notes, preserving headings, creating nodes, retrieving the right context, and proving citations support claims.
LlamaIndex gives names to those steps: readers load data, parsers create nodes, indexes organize nodes, retrievers select nodes, and query engines synthesize answers.
The app reads five Markdown notes, stores category and source URL as metadata, parses heading-based nodes, builds a vector index, and exposes a query engine with similarity_top_k=6.
A learner question about reranking retrieves nodes with heading breadcrumbs. The answer includes source titles rather than anonymous passages.
RAG quality often fails before the index exists.
Learners treat parsing as a quality gate.
Why this matters: Parsing mistakes create broken citations and missing context downstream.
A PDF with headers, a Markdown note, and a table export need different parsing care. If boilerplate, nav text, or fragmented tables become nodes, retrieval quality suffers no matter which model generates the final answer.
The loader should preserve source URL, document title, heading path, date, and permissions. The parser should keep definitions with caveats and code with prerequisites.
A query engine cites a note titled “Limitations,” but the displayed source title gives no topic. The fix is not a better answer prompt; it is heading metadata and node text that includes the parent title.
After metadata and parser changes, the same retrieval result becomes “RAG Evaluation > Limitations,” and reviewers can verify the claim.
The query engine assembles context from several configurable choices.
Learners configure retrieval rather than accepting default context.
Why this matters: Defaults can overpack noisy nodes or miss exact source constraints.
A LlamaIndex query engine can hide several choices: which retriever, how many nodes, which metadata filters, and which postprocessors or rerankers. Each choice changes what the model sees.
For exact product versions or categories, metadata filters should narrow eligible nodes. For noisy top-k, reranking or node postprocessing can improve packed evidence.
| Option | Choice | Use when | Risk | When to choose | Cost | Complexity |
|---|---|---|---|---|---|---|
| Higher top-k | Retrieve more nodes before synthesis. | Expected evidence is just below the cutoff. | Can pack noise and raise cost. | Use with measured recall gaps. | Low | Low |
| Metadata filters | Restrict nodes by category, tenant, date, or source. | Eligibility matters. | Bad metadata hides valid nodes. | Use in most production apps. | Low | Medium |
| Reranker/postprocessor | Reorder or trim retrieved nodes. | Right nodes appear but rank poorly. | Adds latency and another eval surface. | Use after candidate recall is healthy. | Medium | Medium |
The first useful app returns both answer and sources.
Learners connect index and query engine with inspection.
Why this matters: Evidence inspection catches bad retrieval before user-facing polish.
A RAG demo that only prints the final answer is incomplete. The development slice should print retrieved node text, scores, and metadata so you can debug failures.
Spaced recall: from structured outputs, the model is not the validator. Your app should verify source support and output shape outside the model call.
from llama_index.core import Document, VectorStoreIndex notes = [ Document(text="Reranking reorders retrieved candidates before answer synthesis.", metadata={"source": "retrieval-eval.md"}), Document(text="Chunking preserves answer evidence with headings and metadata.", metadata={"source": "chunking.md"}), ] index = VectorStoreIndex.from_documents(notes) query_engine = index.as_query_engine(similarity_top_k=2) response = query_engine.query("What does reranking do in a RAG system?") print(response) for node in response.source_nodes: print(node.metadata, node.score, node.text[:80])
The retrieval-eval note should be selected; if chunking.md dominates, inspect embeddings, top-k, or node text.
A reliable query engine is the foundation for RAG-backed agents.
Learners delay agent complexity until retrieval is trustworthy.
Why this matters: Agents amplify retrieval failures by making more steps with bad context.
If a query engine cannot reliably retrieve the right nodes for direct questions, wrapping it as an agent tool will not fix the evidence problem. It will make traces longer.
Evaluation should include direct lookup, paraphrase, exact identifiers, negative cases, and stale-source cases. The target is not just a plausible answer; it is answer text supported by retrieved nodes.
Use this review when reading generated answers.
Retrieval prompt: name the document reader, node parser, index, retriever, postprocessor, query engine, and evaluation signal for a grounded LlamaIndex app.
Build a small LlamaIndex plan for five docs: loader, metadata, chunk/node settings, index type, similarity_top_k, reranker choice, citation rule, and three retrieval eval questions. Next rung: build the app end to end.
In LlamaIndex's data hierarchy, which object is the smallest unit that actually gets embedded and stored in a vector index?
A Document is the raw loaded file; LlamaIndex splits it into Nodes, and it is the Node that gets an embedding and lives in the index.
You are loading a set of legal contracts. Each contract has a different effective date and jurisdiction. Where is the RIGHT place to store those attributes so a retriever can filter on them later?
Metadata attached to nodes during loading travels with every chunk, so a metadata filter on the retriever can use it to restrict results by date or jurisdiction without touching the query text.
Your RAG pipeline returns the right documents but the LLM's answer ranks a weakly relevant chunk first, burying the best evidence. Which postprocessing step is the most targeted fix?
A reranker postprocessor re-scores already-retrieved candidates and reorders them, which is exactly the right tool when the right nodes are present but misordered.
After calling query_engine.query("What is the refund policy?"), what should you inspect BEFORE trusting the answer the LLM returns — and why?
Checking source nodes lets you confirm the answer is grounded in your documents rather than fabricated by the LLM.
You want to know whether your retriever is actually surfacing the chunk that contains the ground-truth answer. Which evaluation approach directly measures this?
Hit-rate (retrieval recall) directly measures whether the node that contains the correct answer is present in the packed context, which is the retrieval-level check before you even involve the LLM.