Retrieval
A retriever only answers “given a query string, return Nodes.” It does not call the LLM. That is the first stage inside a QueryEngine. Pulling it out lets you mix retrievers, wrap it as an agent tool, or call it from a Workflow step.
Async: await retriever.aretrieve(query). Score scales differ by backend (cosine / inner product / distance)—do not compare raw scores across stores.
VectorIndexRetriever
Explicit form of as_retriever:
as_query_engine(similarity_top_k=...) forwards that argument to the inner retriever. Debug recall with a fixed k and printed text before attaching a synthesizer.
Postprocessors: filter and rerank
From the official querying guide:
Production often adds a reranker (cross-encoder) on the top-k. Class names and extra packages change—use current Node Postprocessor docs rather than stale imports.
Metadata filters
metadata written at ingest time can filter at query time (tenant, year, file type). Syntax varies slightly by vector store; the idea is the same: shrink candidates, then score.
Keys must match ingest. If your installed version’s MetadataFilters API differs, follow the official vector-store page.
Better recall (same ideas as the RAG course)
The RAG tutorial explains why. Here we map where. When the model chooses query strings and hops, that is agentic RAG: expose the retriever or query engine as a FunctionAgent tool (Query Engines).
Retrieve only, generate yourself
This is easy to unit-test (assert on retrieve) and easy to hand to LangChain or CrewAI: they receive a string tool result and do not need LlamaIndex’s synthesizer.