Minimum useful retrieval-span attributes: query, index name, top_k, latency, and per-chunk (id, score, optional preview); without ids and scores you cannot debug which chunk won and why.
Imagine a librarian who fetches books for you on request. After they bring back five books, you want to know what you asked for, which shelf they looked on, how many they were told to bring, how long it took, and for each book: which book it is (call number), how good a match it was (a confidence number), and a few words from the cover so you do not have to open it. Without the call number, you cannot find that book again. Without the confidence number, you cannot tell which book the librarian thought was the best match. Without knowing the shelf, you cannot say whether they searched the right section. A retrieval span is the receipt for that librarian visit; the minimum fields are the ones that let you reproduce and debug what happened.
Concept explanation~2 min read
Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.
Concept explanation~2 min read
Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.
Retrieval is the part of a RAG system that most often goes wrong silently. The LLM produces a fluent-sounding answer; the failure mode is that the retrieved context was wrong, and the fluent answer is a hallucination grounded in bad context. The diagnostic record for this lives on the retrieval span.
This section covers the minimum attribute set on a retrieval span, why each field is required, the cardinality and storage tradeoffs, and how to extend the model for hybrid search and rerankers.
The reproducibility test as the design principle
The minimum attribute set on a retrieval span is the set that lets a developer reproduce the call offline, with no production access. If you can hand a colleague the span alone and they can rebuild the retrieval call in a notebook, the span is complete. If they need to ask 'wait, which index?' or 'what was the filter?' the span is incomplete.
What that implies
The call-level attributes that pass this test:
- query. The user text or a pointer to the query embedding.
- index_name and corpus_version. Which index, which version of the corpus.
- top_k. Number of chunks requested.
- filter or where clause. Any metadata filters applied.
- embedding_model. Which model embedded the query.
- vector_store_params. Any non-default parameters (ANN ef_search, hybrid alpha, etc.).
The per-chunk attributes that pass the test:
- chunk_id, similarity_score, rank for each returned chunk.
With these, the retrieval is reproducible. Without them, debugging a retrieval miss requires re-running production with extra logging, which is slow and often non-deterministic (the index may have changed).
Situations where this technique stops working.
2–4 min · Everything important, quickly.
| Attribute | Why required | Indexed or payload? |
|---|---|---|
| query | Reproduce the call; debug query phrasing | Payload (high-cardinality) |
| index_name | Identify which corpus was queried | Indexed |
| corpus_version | Detect version mismatch | Indexed |
| top_k | Reproduce the call | Indexed |
| filter | Detect filter-related bugs | Payload (often complex) |
| embedding_model | Detect model mismatch | Indexed |
| chunk_id (per chunk) | Join back to corpus, fetch content | Indexed (low-cardinality enough) |
| similarity_score (per chunk) | Debug which chunk won and why | Numeric, indexed |
| content_preview (per chunk) | At-a-glance debug in UI | Payload |
Real products, models, and research that use this idea.
- OpenInference's retrieval.documents attribute is a structured array; Phoenix and Arize AX render it directly as a panel with id, score, and content preview per chunk.
- Pinecone, Weaviate, and Qdrant client SDKs in 2026 ship OTel auto-instrumentation that emits these fields by default, so the developer cost is approximately zero.
What an interviewer would ask next. Try answering before peeking at the approach.
QHow would you log a hybrid (BM25 + vector) retrieval span?
Record bm25_score and vector_score per chunk plus the fused score and the fusion method (e.g. reciprocal rank fusion with k=60). The retrieval span itself carries the query, indexes used, and top_k; per-chunk attributes get the three scores.
Red flags & common mistakes
The phrases that signal junior thinking. Click to expand.
Red flags & common mistakes
The phrases that signal junior thinking. Click to expand.
Logging only the query and the final answer, skipping per-chunk ids and scores, so when retrieval is wrong you cannot tell which chunk won and have to re-run the system to investigate.
60 second bullets to scan on the way to the call.
Why the reproducibility test is the right design principle for span attributes
Call-level attributes (query, index, top_k, filter, embedding model, latency)
Primary sources. Browse if you want the original framing.
Same topic, related formats. Practice these next.