How-to · OpenTelemetry

How to Observe LlamaIndex and RAG Pipelines with OpenTelemetry

Observing a RAG pipeline with OpenTelemetry means tracing both halves of retrieval-augmented generation, the retrieval step (embedding and vector search) and the generation step (the LLM call), over OTLP, so a bad answer can be diagnosed as a retrieval problem or a generation problem, not just labelled slow..

Observing a RAG pipeline with OpenTelemetry means tracing both halves of retrieval-augmented generation, the retrieval step (embedding and vector search) and the generation step (the LLM call), over OTLP, so a bad answer can be diagnosed as a retrieval problem or a generation problem, not just labelled slow.

Why RAG needs its own observability

A retrieval-augmented generation pipeline has two failure surfaces, and confusing them wastes hours. Retrieval fetches context: it embeds the query, searches a vector store, and optionally reranks. Generation passes that context and the query to the LLM to produce an answer. When an answer is wrong, the cause is very often retrieval, the wrong or too few chunks were returned, not the model. So you must observe the retrieval step specifically: what it retrieved, how relevant it was, and how long it took, alongside the usual token, cost and latency of the LLM call.

How to instrument a RAG pipeline

OpenTelemetry has emerging GenAI semantic conventions for LLM and agent spans, and libraries such as OpenLLMetry and OpenInference instrument the popular frameworks to emit them, with token, model and cost attributes, over OTLP. For LlamaIndex, the instrumentation maps the query engine, the retriever, the embedding call, the vector-store lookup and the synthesis LLM call to spans, so the whole pipeline is one trace. The signals to add on top of the standard gen_ai token and cost attributes are retrieval-specific: the number of chunks retrieved, their scores, and the retrieval latency. This is what lets you separate a slow vector search from a slow model, and a poor answer from an expensive one.

Retrieved context and queries can contain sensitive data, so redact or sample captured content while keeping retrieval-quality and token metrics complete.

Key metrics to watch

The signals that explain most RAG incidents:

SignalSourceWhat it tells you / watch for
retrieval result countretriever instrumentationHow many chunks came back; too few (or zero) is the usual cause of a poor, ungrounded answer.
retrieval span latencyretriever instrumentationEmbedding plus vector-store lookup time; a slow vector store drags the whole request.
retrieval relevance / scoresretriever instrumentationThe similarity scores of retrieved chunks; low scores mean the context is weak even if plenty was returned.
gen_ai.usage tokens (context size)LLM instrumentationInput tokens reflect how much context was stuffed in; large context drives cost and latency.
gen_ai.client.operation.durationLLM instrumentationGeneration latency; grows with context and output size.
end-to-end pipeline latencyquery spanTotal query time, split between retrieval and generation so you know which half to fix.

What to put on a dashboard

A RAG dashboard should separate retrieval from generation. Row one is retrieval quality: result count and relevance scores per query type, and retrieval latency, so a weak or slow retriever is obvious. Row two is generation: input tokens (context size), model latency and cost. Row three is the whole pipeline: end-to-end latency split into retrieval versus generation, which tells you where to invest.

# retrieval returning too little (poor answers upstream)
avg(rag.retrieval.result_count) by (query_type)

# retrieval vs generation latency (which half is slow?)
histogram_quantile(0.95, rag.retrieval.duration)
histogram_quantile(0.95, gen_ai.client.operation.duration)

# context size creeping up (cost and latency)
avg(gen_ai.usage.input_tokens) by (query_type)

Reading the signals: common failure modes

Poor retrieval, bad answer

The model is healthy but answers are wrong or vague, because retrieval returned too few chunks or low-relevance ones, so the LLM had nothing good to ground on. Result count and relevance scores expose it. Fix the index, chunking, embedding model or query, not the LLM.

Slow vector search

End-to-end latency is high and the retrieval span, not the LLM, dominates, because the vector store is slow (large index, no filtering, cold cache). Retrieval latency isolates it. Tune the vector store, add filtering, or cache.

Context overflow

Cost and latency climb because retrieval is stuffing too much context into the prompt, inflating input tokens. Context size (input tokens) rising is the signal. Cap the number of chunks and rerank so only the most relevant context is passed.

Example alert conditions

Starting thresholds to tune:

ConditionSignalMeaning
retrieval result count near zeroretrievalRetrieval returning nothing; answers will be ungrounded.
retrieval p95 latency > SLOretrievalVector search is the bottleneck.
input tokens (context) > baseline x2costContext overflow inflating cost and latency.
relevance scores droppingqualityRetrieved context is getting weaker.

From monitoring to autonomous resolution

Ops Singularity's AI/ML and Agent Ops pillar operates RAG pipelines in production, ingesting this OpenTelemetry data, watching retrieval quality alongside model cost and latency, and taking governed action when retrieval or generation degrades. Explore AI/ML and Agent Ops and the RAG explainer.

Frequently asked questions

How do I observe a RAG pipeline?

Trace both halves: the retrieval step (embedding, vector search, reranking) and the generation step (the LLM call), capturing retrieval result count and relevance alongside gen_ai token and latency attributes, over OTLP.

Why is my RAG app giving bad answers?

Most often it is a retrieval problem, too few or low-relevance chunks, not the model. Observing retrieval result count and relevance scores tells you whether to fix the index and retrieval or the generation.

How do I track LLM cost with OpenTelemetry?

Capture prompt and completion tokens per call as gen_ai.usage attributes and multiply by the model's price. Because the tokens are on every span, cost rolls up per model, per feature and per request.

See autonomous operations on your own stack.

Bring a real incident. We will show you Sentinel investigate, act and verify end to end, with every action reversible and audited.

Request a Demo →See TelemetryOps