Quickstart: retriever CLI
Use
retriever ingestandretriever queryfor product-facing workflows.
Quick start¶
Local ingest embeds on the local GPU when --embed-invoke-url is unset. Install
the [local] extra before you run the default retriever ingest or
retriever ingest batch commands:
pip install "nemo-retriever[local]"
If you installed the base package for Remote NIM with no local GPU, keep that
install and pass --embed-invoke-url instead. Refer to
Route ingest to hosted or self-hosted NIM endpoints.
Ingest a PDF locally¶
From a clone of this repository, ./data/multimodal_test.pdf is a valid
first-run input. If you installed from PyPI, pass a PDF file that you supply.
retriever ingest ./data/multimodal_test.pdf
Then query the default LanceDB table:
retriever query "What is in this document?"
By default, local ingest auto-detects supported input formats and writes to
lancedb/nemo-retriever; retriever query reads from the same table. Use
explicit high-level options when a task needs behavior beyond the current ingest
defaults.
The plain retriever query examples below apply to local and batch ingest output
written to LanceDB. Use retriever query service to query a Retriever service.
Ingest a larger corpus with batch mode¶
Replace /path/to/your/pdfs with a directory of PDF files that you supply. The
repository and the PyPI package do not include a pdf_corpus dataset.
retriever ingest batch /path/to/your/pdfs \
--profile fast-text \
--pdf-extract-workers 4 \
--embed-workers 2
Batch mode exposes Ray runtime and batch tuning flags such as --ray-address,
--pdf-extract-workers, --ocr-workers, and --embed-workers.
Ingest through a Retriever service¶
Replace /path/to/your/pdfs with a directory of PDF files that you supply.
retriever ingest service /path/to/your/pdfs \
--service-url http://localhost:7670 \
--service-concurrency 8
Use --service-api-token or NEMO_RETRIEVER_API_TOKEN when the service requires
a bearer token. Service ingest does not expose --lancedb-uri; the service
configures its vector database. Query the service with:
retriever query service "What is in this corpus?" \
--service-url http://localhost:7670
Start a local service with VectorDB¶
Use retriever service start --launch-vectordb to run a local service with a supervised VectorDB child on 127.0.0.1:7671. The child uses nim_endpoints.embed_invoke_url when configured. Otherwise, it uses local Hugging Face embedding when local_models.enabled and local_models.embed.enabled are both true. The command waits for VectorDB readiness and terminates the child when the service exits. If the child does not exit promptly, the service forcefully stops it. You can set the same behavior in YAML with vectordb.launch_on_start: true and a loopback vectordb.vectordb_url.
The child inherits credentials from the service environment. Set NVIDIA_API_KEY or NGC_API_KEY for remote embedding, and set NRL_INTERNAL_VDB_TOKEN or NRL_INTERNAL_VDB_TOKEN_FILE for the VectorDB internal credential. Do not place credentials in the service YAML.
For a fully local deployment, use a CUDA-capable host and install the service and local extras. Install the multimedia extra when you ingest audio or video.
pip install "nemo-retriever[service,local]"
scripts/launch_local_service_with_vectordb.sh \
nemo_retriever/examples/retriever-service.local.yaml
The example configuration leaves NIM endpoints unset and uses local Hugging Face models. The launcher validates /v1/health on the service and VectorDB, then keeps both processes running until you stop it with Ctrl+C.
retriever service start --config my-retriever-service.yaml --launch-vectordb
Use the command above when nim_endpoints.embed_invoke_url is configured. Omit the flag to use an existing VectorDB. Helm continues to deploy VectorDB as a separate pod.
If VectorDB exits during startup or does not become ready, inspect the VectorDB output in the terminal that started the service. Verify the VectorDB configuration, embedding model setup and credentials, writable LanceDB directory, and that port 7671 is available.
Route ingest to hosted or self-hosted NIM endpoints¶
export NVIDIA_API_KEY=nvapi-...
retriever ingest ./data/multimodal_test.pdf \
--page-elements-invoke-url https://ai.api.nvidia.com/v1/cv/nvidia/nemotron-page-elements-v3 \
--ocr-invoke-url https://ai.api.nvidia.com/v1/cv/nvidia/nemotron-ocr-v2 \
--table-structure-invoke-url https://ai.api.nvidia.com/v1/cv/nvidia/nemotron-table-structure-v1 \
--embed-invoke-url https://integrate.api.nvidia.com/v1/embeddings \
--embed-model-name nvidia/llama-nemotron-embed-1b-v2
NVIDIA_API_KEY is required only when those URLs point at hosted
build.nvidia.com endpoints. NGC_API_KEY is used separately when pulling or
running self-hosted NIM containers.
To rerank local query results with the hosted vision-language reranker, pass the
NVIDIA-hosted /reranking endpoint and model. Use the same NVIDIA_API_KEY that
authorizes the hosted embedding URL:
retriever query "What is in this document?" \
--embed-invoke-url https://integrate.api.nvidia.com/v1/embeddings \
--embed-model-name nvidia/llama-nemotron-embed-1b-v2 \
--reranker-invoke-url https://ai.api.nvidia.com/v1/retrieval/nvidia/llama-nemotron-rerank-vl-1b-v2/reranking \
--reranker-model-name nvidia/llama-nemotron-rerank-vl-1b-v2 \
--reranker-api-key-env NVIDIA_API_KEY
Passing --rerank without --reranker-invoke-url uses the local GPU reranker,
not this hosted endpoint.
A Cohere-style /v1/rerank URL is a gateway route, not an NVIDIA-hosted NIM
endpoint. Pass the full URL that your gateway exposes, for example
https://<your-gateway>/v1/rerank, and the model name that gateway expects.
Set --reranker-api-key-env to an environment variable that holds a credential
issued by that gateway. A gateway that expects a LiteLLM virtual key that starts
with sk- rejects NVIDIA nvapi- keys and NGC keys.
Query result controls¶
Both retriever query and retriever query service return compact JSON hits
with source, page_number, and text. Use --candidate-k, --page-dedup,
and --content-types to control how results are selected after vector
retrieval:
retriever query "annual revenue by region" \
--top-k 5 \
--candidate-k 40 \
--content-types table
--top-k is the final number of results to return after filtering and
deduplication. --candidate-k is the number of raw results to retrieve from
LanceDB or the Retriever service before filtering, page deduplication, and
final truncation. If omitted, the candidate pool is the same size as
--top-k. Set --candidate-k larger than --top-k when page deduplication
or content-type filtering might remove too many of the nearest retrieved rows.
It must always be greater than or equal to --top-k.
Page deduplication and content-type filtering are applied after vector
retrieval, preserving retriever ranking order and truncating the final output to
--top-k. Local and batch ingest record the canonical embedding model on the
LanceDB table, and non-service query uses that model automatically. Use
--embed-model-name only as an explicit override or when querying a legacy or
third-party table without model metadata. If the explicit model differs from
the model recorded on the table, the query logs a warning that names both
models and continues with the explicit override. Confirm that the models use a
compatible vector space before you trust the relevance results. Endpoint URLs
and provider prefixes remain runtime configuration, so continue to pass
--embed-invoke-url and --embed-model-provider-prefix when the selected model
must be routed remotely.
For example, a table can store the canonical model
nvidia/llama-nemotron-embed-vl-1b-v2 while a LiteLLM-routed request uses
nvidia/nvidia/llama-nemotron-embed-vl-1b-v2. The endpoint and routing prefix
are intentionally not persisted on the table.
--content-types accepts comma-separated content types such as text, table,
chart, image, and infographic. images is accepted as an alias for
captioned image rows emitted by ingest. This option filters by content-type
metadata only; it does not filter by source, page, or other metadata
predicates. Hits with missing or unknown content-type metadata are excluded
while --content-types is active. In service mode, results must include
content-type metadata to match this filter. Default display values in the JSON
output are not used for content-type matching.
Agentic retrieval¶
--agentic swaps the single dense pass for an LLM-driven ReAct loop: the agent
issues several retrieval sub-queries, fuses the candidates, and selects a final
ranking. It searches the same LanceDB table built by retriever ingest. You can
reuse the same table, embedding flags, and --top-k as standard retrieval.
The JSON hit shape is not a drop-in replacement for dense retriever query
output.
By default, agentic retrieval runs the agent LLM in process with local vLLM and
nemotron-8b (nvidia/Llama-3.1-Nemotron-Nano-8B-v1). This requires a CUDA GPU
host and the local extras installed. Provide --agentic-invoke-url when you want
a custom model or a separately hosted OpenAI-compatible endpoint.
# default local vLLM agent LLM: nemotron-8b
retriever query "how does the ingestion pipeline handle tables?" \
--agentic
# custom/self-hosted model through an OpenAI-compatible endpoint
retriever query "summarize the deployment options" \
--agentic \
--agentic-llm-model custom-remote-model \
--agentic-invoke-url http://localhost:9000/v1/chat/completions \
--embed-invoke-url http://localhost:8000/v1 \
--agentic-react-max-steps 5
Agentic mode returns the agent's ranked documents as JSON. The dense path
projects each hit to five fields: modality, page_number, score,
source, and text. Agentic mode does not use that projection. It prints
the internal hit dictionary plus doc_id, rank, and result_source.
result_source is final_results, rrf, or selection_agent, depending
on which stage produced the ranking.
modality and score exist only on the dense path. Fields such as
content_type, _distance, metadata, path, pdf_basename,
pdf_page, and source_id appear on the agentic path when the retrieval
hop returned them.
Hit fields are rehydrated at the end of the loop from the retrieval hop
that returned the document. When the agent names a document that no
retrieval hop returned, the object contains only doc_id, rank, and
result_source. Classic hit keys such as text and source are
absent. They are not present with null values.
Agentic retrieval reuses the same --top-k, --lancedb-uri, --table-name,
--embed-invoke-url, and --embed-model-name options as standard retrieval.
Agentic retrieval uses the selected table's model automatically when
--embed-model-name is omitted.
How it works. Each agentic query runs Query -> ReActAgentOperator -> (RRF
fusion) -> SelectionAgentOperator -> ranked results:
ReActAgentOperatorruns the per-query ReAct loop; everyretrievetool call delegates to the standardRetriever, so the agent searches the same vector DB and embedding config as dense retrieval.RRFAggregatorOperatorfuses candidates from the loop's multiple searches with reciprocal rank fusion.SelectionAgentOperatorruns a final LLM selection pass over the fused set and emits ranked document IDs. Those IDs are then rehydrated from the retrieval-hop hit dictionary.
Agentic-only knobs (apply only with --agentic):
--agentic-llm-model— local profile alias/model ID when no invoke URL is provided (nemotron-8bby default;super-49balso supported), or the remote model ID when--agentic-invoke-urlis provided.--agentic-local-tensor-parallel-size(default1) — vLLMtensor_parallel_sizefor the in-process agent LLM. Use2+with matchingCUDA_VISIBLE_DEVICESfor multi-GPU local profiles (for examplesuper-49b). Ignored when--agentic-invoke-urlis set. When the firsttensor_parallel_sizeCUDA-visible GPUs are not NVLink-connected (typical dual-GPU PCIe workstations), tensor-parallel startup automatically setsNCCL_NVLS_ENABLE=0andTORCH_SYMM_MEM_DISABLE_MULTICAST=1, because NVLink multicast collectives abort vLLM startup there; set either variable yourself to override. Detection is scoped to that TP device group, not the whole host or extra visible GPUs outside the shard.--agentic-invoke-url— OpenAI-compatible chat-completions endpoint for the agent LLM. Providing it routes agent LLM calls to that remote endpoint; omit it to run the in-process local model.--agentic-llm-client(optional) — LLM client that builds the agent LLM. Defaults tocallable. It drives the in-process adapter when--agentic-invoke-urlis omitted, and the shared chat-completions HTTP client when it is set.--agentic-reasoning-effort(defaulthigh) —reasoning_effortforwarded on OpenAI-compatible agentic LLM calls; ignored by the local adapter.--agentic-react-max-steps(default50) — maximum ReAct loop iterations.--agentic-text-truncation(default0) — max characters of each candidate shown to the agent;0disables truncation.--agentic-temperature(default: unset) — sampling temperature for agent LLM calls; omit to use the endpoint/model default (0.0= greedy). Local and non-NVIDIA OpenAI-compatible endpoints allow up to2.0; NVIDIA-hosted endpoints allow up to1.0.