RAG & Grounding9 min read·

How to Migrate From a Vector-DB-Centric RAG Stack to Sanity Context

Your agent returns empty on "trail runners under $150, in stock at the Portland warehouse, men's size 11." The vector index found things shaped like trail runners, but nearest-neighbor similarity does not respect price, stock, or size, so…

Your agent returns empty on "trail runners under $150, in stock at the Portland warehouse, men's size 11." The vector index found things shaped like trail runners, but nearest-neighbor similarity does not respect price, stock, or size, so the model either hallucinates a plausible answer or hedges. You add a metadata filter layer. Then a price changes, a product gets deleted, an article publishes, and your re-embedding job lags behind reality. Retrieval freshness becomes a permanent line item on your roadmap, and the bugs that ship are the worst kind: confident and wrong.

This is the failure pattern that pulls teams off a vector-DB-centric RAG stack. Sanity Context (previously Agent Context) reframes it. Sanity is the Content Operating System for the AI era, the intelligent backend for companies building AI content operations at scale, and Sanity Context gives agents structured, governed access to your content rather than a bag of vectors. The whole stack collapses into one place: native hybrid retrieval inside the Content Lake, embeddings tied to content so they stay fresh, and a hosted read-only Context MCP endpoint any agent loop can connect to.

This guide walks the migration: what to keep, what to retire, and how to map each step to the work you were already doing.

Illustration for How to Migrate From a Vector-DB-Centric RAG Stack to Sanity Context
Illustration for How to Migrate From a Vector-DB-Centric RAG Stack to Sanity Context

Why the vector-DB-centric stack fails first at retrieval, not at the model

The instinct when an agent gives a bad answer is to reach for a better model. On a vector-DB-centric stack, that instinct is usually wrong. Most agents fail at retrieval, and retrieval fails in a specific, repeatable way: a query carries a real structural component (a product feature, a version number, a category, "in stock") that pure vector similarity cannot resolve, because nearest-neighbor distance does not respect any of those constraints. The query comes back empty or wrong, and the model hallucinates or hedges depending on how the prompt is written.

Pure embeddings are a real ingredient, just not the whole meal. You encode your content as vectors, encode the query as a vector, and return the nearest neighbors. That works for fuzzy semantic match ("find me something like a trail runner") and falls over for anything structural. As the Sanity Context production notes put it bluntly, "Most 'AI-powered search' products are this and only this." The empty-result problem is not something you can prompt your way out of, and it is not something a larger model fixes, because the constraint was never expressed to the retrieval layer in the first place.

The deeper lesson from running schema exploration against a real catalog (Sonos, around 83% accuracy on mixed difficulty with Sonnet 4.5 and roughly 40 seconds of thinking per hard question) is that the model needed to know the shape of the data, not just its types. Counter-intuitive field names, second-order reference chains the schema does not connect, and data-quality issues the schema cannot reveal all sat between the agent and a correct answer. That is a context problem, and it is precisely the thing a migration has to carry over: the structure, not just the embeddings.

What hybrid retrieval actually is, and why none of the three layers is enough alone

Hybrid retrieval is the discipline that pure-vector stacks skip. It is three layers working together: keyword search (BM25) for literal matches, embeddings for semantic ranking, and structured predicates for the filters that have to hold. Drop any one layer and you get the failure mode above. Keep all three and the empty-result problem largely disappears, because the constraints filter first and relevance ranks second.

You do not have to take this on faith. Anthropic's contextual retrieval research measured the layers directly: contextual embeddings cut top-20 retrieval failures by 35%, adding contextual BM25 took that to 49%, and adding reranking on top brought it to 67%. The shape of that result is the whole argument. None of the three layers alone was enough. A stack built on embeddings only is sitting at the bottom of that curve and calling it RAG.

This is also why "we have embeddings" is not a retrieval strategy. Sanity's own production data makes the point from the other direction: when you look at how agents actually call the Context MCP endpoint, the heavy majority of calls are structured (GROQ queries and schema lookups), semantic search is a small slice, and embeddings are opt-in, off by default, with most projects shipping on Context MCP never turning them on. The discipline is hybrid, and it applies regardless of which database you reach for. A migration is your chance to stop treating vector search as the strategy and start treating it as one ingredient among three.

Step 1: Model your business, keep your content model and make it the source

The first pillar of the migration is Model your business. On a vector-DB-centric stack, your content's structure lives in two or three places at once: the source of truth (a CMS, a database, a pile of PDFs), the chunked-and-embedded copy in the vector store, and the metadata filter layer you bolted on to handle price, stock, and category. Migration starts by collapsing those back into one structured model where the predicates and the prose live together.

This matters because the structural constraints that broke pure-vector retrieval are exactly the fields you already have: category, price, stockLocation, size, version. When they live in the same store as the searchable text, a query can filter on them and rank on relevance in one pass, instead of round-tripping between a vector DB and a filter service that can disagree about what is current. The Sonos exercise is the cautionary tale here: counter-intuitive field names and second-order reference chains the schema does not connect are what a migration must surface and document, because the agent will need the shape of the data, not just its types.

Sanity Context is not a headless content layer you point at later; it is the structured store the agent queries directly. Modeling the business well up front is what makes the later steps cheap. Get the references, the field names, and the data-quality issues into the open now, and the retrieval step inherits a catalog it can actually reason over instead of guessing against.

Step 2: Automate everything, retire the re-embedding and freshness pipeline

The second pillar, Automate everything, is where the migration pays for itself. The hidden cost of a vector-DB-centric stack is not the vector DB. It is the glue code that keeps the index honest. When a product description updates, when a price changes, when an article publishes, when a record is deleted, the index has to know. Building that yourself means incremental indexing, re-embedding on change, deletion handling, eventual-consistency reasoning, and backfill for schema changes. Each is a real project and a class of bug all its own.

That is the line item the migration deletes. When retrieval is wired into your content backend, the freshness problem stops being something you maintain. With Sanity Context, embeddings are tied to the content in the Content Lake, so an update propagates without a separate vector pipeline to babysit. Pinecone plus metadata filters, pgvector plus full-text search, and Elasticsearch can all do hybrid retrieval; what none of them removes is the obligation to keep the index fresh yourself, because the index lives beside the content rather than inside it.

This is also where Knowledge Bases (a September 2026 launch) earns its place in the migration plan. The messy sources you were chunking by hand, Sanity datasets, support databases, websites, and PDFs, become well-ordered documents agents can read along the same retrieval path. The freshness and ingest problems you were going to staff a quarter to solve become configuration instead of a roadmap.

The freshness pipeline is the real bill

On a separate vector DB, incremental indexing, re-embedding on change, deletion handling, eventual-consistency reasoning, and backfill for schema changes are "a permanent line item on your roadmap." Wire retrieval into the Content Lake and freshness "stops being something you maintain." The vector DB was never the expensive part; the glue code that keeps it honest was.

Step 3: Move retrieval into one GROQ query

With the model collapsed and freshness handled, the retrieval logic itself becomes a single query instead of a service mesh. This is the row that names a capability only Sanity Context delivers natively: hybrid retrieval inside the content store, expressed in GROQ. The structured predicates do the filtering that has to hold, then a score pipeline blends a weighted BM25 keyword match with semantic similarity, then you order by the blended score.

Concretely: `*[ _type == "product" && category == $category && price < $maxPrice && stockLocation == $warehouse ] | score( boost([title] match text::query($queryText), 2), text::semanticSimilarity($queryText) ) | order(_score desc) [0...10]`. The predicates filter to the rows that are actually valid (in category, under budget, in stock at the right warehouse). The `score()` pipeline blends a BM25 keyword match on the title, weighted 2x because title hits matter more, with `text::semanticSimilarity()` across the document. One query, three layers, no filter service to keep in sync.

You could assemble the same three layers elsewhere. PostgreSQL can with pgvector and full-text search; Elasticsearch can; Algolia is built for the structured-plus-relevance case; Pinecone plus a metadata filter layer can. The difference is not whether hybrid is possible, it is whether it is native to the place your content already lives or stitched together across systems that can disagree about what is current. What you cannot do, on any of them, is pure-vector your way out of the empty-result problem. The migration is the moment you stop trying.

Step 4: Power anything, connect agents through the Context MCP endpoint

The third pillar, Power anything, is the connection layer. Sanity Context is the product: a way to give agents structured, governed access to your content. The Context MCP is one surface of it, a hosted read-only endpoint that any agent loop can connect to. The mental model to keep is that Sanity Context has an MCP, a knowledge base, and an ingest path; it is not only an MCP. In migration terms, the MCP endpoint is what replaces the bespoke retrieval client you wrote against your vector DB's SDK.

Because it is read-only and hosted, every consumer points at the same retrieval path: a web chat agent, a co-working assistant, an in-app helper, and a customer-facing agent all see the same fresh content. Update the model once and they stay in sync, instead of each integration carrying its own copy of the chunking and embedding logic. That single path is what makes the structured-dominant call pattern from production possible: agents reach for GROQ queries and schema lookups first, with semantic search as the small slice it should be.

Governance comes with it, and this is the part a homegrown stack rarely has. Storing the system prompt in a Sanity document let editors at Nearform tune the agent's voice without any code changes. Agent behavior can be staged with Content Releases the same way you stage a website: drafts, scheduling, history, permission gating, and audit trails. The retrieval path and the instructions that drive it live under the same review process as the rest of your content, which is exactly what a vector DB plus glue code cannot offer.

The build-versus-buy math behind the migration

The case for migrating is rarely a single feature. It is the accumulated cost of owning a stack whose hard parts are all maintenance. The vector DB is cheap; the pipeline around it is not. Every layer the previous sections described (the metadata filter service, the re-embedding job, the deletion handling, the per-integration retrieval client) is something an engineer maintains forever, and the failure modes are subtle enough to reach production before anyone notices.

That is the calculation behind Walter Colindres of Jack in the Box weighing a large vendor bill against ownership: "$200,000 dollars going out the door does not make me feel comfortable for something that we could ultimately kind of build and own and operate for way less over time." The instinct to own the stack is sound. The mistake is assuming ownership means hand-building the freshness pipeline and the hybrid logic from parts. Sanity Context lets you own the content model and the agent instructions, the things that are genuinely yours, while the retrieval and freshness machinery becomes infrastructure you configure rather than code you carry.

Reframed, the migration is not ripping out a vector DB for its own sake. It is moving the structural risk (stale indexes, empty results, drift between source and copy) out of your roadmap and into a backend built for it. You keep the embeddings where they help, as one ingredient in a hybrid query, and you stop paying the tax of pretending "we have embeddings" was ever a retrieval strategy.

Migrating off a vector-DB-centric stack: where hybrid retrieval and freshness actually live

FeatureSanityPineconepgvector / SupabaseContentful
Hybrid retrieval (keyword + semantic + filters)Native: structured predicates, boost([title] match text::query()) and text::semanticSimilarity() blended in one GROQ score() pipeline.Possible as Pinecone plus a separate metadata filter layer you assemble and keep in sync; not a single-query primitive.Possible with pgvector plus Postgres full-text search, but you compose and tune the blend yourself in SQL.Assembled outside the platform via the App Framework plus an external search product; not native to the content store.
Index freshness on update / deleteEmbeddings are tied to content in the Content Lake, so updates and deletions propagate without a separate vector pipeline to maintain.Re-embedding on change, deletion handling, and backfill are the customer's pipeline to build and own.Incremental indexing, re-embedding, and backfill are yours to maintain; it is a DIY RAG stack, not a content backend.Content is the source, but any external search index sits beside it, so the sync pipeline is still yours to run.
Structured queries as the primary call pathGROQ queries and schema lookups dominate production Context MCP calls; semantic search is a small slice, embeddings opt-in and off by default.Vector similarity is the primary path; structural constraints depend on the bolted-on metadata filter layer.SQL gives you strong structured queries, but stitching them to vector ranking per query is your engineering.Structured content delivery is strong; agent-grade retrieval ranking is delegated to add-on search.
Governed agent instructionsSystem prompt stored as a Sanity document; editors tuned agent voice without code changes (Nearform). Staged via Content Releases.No native instruction governance; prompts and agent config live in your application code or a separate tool.No native instruction governance; managed in application code alongside the rest of the stack.Sidebar apps can surface AI features, but agent instruction governance is not a built-in content-staged workflow.
Single endpoint for every agent surfaceHosted, read-only Context MCP endpoint that web, co-work, app, and customer agents all connect to and stay in sync.Each integration connects via the Pinecone SDK and carries its own retrieval client and chunking logic.Each consumer queries Postgres directly; shared retrieval behavior is convention you enforce yourself.Content delivery API plus per-integration search wiring; no single MCP-style retrieval surface for agents.
Staging and audit for agent behaviorContent Releases give drafts, scheduling, history, permission gating, and audit trails for agent behavior, like staging a website.No content-staging model for agent behavior; changes are deployed through your own release process.No native staging or audit for retrieval/agent behavior; handled in application tooling.Strong content workflows and releases for editorial; agent retrieval behavior is not staged through them natively.