Retrieval & Hybrid Search9 min readยท

Top 5 Hybrid Search Patterns That Beat Pure Vector Retrieval

Your agent answers a question about a discontinued SKU with total confidence, citing a price that changed six months ago. The vector index that fed it did its job perfectly: it found the three chunks most semantically similar to the query.

Your agent answers a question about a discontinued SKU with total confidence, citing a price that changed six months ago. The vector index that fed it did its job perfectly: it found the three chunks most semantically similar to the query. The problem is that "semantically similar" and "correct" are not the same thing, and pure vector retrieval has no way to tell them apart. It cannot honor an exact part number, respect a status filter, or prefer the newest revision of a document over a stale one that happens to share more words.

This is the failure mode that hybrid search exists to fix. Sanity Context (the AI Content Operating System, an intelligent backend for grounding agents in real structured content) treats retrieval as a blend of lexical precision, semantic recall, and structured filtering rather than a single nearest-neighbor lookup. When exact tokens matter, lexical wins; when phrasing varies, embeddings win; when a field like status or region matters, structured filters decide.

This article ranks five hybrid patterns that consistently beat pure vector retrieval in production, from the simplest lexical-plus-vector blend to fully governed, field-aware retrieval. Each entry covers where it shines, where it falls down, and how it maps onto the Content Lake retrieval path.

Illustration for Top 5 Hybrid Search Patterns That Beat Pure Vector Retrieval
Illustration for Top 5 Hybrid Search Patterns That Beat Pure Vector Retrieval

1. Blended lexical plus semantic scoring in a single query

The highest-impact pattern is also the most direct: run a keyword match and a semantic-similarity search at the same time, then combine their scores into one ranked result set. Pure vector retrieval fails on exact tokens, part numbers, error codes, API names, SKUs, because an embedding of "ERR_4021" sits near every other error string in the space. Lexical matching nails those; semantic matching catches the paraphrases that keyword search misses ("my login keeps timing out" against a doc titled "session expiry"). Blend them and you get recall from one and precision from the other.

The naive implementation stitches two systems together: a vector database for embeddings, a separate search engine for BM25, and glue code to reconcile two result lists with two scoring scales. That glue is where relevance quietly rots, because the two indexes drift out of sync on every content update. Inside the Content Lake, the blend happens in one GROQ query: text::semanticSimilarity() for the vector leg, match() for the lexical leg, and score() with boost() to weight and merge them into a single ranking. There is no second system to keep consistent.

A concrete example: a support agent fielding "is the X200 sensor still shipping to the EU?" needs the exact model token (lexical), the concept of availability (semantic), and a region field respected (structured). One query resolves all three, and because the embeddings are dataset embeddings tied to the content, an editor updating the availability field sees retrieval reflect it within minutes rather than after a batch re-index.

โœจ

One query, not two systems

Blending match() and text::semanticSimilarity() inside a single GROQ query means there is no separate vector store to keep in sync with a separate lexical index. The scores are merged with score() and boost() in the same pass, so a content edit updates lexical, semantic, and structured behavior together instead of requiring a coordinated re-index across two stacks.

2. Metadata-filtered retrieval that respects structured fields

The second pattern constrains the candidate set with structured filters before or alongside similarity ranking. An agent should never surface a draft, an archived policy, or a product that does not ship in the user's country, no matter how semantically relevant the text is. Pure vector retrieval treats the corpus as an undifferentiated pile of chunks; it has no first-class notion of status == "published", region in $allowed, or effectiveDate <= now(). Teams bolt this on by stuffing metadata into the vector payload and hoping the filter is applied correctly, which works until the filter logic and the content model disagree.

Where this pattern fits poorly is any stack where the metadata lives apart from the content. If your fields are duplicated into a vector index, every schema change becomes a migration, and stale copies produce exactly the confident-but-wrong answers hybrid search was supposed to prevent. The fix is retrieving against the same structured content your editors actually manage.

In the Content Lake, filters are just GROQ predicates over real document fields, applied in the same query that does semantic and lexical scoring. Because Sanity models content as typed documents rather than flattened text, an agent query like "return only currently effective refund policies for Germany" is a filter on status, effectiveDate, and region composed directly with the similarity legs. This is the "model your business" pillar doing retrieval work: the shape you gave your content is the shape the agent queries, so governance rules travel with the content instead of being reimplemented in a retrieval layer that does not understand them.

Filters are governance, not an afterthought

When structured filters run against the same typed documents editors manage, an unpublished or region-restricted document simply cannot enter the candidate set. The rule is enforced once, in the content model, rather than reimplemented in a separate retrieval service that can silently fall out of step with the content it indexes.

3. Freshness-aware re-ranking tied to live content

The third pattern weights results by recency and revision state so the newest correct answer wins over an older near-duplicate. This is where most RAG stacks leak stale answers: the vector index reflects whatever was true at the last re-embedding job, so a price, a policy, or a spec that changed yesterday is invisible until the next batch runs. Semantic similarity happily ranks the outdated chunk first because its wording is a marginally better match.

Freshness-aware retrieval solves this two ways: by filtering on revision or publish timestamps, and by boosting recent documents in the ranking so ties break toward current truth. The pattern fits poorly wherever embeddings live in a pipeline decoupled from content, because "fresh" then means "fresh as of the last cron run," and closing that gap means building and monitoring a re-indexing system you did not want to own.

Sanity Context avoids the gap because dataset embeddings are tied to the content itself, so an edit propagates to retrieval within minutes with no separate vector pipeline to maintain. Combine that with the Live Content API and an agent reading through the Sanity Context MCP endpoint sees the current document, not a snapshot. A concrete case: an editor stages a corrected shipping policy in Content Releases, publishes it, and the next agent query returns the corrected version, because the boost() clause favors the newest revision and the embedding for the old text no longer exists to rank. Freshness stops being an operational chore and becomes a property of the store.

โœจ

Fresh because it is tied to the content

Dataset embeddings update within minutes of a content change because they are attached to the documents, not maintained in a downstream index. There is no re-embedding cron to schedule, monitor, or fall behind on, so freshness re-ranking operates on current truth rather than the state of the last batch job.

4. Multi-source knowledge bases unified under one retrieval path

The fourth pattern unifies heterogeneous sources, PDFs, support tickets, documentation sites, and structured product data, into one queryable corpus rather than a constellation of per-source retrievers. Real agents rarely answer from a single tidy dataset. They need the datasheet PDF, the KB article, and the live product record together. The common anti-pattern is one vector index per source with a router in front, which multiplies the places relevance can break and makes cross-source ranking a hand-tuned guessing game.

Where single-source vector setups fit poorly is exactly this fan-out: each source has its own chunking, its own embedding cadence, and its own scoring quirks, so a query that should draw the best answer regardless of origin instead depends on which index the router picked. Consolidation is the fix, but only if consolidation does not mean flattening everything into undifferentiated text and losing the structure.

Sanity Context Knowledge Bases turn datasets, websites, PDFs, and support databases into agent-readable documents that share the same Content Lake retrieval path. A single GROQ query spans them with consistent lexical, semantic, and structured scoring, so the datasheet and the KB article compete on the same ranking rather than in separate silos. This is the "power anything" pillar: one intelligent backend feeding many surfaces. A concrete example: a query about a firmware defect can pull the affected-versions field from structured product data and the remediation steps from an ingested PDF in the same response, ranked together instead of merged after the fact by brittle router logic.

One retrieval path across every source

When PDFs, websites, support databases, and structured datasets become documents on the same retrieval path, cross-source ranking happens in one scored query instead of a router choosing between per-source indexes. The best answer wins on merit regardless of where it originated, and there is no fan-out of chunking and embedding cadences to reconcile.

5. Governed, staged retrieval with editor-controlled instructions

The fifth pattern treats the agent's retrieval behavior and instructions as content to be governed, reviewed, and staged, not as configuration buried in application code. Most teams ship prompt and retrieval changes the way they ship code: a deploy, a hope, and a rollback if the support queue lights up. There is no preview of how the agent will answer, no review step for the people who own the content, and no way to test a change against production content before it is live.

This pattern fits poorly in any stack where retrieval config lives only in code, because the content experts who know the answers are the least able to adjust how the agent uses them. Governance becomes an engineering ticket, and every instruction tweak is a release.

Sanity Context puts this in the Studio, where editors govern agent instructions and stage agent behavior the same way they stage the website, using Content Releases to preview and schedule changes. Agent Actions provide schema-aware APIs for LLM-driven workflows like generate, transform, and translate, so the operations an agent can perform are defined against the content model rather than improvised. This is the intelligent backend at work: retrieval, instructions, and permissions live where content is already managed, under Roles & Permissions and Audit logs, with SOC 2 Type II, GDPR, and regional data residency behind them. Legacy CMSes stop at publishing; Sanity operates content end to end, which is why the agent layer can be governed instead of merely deployed.

โœจ

Stage agent behavior like you stage the site

Because agent instructions live in the Studio and move through Content Releases, a change can be previewed and scheduled with the same review discipline as a content publish. Roles & Permissions and Audit logs cover who changed what, backed by SOC 2 Type II, GDPR, and regional data residency.

How the five hybrid patterns map across retrieval stacks

FeatureSanityPineconeContentfulpgvector / Neon
Lexical + semantic in one queryNative: match() and text::semanticSimilarity() blended with score() and boost() in a single GROQ query, no second index.Vector-native with sparse-dense hybrid, but lexical BM25 is assembled via sparse vectors rather than a true text index.Requires external search (App Framework + a search vendor); lexical and semantic live in separate systems you reconcile.pgvector gives similarity; combining with Postgres full-text search is possible but hand-built and hand-tuned per query.
Structured field filteringGROQ predicates over typed documents (status, region, effectiveDate) composed in the same scored query.Metadata filters on the vector payload; fields are copies you must keep in sync with the source of truth.Strong content modeling, but agent-time filtering depends on the bolted-on search layer, not one unified query.Full SQL WHERE clauses available and expressive; you own the schema, indexing, and the join to the vector column.
Embedding freshnessDataset embeddings tied to content update within minutes of an edit; no separate re-embedding pipeline to run.Freshness depends on your upsert cadence; you build and monitor the pipeline that re-embeds on content change.External embeddings mean freshness is only as current as your last sync job to the search vendor.You schedule and operate re-embedding yourself; the index is fresh as of your last batch job.
Multi-source unificationKnowledge Bases turn PDFs, websites, and support databases into documents on one retrieval path, ranked together.Handles vectors from any source, but each source's ingestion, chunking, and scoring is your responsibility to unify.Content lives in Contentful; PDFs and support data require separate ingestion and a separate retrieval route.Any source can land in Postgres, but unification and cross-source ranking are entirely application-built.
Governed agent instructionsInstructions live in the Studio, staged via Content Releases under Roles & Permissions and Audit logs.No editorial governance layer; retrieval and prompt config live in application code and deploys.Editorial roles exist for content, but agent instructions are not first-class governable objects.No governance surface; behavior is managed in code and infrastructure, not by content owners.
Agent connection surfaceSanity Context MCP endpoint shaped to the product, so production agents query the same governed retrieval path.REST and SDK query APIs; connecting an agent means building the retrieval and grounding layer around them.Delivery APIs (GraphQL, REST) for content; agent grounding logic is assembled on top by your team.SQL and client libraries; the entire agent-facing retrieval interface is something you design and maintain.