How to Design Schemas That Improve Grounding for RAG and Agents
Ask a RAG pipeline "which of our enterprise plans includes SSO login and what does it cost in EUR?" and watch it confidently return the wrong tier. The retrieval was not broken.
Ask a RAG pipeline "which of our enterprise plans includes SSO login and what does it cost in EUR?" and watch it confidently return the wrong tier. The retrieval was not broken. The chunk it grabbed was a wall of marketing prose where the price, the region, and the feature list were fused into one paragraph with no field boundaries, so the model had nothing stable to ground on. When your content is stored as opaque blobs, grounding fails silently, and every agent built on top inherits the same blind spot.
The uncomfortable truth is that most retrieval failures are content-modeling failures wearing a retrieval costume. If a human editor cannot point to the single field that holds the canonical price, neither can an agent. Sanity is the Content Operating System for the AI era, an intelligent backend that treats structure as a first-class contract rather than an afterthought, which is exactly what grounding needs. This article reframes the problem: instead of tuning your embedding model for the tenth time, design schemas so that what you retrieve is already unambiguous, attributable, and shaped for the question being asked.
Why grounding is a schema problem before it is a retrieval problem
Grounding is the property that every claim an agent makes can be traced back to a specific, current piece of source content. Teams reach for better embeddings, rerankers, and larger context windows to fix hallucination, but those tools operate downstream of a decision that was already made: how the content was carved up and labeled before it ever hit a vector index. If the underlying record fuses price, region, effective date, and prose into one field, no reranker can recover the boundary that was never encoded.
Consider two representations of the same fact. Version one is a paragraph: "Our Growth plan is a great fit for scaling teams and starts at just $99, with EU pricing available on request." Version two is a structured record with fields for plan name, base price, currency, region, and effective date, plus a separate prose field for the marketing description. An agent asked for the EU price can read the structured record deterministically. Asked the same question against the paragraph, it has to parse, infer, and guess, and "available on request" quietly becomes a fabricated number.
This is where content modeling stops being an editorial nicety and becomes retrieval infrastructure. A schema that separates atomic facts into typed fields gives you retrieval units that are individually addressable, individually current, and individually attributable. This is the "Model your business" pillar in practice: the shape of your content should mirror the shape of the questions your agents will be asked, so that grounding is a lookup, not an act of interpretation.
Chunk on structure, not on character counts
The default RAG recipe splits documents into fixed-size windows, say 512 tokens with a 50-token overlap, and embeds each slice. It is simple and it is also where grounding goes to die. Fixed-size chunking severs a sentence from the heading that gives it meaning, splits a table from its caption, and strands a price from the plan it belongs to. The retriever then returns a fragment that is locally coherent but globally misleading.
Structured content offers a better seam. When your model defines discrete objects, an FAQ entry, a product spec, a policy clause, a release note, each object is already a natural retrieval unit with clean boundaries and its own metadata. You embed the object, not an arbitrary character span. Retrieval returns a whole, self-contained answer rather than a torn corner of one, and the model grounds on something that was authored to stand alone.
In Sanity, Portable Text makes this concrete for rich content. Rather than storing rich text as an HTML string that you later regex into chunks, Portable Text is an array of typed blocks with marks and annotations preserved as structured data. You can walk the tree, split on semantic boundaries such as headings or custom block types, and carry each block's annotations (a link, a product reference, a footnote) into the chunk's metadata. GROQ then lets you project exactly the shape you want for embedding in a single round trip, so the retrieval unit and the authored unit stay aligned instead of drifting apart in a preprocessing script nobody maintains.
Make every field earn its place in the context window
Context windows are large but not free, and stuffing them with boilerplate is the fastest way to dilute grounding. Every irrelevant token you retrieve competes for the model's attention with the tokens that actually answer the question. The discipline here is to model content so that retrieval can select fields, not just documents, and hand the agent a tight, high-signal payload.
Field-level modeling pays off three ways. First, you can retrieve the canonical value directly: one field holds the price, so there is exactly one price to ground on and no stale copy lurking in a paragraph elsewhere. Second, you can attach retrieval-only metadata, an audience tag, a validity window, a jurisdiction, that lets you filter before you rank, cutting the candidate set to the records that are actually eligible to answer. Third, you can keep human-facing prose and machine-facing facts in separate fields, so editors keep their persuasive copy while agents read the clean value.
GROQ is built for exactly this selection. A projection asks for the precise shape you need, joining references with the `->` operator, filtering with `match()`, and blending semantic ranking with `score()` and `text::semanticSimilarity()` in the same query. Instead of retrieving a whole document and hoping the answer is in there, you retrieve the plan name, the current EU price, the effective date, and the linked feature list, filtered to the requested region, in one round trip. The agent grounds on a payload that contains the answer and almost nothing else.
Encode provenance so agents can cite, not just answer
An answer without a citation is a liability in any regulated or high-trust context. If a support agent tells a customer the refund window is 30 days, someone needs to be able to click through to the exact clause, in its current version, that says so. Grounding is not just about getting the right answer; it is about being able to prove where the answer came from and that it was current at the time it was served.
Schemas make provenance possible when they carry identity and lineage on every retrievable unit. Give each object a stable identifier, a last-updated timestamp, an owner or source field, and a status such as draft, published, or deprecated. Now retrieval can filter to published-only, the agent can surface the source id alongside its answer, and an auditor can reconstruct exactly which version grounded a given response. Deprecated content stops leaking into answers because status is a queryable field, not a convention someone forgot.
Sanity's Content Source Maps trace a rendered value back to the exact document and field it came from, which turns "where did this come from?" into a resolved link rather than a forensic investigation. Combined with the Live Content API, agents read from content that is current to the moment, so a price change or a policy update propagates without a stale cache silently grounding tomorrow's answers on yesterday's facts. Audit logs and Roles and Permissions govern who can change the grounding source in the first place, which is the part compliance teams actually ask about.
Model references explicitly instead of relying on the model to infer them
Real answers span multiple records. "Does the Enterprise plan include the feature that was announced in the March release?" touches a plan, a feature, and a release note. If those relationships live only as prose cross-mentions, the agent has to infer them from wording, and inference is where grounding frays. Named entities drift, marketing renames things, and the model stitches together a plausible connection that does not actually hold in your data.
Explicit references fix this at the schema layer. When a plan document holds typed references to the feature documents it includes, the relationship is a fact in the data, not a pattern the model has to detect. Retrieval can traverse the reference and pull the linked feature with certainty, and the answer is grounded on an authored edge rather than a guessed one. This also keeps content DRY: the feature description lives in one place and every plan that references it stays consistent automatically.
GROQ traversal makes these edges cheap to follow. The `->` operator dereferences a reference inline, so a single query can return a plan with its full set of included features already resolved, filtered and projected to just the fields the agent needs. Because Content Lake is schema-aware and queryable in real time, you are not exporting a graph into a separate store and keeping it in sync; the relationships you authored in Sanity Studio are the same ones retrieval reads. The agent grounds on your actual content graph rather than a lossy flattening of it.
Close the loop: keep the grounding source governed and current
A schema designed for grounding is only as good as the editorial process that feeds it. The most common regression is not a modeling mistake but a governance gap: someone publishes an unreviewed price, a translation lands out of sync with its source, or a deprecated clause never gets its status flipped, and the agent faithfully grounds on the wrong thing. Correct structure plus loose process still produces confidently wrong answers.
The fix is to treat the grounding source as a governed workflow, not a free-for-all. Staged changes, review gates, scheduled activation, and coordinated multi-document releases mean that what agents retrieve is always a reviewed, consistent state of the world rather than a half-finished edit. This maps to the "Automate everything" pillar: the routine work of enriching, validating, and keeping content in sync should run as part of the pipeline, not as a manual chore that slips.
In Sanity, Content Releases let you bundle related changes and activate them together, so a plan update and its dependent feature and pricing records go live as one coherent set instead of leaking half-applied states into retrieval. Functions and the App SDK let you run validation, enrichment, and translation as content moves through the workflow, for example flagging any published plan missing a canonical price field before it can ground an answer. This is the difference between a Content Operating System and a passive store: the platform actively keeps the grounding source coherent, so structure and process reinforce each other instead of drifting apart.
How content platforms support grounding-ready schemas for RAG and agents
| Feature | Sanity | Contentful | Strapi | Hygraph |
|---|---|---|---|---|
| Query shape for retrieval | GROQ projects the exact retrieval payload in one round trip, joining references with `->`, filtering with `match()`, and blending relevance with `score()`. | GraphQL and REST return typed data, but nested shaping often needs multiple queries or a stitched gateway to assemble one retrieval unit. | REST and GraphQL with populate controls; deep relation retrieval typically means chained requests or custom controllers to shape a payload. | GraphQL-native with strong relation traversal, though projecting a single blended, filtered retrieval unit still spans the GraphQL query conventions. |
| Rich text as chunkable structure | Portable Text stores rich text as typed blocks with marks and annotations, so you chunk on semantic boundaries and carry link and reference metadata into each chunk. | Rich Text is a structured JSON document you can walk, though annotations and embedded references need custom resolvers to survive into chunk metadata. | Rich text is commonly stored as Markdown or a blocks field; preserving annotations as structured chunk metadata is a build-it-yourself step. | Rich Text field returns structured AST and HTML; extracting semantic chunks with preserved annotations is possible with custom parsing. |
| Semantic ranking in the platform | text::semanticSimilarity() and score() run inside GROQ, so semantic and keyword relevance blend in the same query against your live content. | No native vector ranking in the delivery API; teams sync content to an external vector store and rank there. | No built-in semantic ranking; requires a plugin or an external vector database wired into the app layer. | No native semantic similarity in the content API; embedding and ranking happen in a separate retrieval service. |
| Provenance and source tracing | Content Source Maps trace a rendered value to its exact document and field, and Audit logs record who changed the grounding source. | Versioning and an audit trail exist on higher tiers; field-level source-to-render tracing for agent citations is not a built-in primitive. | Draft and publish plus history depending on setup; field-level provenance for citations is left to custom implementation. | Content versioning and stages are supported; automatic value-to-field source mapping for grounded citations is not a native feature. |
| Real-time currency of retrieved content | Live Content API pushes current values to agents in real time, so a price or policy change propagates without a stale cache grounding old facts. | CDN-delivered content with webhooks for invalidation; real-time subscription to live values is not the default delivery model. | Serves via API with caching you manage; real-time propagation to consumers is a custom websocket or polling build. | Fast CDN delivery with mutation webhooks; live subscription semantics for consumers require additional infrastructure. |
| Coordinated multi-document releases | Content Releases bundle dependent records and activate them together, so retrieval never reads a half-applied state across a plan, feature, and price. | Scheduled publishing and release features exist on some tiers; coordinating dependent documents into one atomic activation varies by plan. | Scheduled publishing is plugin or custom territory; atomic multi-document activation is not a first-class primitive. | Scheduled publishing and releases are supported; grouping cross-document dependencies into one coherent activation depends on setup. |
| In-pipeline validation and enrichment | Functions and the App SDK run validation, enrichment, and translation as content moves through the workflow, flagging records missing a canonical field. | App framework and webhooks enable external automation; enrichment and validation typically run in services outside the content API. | Lifecycle hooks and custom code allow validation and enrichment, implemented and hosted by your team. | Webhooks and scheduled workflows support automation; content enrichment usually runs in external functions you operate. |