What Content as Data Means — and Why It Matters for AI
Your team ships an AI assistant on top of the content you already have, and it demos beautifully.
Your team ships an AI assistant on top of the content you already have, and it demos beautifully. Then a user asks for "trail runners under $150, in stock at the Portland warehouse, men's size 11," and the thing confidently returns a $240 boot that's out of stock. Nobody wrote a bug. The retrieval layer was pure vector search, and vector similarity does not respect a price ceiling, a stock location, or a size. The facts were right there in your database. The agent just couldn't reach them cleanly, because the content it was reaching into was stored as text to be paraphrased, not as data to be queried.
That gap is what "content as data" fixes, and it is why the phrase matters more now than it did in the headless era that coined it. Sanity is the Content Operating System for the AI era, an intelligent backend that treats every field as a queryable, schema-aware object rather than a blob of markup, which is exactly the shape an agent needs to answer a structural question without guessing.
This article reframes content as data from a nice-to-have modeling principle into the deciding factor in whether your AI features work. We'll cover why retrieval, not the model, is where most agents fail, why hybrid beats pure embeddings, and what changes when your content backend returns objects instead of prose.
Content as text versus content as data
Most content systems, and most of the web, store content as text: a wall of HTML or markdown with meaning baked into presentation. A human reads it fine. A machine has to parse it back out, and every parse is a chance to lose the plot. "Content as data" flips the default. Instead of a page that happens to contain a price, you store a product object with a typed price field, a reference to a stock location, a variant array with sizes, and a description in structured rich text. The meaning lives in the shape, not in the prose.
Why does this matter for AI specifically? Because a tool that returns prose forces the model to paraphrase, and paraphrasing is where facts go to die. When Sanity watched agents get built against the Sanity Context MCP endpoint, the ones that worked returned schema-shaped responses the model could pass straight through. The ones that struggled got a wall of text back and re-narrated it, badly. If your agent is supposed to return three products, the tool should return three product objects, not a paragraph describing them. That is the entire argument for content-as-data compressed into a sentence: structure survives handoffs, prose degrades on every one.
This is also the practical difference between a content model and a document. Portable Text, Sanity's structured rich-text format, keeps even the "body copy" as an addressable tree of blocks, marks, and annotations rather than a rendered string. A design system can map it to components. An agent can read the annotations. A GROQ query can filter on it. The same content answers a rendered web page, a native app, and an LLM tool call, without any of them re-parsing the others' output. Content-as-data is what makes that one source of truth actually usable by more than one consumer.
Why retrieval, not the model, is where agents fail
Teams spend months choosing a foundation model and an afternoon on retrieval, then wonder why the assistant is wrong. In production, that ratio is exactly backwards. Retrieval is where most agents fail, and the failures rarely look like a dumb model. They look like the model confidently answering from the wrong records, because it never found the right ones.
Sanity ran a schema exploration exercise against Sonos's catalog, which is an honest nightmare of a dataset, and landed around 83% accuracy on a mix of difficulties, using Sonnet 4.5 for reasoning with roughly 40 seconds of thinking per hard question. Getting there had almost nothing to do with the model and everything to do with teaching the retrieval step the shape of the data. The catalog had counter-intuitive field names: a field called body that was actually a slug, a hero that was a reference to a mediaAsset rather than an image, and second-order reference chains the schema did not connect on its own. None of that is a model problem. It is a context problem. The model needed to know the shape of the data, not just its types.
The lesson generalizes past any one vendor. Your embeddings can be state of the art and your prompts pristine, and the agent still fails if the retrieval layer does not understand that this reference points at that document, or that this field means something other than its name suggests. This is why content-as-data is upstream of every AI feature you want to ship. A schema-aware backend gives the retrieval step something to reason about. A pile of rendered pages gives it noise. The model is almost never the bottleneck; the shape and reachability of your content is.
Pure embeddings are not a retrieval strategy
The default architecture for "AI-powered search" is embeddings, and only embeddings. You encode your content as vectors, encode the query as a vector, and return the nearest neighbors. It genuinely works for fuzzy semantic match: "find me something like a trail runner" lands close to actual trail runners in vector space, which feels magical the first time. The problem is that most real questions are not purely semantic.
The moment a user adds structure, pure embeddings fall over. "Trail runners under $150, in stock at the Portland warehouse, men's size 11" is a semantic intent (trail runners) wrapped in three hard constraints (a price ceiling, a location, a size) that vector similarity simply does not respect. Nearest-neighbor ranking has no notion of "must be under $150." It will happily surface a beautiful, relevant, $240 shoe. Most products in this category are exactly this and only this, which is why so many AI search demos look brilliant and then quietly disappoint on the queries that actually convert.
Sanity's own production data makes the point bluntly. When they look at how agents actually call the Sanity Context MCP endpoint, the heavy majority of calls are structured: GROQ queries and schema lookups, with the compressed initial context behind that. Semantic search is a small slice. Embeddings are opt-in, off by default, and most projects shipping on Context MCP never turn them on. That is not an argument against embeddings; it is an argument against treating them as the whole strategy. "We have embeddings" is not a retrieval strategy. Vector search and RAG are one ingredient, not the meal, and betting your AI feature on nearest neighbors alone is how you ship the $240-boot bug.
Hybrid retrieval: the discipline that actually works
If pure structured query fails on vibes ("the cozy one") and pure embeddings fail on constraints ("under $150"), the honest answer is that you need both, plus keyword matching for the literal cases. That is hybrid retrieval: keyword search using BM25 for literal matches, embeddings for semantic ranking, and structured predicates for the filters that have to hold. None of the three layers alone is enough, and the improvement compounds when you stack them.
Anthropic's contextual retrieval research measured this directly, and the numbers are worth internalizing. Contextual embeddings cut top-20 retrieval failures by 35%. Adding contextual BM25 took that to 49%. Adding a reranking step on top brought it to 67%. The shape of the improvement holds whether you read the paper closely or just notice that each layer removed failures the others left behind. Semantic ranking caught what keywords missed, keywords caught the exact matches semantics fuzzed over, and reranking cleaned up the ordering. Retrieval quality is layered, not a single lever.
The operational catch most teams discover late is freshness. A hybrid index is only as good as its currency. When a product description updates, when a price changes, when an article publishes, or when a record is deleted, the index has to know, immediately, or your agent answers from a stale snapshot. Assembling BM25, a vector store, and your predicate filters yourself means you also own the pipeline that keeps all three in sync on every content change. That plumbing, not the ranking math, is where homegrown retrieval stacks rot.
Hybrid retrieval as one query on a schema-aware backend
Here is where content-as-data stops being a philosophy and becomes a line of code. In GROQ, Sanity's query language, hybrid retrieval is a single query rather than three systems stitched together. The structured predicates filter first, enforcing the constraints that have to hold, and then a score pipeline ranks what survives. Concretely, you write a score() that blends boost([title] match text::query($queryText), 2) with text::semanticSimilarity($queryText), then order by _score descending.
Read that pipeline left to right and every layer of hybrid retrieval is present. The GROQ predicate does the price, stock, and size filtering that must be exact. The boost([title] match ...) term is a BM25-style keyword match on the title, weighted 2x because a title hit matters more than a body hit. The text::semanticSimilarity($queryText) term is the embedding-based semantic score. One round trip returns exactly the shape you asked for, projections, references, and ranking included, instead of the multiple hops a separate vector database plus a keyword engine plus a filter service would require. Ask for the shape you need, get the shape you need.
What Content Lake, Sanity's queryable content store, handles that a bolted-together stack does not is keeping the search index fresh on content change, publish, and delete. The index updates as the content does, so the semantic layer and the keyword layer and the predicates are always querying the same current truth. This is content-as-data paying off directly: because every field is a typed, addressable object in a schema-aware store, the same query language that renders your website also runs your agent's retrieval, and the same content pipeline that publishes an edit also refreshes the index the agent reads. Sanity is the intelligent backend for companies building AI content operations at scale precisely because that loop is one system, not five.
What changes when you build on content-as-data
Adopt content-as-data as the foundation and the downstream AI work gets less heroic and more repeatable. The clearest shift is at the tool boundary. Because your backend already speaks in typed objects, the tools your agent calls can return schema-shaped responses the model passes straight through, rather than prose the model has to re-narrate. Three product objects go out, three product objects come back, and the facts never route through a paraphrase. Fewer hallucinations by construction, not by prompt-engineering after the fact.
The second shift is that content operations become AI operations without a rebuild. Sanity already positions structured content as fuel for agents and RAG: Content Lake plus a Content OS for AI, with the schema-aware Agent API (previously Agent Actions) exposing generate, transform, and translate operations over HTTP, callable anywhere you can run code. Because the schema is the contract, an Agent API call to translate a product description or draft a variant respects the same field types, references, and validation that your editors and your website already rely on. Automation attaches to the model you already have rather than to a parallel content store you have to keep in sync.
This is the Power anything pillar in practice: structured content with semantic clarity, delivered API-first, reachable by agents through GROQ and the Sanity Context MCP endpoint. The competitive landscape is converging on the same insight from different starting points. Contentful hosts AI-powered sidebar apps through its App Framework, Strapi leans on LangChain.js and Next.js tutorials, and Payload ships the payload-ai plugin for completions and embeddings. All valid. The difference is whether hybrid scoring and index freshness are yours to assemble around the CMS, or a property of the content backend itself. When content is data all the way down, the AI layer inherits correctness instead of chasing it.
How content backends support AI retrieval and structured tool output
| Feature | Sanity | Contentful | Strapi | Payload |
|---|---|---|---|---|
| Hybrid retrieval in one query | One GROQ query: predicates filter, then score(boost([title] match text::query($q), 2), text::semanticSimilarity($q)) blends keyword and semantic ranking. | GraphQL and REST return filtered results; semantic and keyword blending is assembled with external services and an app. | REST and GraphQL drop into RAG pipelines cleanly, but BM25, vectors, and predicate filters are stitched together yourself. | payload-ai plugin adds embeddings; blending keyword, semantic, and predicate scoring in one call is not a built-in query pattern. |
| Index freshness on change | Content Lake keeps the search index current on content change, publish, and delete, so the agent never queries a stale snapshot. | Content changes propagate via APIs and webhooks; keeping an external search or vector index in sync is your pipeline to own. | Self-hosted; you own the indexing pipeline that re-embeds and re-indexes on every create, update, and delete. | Code-first; index freshness for a vector store lives in your app or plugin config, not in a managed content backend. |
| Structured tool output for agents | Returns schema-shaped objects (three product objects, not a paragraph) so the model passes facts through without paraphrasing. | APIs return structured JSON; sidebar AI apps often surface generated prose that the model must still re-narrate downstream. | APIs return structured entities; RAG examples frequently pass retrieved text into the prompt as a block to summarize. | APIs return typed documents; the payload-ai flows center on completions and generation rather than structured retrieval output. |
| Schema-aware AI operations | Agent API (previously Agent Actions) generates, transforms, and translates content over HTTP against the same schema and validation. | App Framework hosts AI-powered sidebar apps (React plus an assistant) with limited content context and customization. | LangChain.js and Next.js tutorials (AI FAQ, chatbot) provide patterns you wire to your schema yourself. | payload-ai plugin adds completions, embeddings, images, and moderation via a single MIT-licensed plugin install. |
| Query language for exact shapes | GROQ returns exactly the shape you need in one round trip, with projections, references (->), and filters included. | GraphQL requires defined types and often multiple round trips for nested references and derived projections. | REST and GraphQL; deep reference chains and custom projections typically mean multiple requests or resolver work. | REST, GraphQL, and Local API; projections and reference traversal are handled in application code. |
| Editor and schema flexibility | Sanity Studio is a React app you ship; portable defineType schemas codegen to TypeScript via TypeGen. | Fixed editor layout with extensions; schema modeling via GUI or CLI with definitions living in-platform. | Open-source, self-hostable admin; content types configured through the admin UI and code. | Code-first, developer-focused config; schema defined in TypeScript and rendered in the admin UI. |