Hybrid Retrieval Combining Dense Vectors and Live Web Search

Dense vectors miss SKUs and keywords miss paraphrases, so fuse both.

· 16 min read · Updated
Cover illustration for “Hybrid Retrieval Combining Dense Vectors and Live Web Search”
RAG Architecture · October 1, 2026 · 16 min read · 3,500 words

A customer support bot gets a query for "SKU AZ-4471." The correct product sheet sits in the knowledge base, fully indexed, ready to be retrieved. The bot answers with a different product instead, one that reads as plausible but is simply wrong. That failure, not an abstract description of embedding math, is where the case for hybrid retrieval has to start. The vector representing "AZ-4471" carries almost no semantic content: it's an alphanumeric string, not a concept, and the embedding model encodes it into a region of vector space crowded with other low-signal identifiers rather than the specific product page that contains it. The correct document is outranked by passages that are topically adjacent but factually wrong, and the retriever hands the language model a confident answer built on the wrong source.

This is a structural property of dense embeddings. Embedding models are trained to place semantically similar text near each other in vector space, which makes them excellent at matching "how do I fix a slow laptop" to a document about performance troubleshooting even when none of the words overlap. The same mechanism that produces that strength is the mechanism that produces the SKU failure: models encode meaning, and meaning is exactly what a serial number, an error code, or a customer ID does not have in any useful sense. A user querying "SKU AZ-4471" illustrates the problem: the correct document is in the corpus, but the embedding vector lands in generic space, outranked by irrelevant passages.

The failure also runs in the opposite direction: a user asks "how do I return a damaged item?" and the right document, titled "Refund Policy for Defective Products," contains no shared words with the query beyond "item" or "product," so a pure keyword index returns nothing useful. Neither failure is rare or edge-case: one is a vocabulary mismatch problem, the other is an entity-recognition problem, and both are common in the query distribution any real production system sees every day.

A third limitation sits underneath both failures: no embedding corpus, regardless of how carefully it's chunked or indexed, can contain facts that didn't exist at indexing time, and this limitation earns its own section later. That's a separate problem from the SKU and refund-policy failures above, and conflating the two obscures the fact that each demands a different architectural fix. In agentic pipelines, the stakes compound. A single retrieval miss doesn't only produce one wrong answer to one question. It can cause an agent to pick the wrong tool, skip a clarification it should have asked for, or carry bad context forward across several turns of a multi-step task, which means the cost of a retrieval failure in an autonomous system is rarely contained to the single response where it first appears.

How BM25 and dense vectors each fail

BM25 and dense vector retrieval don't share failure modes, and that non-overlap is precisely what makes combining them productive rather than redundant.

BM25 is a sparse, term-frequency-based ranking function, and its strength is exact match: product SKUs, error codes, version numbers, regulatory clause citations, and person names all retrieve reliably. It requires no neural inference at query time, which means it runs on an inverted index on ordinary CPU hardware, fast and cheap. Its weakness is the mirror image of its strength: a query for "automobile repair" will not retrieve a document about "car maintenance" unless the two share vocabulary, because BM25 has no notion of conceptual equivalence.

Dense vector retrieval flips both the strength and the weakness. It captures semantic equivalence across vocabulary mismatches, which is exactly why it retrieves "Refund Policy for Defective Products" for a query about returning a damaged item despite zero shared words. Its weakness is low-frequency tokens: identifiers, codes, and names get encoded as low-signal noise, in part because the embedding model may never have encountered that specific token during training.

Query type determines which branch should win, and that assignment is testable rather than theoretical. A query like "Order AP-8127 ship date" is squarely BM25 territory: an exact identifier with an unambiguous right answer. A query like "why is my app slow on cold start" is squarely dense-plus-rerank territory: a conceptual question with many valid phrasings. A query like "refund policy for EU enterprise" needs both branches running in parallel plus a metadata filter to scope the result to the right jurisdiction and account tier.

| Query type | Example | Retrieval branch | |---|---|---| | Exact identifier | "Order AP-8127 ship date" | BM25 | | Conceptual / paraphrase | "Why is my app slow on cold start" | Dense + rerank | | Scoped and conceptual | "Refund policy for EU enterprise" | Both + metadata filter |

The table is a diagnostic. What it shows is that the two retrieval methods are answering different questions about the same corpus, and a system that only runs one of them is structurally blind to whatever the other one catches.

Reciprocal Rank Fusion as the practical glue between two incompatible score spaces

Knowing that BM25 and dense retrieval are complementary doesn't automatically tell you how to merge their outputs into one ranked list a language model can consume.

Reciprocal Rank Fusion discards raw scores entirely and works with rank position instead. Each document gets a contribution based on where it lands in each ranked list, using a smoothing constant in the denominator that keeps a single first-place finish from completely dominating the fused order. A document that ranks highly in both the BM25 list and the dense list accumulates a larger combined score than a document that ranks first in one list and nowhere in the other, and that's the entire mechanism.

A minimal implementation treats each retrieved list as a set of unique document IDs, iterates through both lists, and accumulates a reciprocal-rank contribution for each document each time it appears:

def reciprocal_rank_fusion(ranked_lists, k=60):
 scores = {}
 for ranked_list in ranked_lists:
 for rank, doc_id in enumerate(ranked_list):
 scores[doc_id] = scores.get(doc_id, 0) + 1 / (k + rank + 1)
 return sorted(scores.items(), key=lambda x: x[1], reverse=True)

A straightforward implementation treats each list as unique document IDs and accumulates reciprocal rank contributions, so the document appearing highly in both lists wins the fused ranking.

Fusion produces an ordering, and an ordering is not the same as a validated answer. RRF tells you which documents both retrieval paths agree are relevant. It does not check whether the top-ranked document actually answers the question, which means evaluation still has to happen downstream of fusion, not instead of it. The smoothing constant in the formula, along with any weighting between the two branches, is a parameter to tune against a team's own held-out queries rather than a fixed constant to copy from a blog post: a corpus dominated by identifiers will want more weight on the BM25 branch, while a corpus dominated by conceptual documentation will want more weight on the dense branch.

Permission and version filters need to apply consistently across both retrieval paths before results get merged, because a document a given tenant isn't allowed to see must not re-enter the prompt just because it happened to rank well on one branch and slip through before the filter catches it.

Static hybrid retrieval and the knowledge cutoff no index can solve

Re-indexing a large corpus continuously carries a cost in compute and engineering time that makes constant freshness impractical for most teams. Call it the re-indexing tax: a background process that keeps re-embedding and re-fusing introduces its own delays and version drift, and the practical result is that the index becomes a lagging indicator of the world rather than a live one.

The failure this produces is systematic. It's systematic, and it hits the same category of query every time: a question about a recent earnings release, a new regulatory update, a breaking news event, or a research finding published after the last indexing run will hit the wall regardless of how well the hybrid retrieval branch is tuned. No improvement to RRF weighting, no better cross-encoder, no smarter chunking strategy closes this gap, because the gap comes from stale data, not poor retrieval quality, and stale data needs a different fix entirely.

In an agentic pipeline the consequence is worse than a simple wrong answer. An agent that cites a superseded policy or a stale stock figure as though it were current produces output that reads as confident and well-sourced, which makes it harder to catch than an obvious hallucination that announces itself through incoherence. A wrong answer that sounds uncertain gets double-checked. A wrong answer built on a stale but internally consistent fact often doesn't.

The architectural response is Just-In-Time data retrieval: instead of pre-indexing everything and hoping the index stays current, the system pulls fresh, structured information at the moment a query needs it, so the agent's knowledge of the world is as current as the query itself rather than as current as the last re-indexing job, and this is the segue into live web search as a distinct architectural layer that solves the staleness a static index cannot fix on its own.

What live web search adds to the retrieval stack

Live web search closes the temporal gap by delivering cited, current facts at the moment of the query, which is the one capability an embedding corpus cannot structurally provide no matter how it's engineered. It is worth thinking of this as a branch added to the pair of retrieval methods already in place.

The practical API surface for developers splits into distinct tiers, each doing a different job. Web search APIs return snippets formatted for direct consumption by a language model along with citation metadata attached to each snippet. Content extraction APIs take a raw URL and convert it into structured Markdown a downstream system can parse reliably. Deep research APIs run multi-step agentic loops, chaining several searches and extractions together, and return a structured, cited output at the end of the process. Choosing among these tiers is itself an architecture decision: a simple factual query needs only the first tier, while a query that requires synthesizing several sources needs the third.

Live search has its own failure mode, and it's the mirror image of the hybrid index's failure mode. It returns breadth without depth: it surfaces what's publicly available and recent, but it has no access to an organization's private knowledge base, proprietary data, or versioned internal documentation, none of which lives on the public web. A live search branch bolted onto a pipeline with no internal hybrid index answers "what happened in the news today" well and "what does our internal refund policy say" not at all.

Latency is the primary engineering cost of adding this layer. Sequential URL scraping adds multiple seconds of wall-clock time per call, which is untenable for most production latency budgets. The practical fix is parallelization: firing scrape requests concurrently rather than in sequence is what makes a live web branch viable inside a pipeline with real latency targets. That is an engineering problem with a known engineering solution.

The honest architectural picture is a division of labor: live web search covers temporal freshness and external, public facts, while the hybrid vector index covers internal knowledge, semantic matching within a private corpus, and exact-match entity recall. Neither layer, run alone, covers what the other one does, and a production system that only builds one of the two is leaving a known category of query unanswerable.

How the two layers connect in a production pipeline

Put the pieces together and a production hybrid retrieval pipeline resolves into a clear sequence. A production hybrid retrieval pipeline runs parallel retrieval from the BM25 branch, the dense vector branch, and the live web branch, fuses the first two via RRF, and injects web results at the re-ranking stage or as a separate context block with citation metadata. The BM25 and dense results fuse through RRF, producing a single ranked candidate list from the internal corpus. Web results, carrying their own citation metadata, get injected either at the re-ranking stage alongside the fused internal candidates or as a clearly separated context block the model can distinguish from internal knowledge.

Re-ranking is the largest single lever for accuracy after the retrieval strategy itself is decided. A cross-encoder re-ranker looks at each candidate passage against the actual query, after the initial retrieval pass has already narrowed the field, and removes irrelevant context that would otherwise cause the language model to hallucinate around noise. Enterprise benchmarks show meaningful precision gains from adding this stage on top of fused retrieval. What re-ranking cannot do is recover a passage that neither the BM25 branch nor the dense branch surfaced in the first place: it only reorders the candidate pool it's given, which is exactly why coverage at the retrieval stage has to be right before re-ranking ever runs.

One documented instantiation of this architecture is Lyzr Cognis, which pairs OpenSearch BM25 with Matryoshka vector similarity search, fuses them via RRF, and applies a BGE-2 cross-encoder reranker, achieving state-of-the-art results on the LoCoMo and LongMemEval benchmarks. That's one concrete proof that the architecture described above isn't theoretical.

Corpora with real hierarchical structure, code repositories, enterprise wikis, versioned documentation, need one more refinement. Flat metadata filtering on its own isn't enough to keep archived or obsolete branches of a repository from surfacing alongside current ones. A Trie-based, directory-aware index preserves the hierarchical scope of the corpus, so a query about the current version of a document doesn't pull in a deprecated one that happens to share metadata tags.

Evaluating the whole assembled pipeline needs two different measurement layers. BEIR-style NDCG@10 measures retrieval quality in isolation, how well the fused candidate list matches what a human judge considers relevant. RAGAS measures the end-to-end pipeline across four dimensions: faithfulness, answer relevance, context recall, and context precision. Retrieval quality and generation quality are different things, and a pipeline can score well on one while failing the other.

Choosing and evaluating live web search APIs against accuracy and latency benchmarks

Selecting a live web search API is a benchmarking exercise. Latency and accuracy trade-offs differ meaningfully across providers, and the only honest way to choose is to test candidates against the specific query distribution a team actually runs, rather than trusting a single published number.

The openbenchmarks.com evaluation, run on September 26, 2026, tested eleven web search APIs on company-news questions, and pricing varies across the field, with a provider's ranking on accuracy alone not settling the question of which is the right fit for a given budget.

The Artificial Analysis Search Index, covering results from September 2026, benchmarks on a broader set of criteria and produces a different leaderboard depending on what's being measured. Perplexity Search at its medium setting scores highest overall at 80, with BrowseComp accuracy of 87. Octen Search posts the lowest end-to-end task latency in the field. One provider achieves the highest AA-Omniscience accuracy at 73, but pairs that accuracy with the slowest total task time recorded in the benchmark. No single provider wins on every axis: accuracy and speed trade against each other across this entire field, not just for one vendor.

Linkup, notably, is already in production use at McKinsey, KPMG, and Cohere, which speaks to real enterprise adoption rather than benchmark performance alone. You.com's Research API holds the top position on the DeepSearchQA benchmark, and its Finance Research API, launched in May 2026, ranks first on the T2 (Simple Historical Lookup) sub-benchmark of FinSearchComp, a result achieved through evidence reconciliation across conflicting sources combined with licensed structured financial data from providers including S&P Global. The Finance Research API's output format, a JSON object carrying a Markdown response, inline citation tags, and a sources array mapping every citation back to a URL, matters specifically for regulated use cases where reconciling a claim back to its source isn't optional but a compliance requirement. Separately, the Valyu DeepResearch API distinguishes itself through access to more than 36 proprietary data sources, including SEC filings, FRED macroeconomic data, academic literature, and patent databases, returning both retrieval results and structured finance data from a single call.

None of this adds up to one universal answer. The right choice depends on the query type a system needs to serve, the latency budget it has to stay inside, and whether citation provenance is a compliance requirement or a nice-to-have. A team building a consumer chatbot has different constraints than a team building a regulated financial research tool, and the benchmarks above should be read against that difference rather than collapsed into a single ranking.

Security risks that live web retrieval introduces into agentic pipelines

Opening a pipeline to live web data opens an attack surface that a static vector index simply does not carry, a dimension most architecture guides skip. Prompt injection through retrieved content is the mechanism: when an agent retrieves a document from the open web, processes its contents, and acts on what it finds, a single injected instruction hidden inside that retrieved document can hijack the agent's subsequent behavior. One documented case involved a GitHub MCP server, where a malicious issue contained hidden instructions that took over an agent's workflow and triggered data exfiltration from private repositories.

The scale of the exposure is already measurable. A Gravitee survey of 750 senior technology leaders found that the enterprise AI agent estate had doubled in the four months since December 2025, while security coverage failed to keep pace: fewer than a third of respondents had a plan in place for how agents process sensitive data, and fewer than a third had defined the scope of what their agents are actually permitted to access. Growth in deployment outpaced growth in the policies meant to govern it, and that gap is where incidents like the GitHub MCP case come from.

Part of what widened the surface is the rapid adoption of the Model Context Protocol as an integration standard connecting agents to tools and data sources. That adoption, and the standardization it brought, also opened room for MCP tool poisoning, now recognized as a distinct attack vector in hybrid retrieval contexts where an agent calls out to external tools as part of its retrieval process.

None of this argues against building live web retrieval into a pipeline. It argues for treating every piece of retrieved external content as untrusted input by default. That means running agent actions inside sandboxed execution environments, applying automated PII masking to anything pulled from external sources, enforcing permission filters consistently across every retrieval path rather than just the internal ones, and keeping auditable logs of agent actions for any regulated environment. Zero data retention and SOC2 certification at the infrastructure layer belong in the baseline requirements for an enterprise pipeline, not on a list of premium features to add later. Security here is a design decision made at the same time as the retrieval architecture.

Where "keyword search is all you need" breaks down

The strongest challenge to everything argued above comes from a 2025 paper by Subramanian and colleagues, which makes the case that well-tuned sparse retrieval closes more of the gap with dense and hybrid methods than the hybrid-retrieval consensus tends to admit. It's worth taking that challenge seriously rather than dismissing it, because the case for BM25's continued relevance rests on real advantages laid out earlier in this piece: it runs cheaply on CPU with no neural inference at query time and it handles exact-match queries with total reliability. For a corpus that's dominated by structured identifiers, part numbers, ticket IDs, legal citations, a tuned sparse index may get most of the way to what a full hybrid system would deliver, at a fraction of the engineering cost.

Where does that argument break down? It breaks down exactly at the query type that produces no token overlap between the user's words and the document's words: BM25 alone misses "how do I return a damaged item?" when the document is titled "Refund Policy for Defective Products," while dense vector retrieval captures that semantic equivalence across the vocabulary mismatch and retrieves it. No amount of tuning makes a term-frequency method understand that "how do I return a damaged item" and "Refund Policy for Defective Products" are asking about the same thing, because that understanding requires exactly the semantic representation BM25 was built without. And even a perfectly tuned sparse-plus-dense hybrid still runs into the temporal ceiling described earlier: no index, however it's weighted or fused, can answer a question about something that happened after the index was built.

The keyword-first case is strongest as a claim about cost and simplicity for a specific, identifier-heavy corpus. It's weakest as a claim about general-purpose retrieval across the full range of query types a production system actually has to serve, which is the same range this piece opened with: the SKU that dense search cannot find, and the refund policy that keyword search cannot find, sitting in the same knowledge base, waiting on the same query interface.

Sources

  1. Hybrid Search Guide: Vectors & Full-Text (April 2026)
  2. Directory-Aware Query and Maintenance in Vector Databases
  3. Cognis: Context-Aware Memory for Conversational AI Agents
  4. Vector Search with OpenAI Embeddings: Lucene Is All You Need
Filed underRAG Architecture

More in RAG Architecture