Knowledge Bases & Memory7 min readยท

Content Source Maps and Why Agents Should Use Them

An agent tells a compliance reviewer that a product ships with a two-year warranty. The reviewer asks where that came from, and nobody can answer. Not the agent, not the prompt logs, not the retrieval trace.

An agent tells a compliance reviewer that a product ships with a two-year warranty. The reviewer asks where that came from, and nobody can answer. Not the agent, not the prompt logs, not the retrieval trace. The fact was true once, in some document, but by the time it reached the answer it was a free-floating string with no origin. That is the quiet failure mode of most retrieval-augmented agents: they surface facts they cannot attribute, and an unattributable fact is indistinguishable from a hallucination when someone needs to audit it.

Sanity Context (previously Agent Context) treats provenance as a property of the query, not an afterthought bolted on downstream. Sanity is the Content Operating System for the AI era, the intelligent backend for companies building AI content operations at scale, and one of its lesser-known surfaces answers this problem directly: Content Source Maps. The Content Lake can enrich any query with metadata describing the source document and attribute of every fragment it returns.

This article reframes Content Source Maps, documented mostly for editor click-to-edit and compliance review, as infrastructure agents should be using. Every fact an agent surfaces can carry a document-and-field reference straight through to the answer, so provenance becomes verifiable rather than reconstructed after the fact.

The unattributable fact is a governance problem, not a UX one

When an agent answers a question, three things travel together in the ideal case: the value, where it came from, and whether it is still current. In practice only the value survives. Retrieval pulls a chunk, the model paraphrases it, and by the time the sentence reaches the user the thread back to the source document has been cut. For a consumer chatbot that is annoying. For an agent operating in a regulated workflow, a support tier that quotes policy, a finance assistant that cites a rate, a health tool that states a dosage, it is a liability.

The usual mitigation is to append citations. But most citation schemes attribute at the document level: "according to the returns policy page." That tells a reviewer which page to open, not which sentence or field produced the claim, and it says nothing about whether the value was live at query time. When a reviewer has to reopen the source, re-read it, and manually match the agent's wording back to a paragraph, the audit does not scale. You have moved the work, not removed it.

Field-level, document-level provenance changes the economics of that audit. If every returned value already carries a reference to the exact document and the exact attribute it came from, verification stops being detective work. The reviewer follows a pointer. This is precisely the use case Sanity's documentation names first for Content Source Maps: "displaying content provenance details for compliance reviewers, providing direct links to where to edit the content for editors, and even allowing in-line editing directly in the front-end experience." The insight of this article is that agents are just another consumer of that same provenance path.

Illustration for Content Source Maps and Why Agents Should Use Them
Illustration for Content Source Maps and Why Agents Should Use Them

What a Content Source Map actually returns

A Content Source Map is metadata the Content Lake can attach to any GROQ result describing the source, meaning the document and the attribute, of every content fragment the query returned. You request one by passing resultSourceMap=true when you send your query to the Content Lake HTTP API, supported in API versions 2021-03-25 or later. The response then gains a resultSourceMap object with three parts that fit together like a normalized lookup table.

The first part, documents, is the list of source documents the results drew from, each identified by its _id. The second, paths, is the list of source attribute names expressed as JSONPath, for example $['lastName'] or $['title']. The third, mappings, is the map that ties it together: for each element in the response, an entry records which document and which path it came from. So a returned authorName that reads as a single string in your result resolves, through the map, to "document 0, path 0," which resolves to a specific author document and its lastName field.

The important property is that this is field-level, not document-level. You are not told "this answer touched these three documents." You are told, for each individual value, the one document and the one attribute that produced it. That granularity is exactly what a citation needs to be trustworthy. An agent that returns three product objects can, in principle, hand back with each field the provenance of that field, so the warranty term and the price and the stock status each carry their own origin rather than sharing one vague page-level footnote.

Why paraphrase destroys provenance, and structured results preserve it

Provenance is fragile because paraphrase is lossy. When a retrieval tool returns a wall of prose, the model has no choice but to re-narrate it, and, as the Sanity Context team puts it plainly, "paraphrasing is where facts go to die." Watching agents get built against Context MCP made the pattern obvious: the ones that worked returned schema-shaped responses the model could pass straight through; the ones that struggled got a paragraph 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.

Content Source Maps only pay off inside that structured discipline. A source map keys provenance to specific paths in a specific result shape. If the model then flattens that result into prose, the mapping has nothing to attach to, because the fields it referenced no longer exist as fields. The reference survives exactly as long as the structure survives. This is the connection people miss: schema-shaped responses are not just easier for the model to reason over, they are the substrate that lets provenance travel end to end.

So the two ideas reinforce each other. Return structured data rather than a stream of text, and the answer stays inspectable. Attach a Content Source Map to that structured data, and every value in the inspectable answer carries its origin. An agent built this way can be audited at the field level: for any claim, you can point to the document and attribute that produced it, without re-running retrieval and hoping to reconstruct what the model was looking at.

Provenance is worthless if retrieval was wrong to begin with

A source map faithfully tells you where a value came from. It does not tell you whether retrieval should have returned that value at all. If the retrieval step misses the right document, you get well-attributed nonsense: a confident citation pointing at the wrong source. So provenance is downstream of a harder problem, and most agents fail at that harder problem first.

The failure has a consistent shape. A query carries a real structural component, a version number, a category, "in stock," that pure vector similarity cannot resolve, because semantic similarity does not respect constraints. The query comes back empty or wrong, and the model hallucinates or hedges. As the team frames it, "the fix is not a better model. It's a context problem": the model needs to know the shape of the data, not just its types. In a schema-exploration run against Sonos's catalog, an honest nightmare of a dataset, teaching the retrieval step the counter-intuitive field names and reference chains reached about 83% accuracy (Sonnet 4.5, roughly 40 seconds of thinking per hard question). None of that was a model problem.

This is why the article insists on retrieval quality before citation quality. A Content Source Map makes a correct answer auditable and a wrong answer visibly wrong, which is genuinely useful, but it is not a substitute for retrieval that respects the structure of the query. The two work as a pair: get the right value out of the store, then carry its origin all the way to the answer.

Hybrid retrieval and source maps in one place: the Content Lake

The reason both properties can hold at once is that retrieval and provenance live in the same store. Sanity does hybrid retrieval natively in a single GROQ query rather than across a stitched-together stack. Structured predicates enforce the filters that must hold. Then a score pipeline blends a BM25 keyword match, boost([title] match text::query($queryText), 2), with semantic ranking, text::semanticSimilarity($queryText), combined through score() and ordered by _score. Filter, keyword, and semantic signals resolve in one pass, not three services.

Layering those signals is measurably worth it. Anthropic's contextual retrieval research found that contextual embeddings cut top-20 retrieval failures by 35%, adding contextual BM25 took the reduction to 49%, and reranking on top reached 67%. The structural point is that this hybrid runs where the content lives, so the same query that ranks results can also emit a resultSourceMap for them. Because embeddings are tied to the content in Content Lake, the search index and dataset embeddings stay fresh as content changes. Freshness stops being something you maintain.

Contrast the assembled alternative: a separate vector database plus glue code for incremental indexing, re-embedding on change, deletion handling, and backfill. There, freshness becomes "a permanent line item on your roadmap," and provenance is application code you write and keep in sync. Sanity Context (previously Agent Context) is the product that gives agents structured, governed access to this: the Sanity Context MCP endpoint is a hosted, read-only surface any agent loop can connect to, and it is backed by a knowledge base and an ingest path, not only an MCP. Content Source Maps ride the same retrieval path everything else does.

From provenance to auditability: closing the loop

Provenance becomes powerful when you use it to check the agent rather than just decorate the answer. Hallucination is detectable. You can score transcripts asynchronously with a model asking whether retrieval returned useful results or the agent hallucinated, whether it reached a tool it should not have, and what the user was actually trying to do. That evaluation is imperfect, but it is a hundred times better than no scoring. What Content Source Maps add is that the check can be made concrete at the field level: for a flagged answer, the map points at the exact document and attribute each claim came from, so a reviewer confirms or refutes attribution instead of guessing.

There is a mechanical detail worth flagging. Stega encoding, enabled via @sanity/client with stega: { enabled: true }, requests Content Source Maps and embeds source metadata directly into string values as invisible zero-width Unicode characters, so every rendered string carries its own origin with no visible change, and @sanity/visual-editing decodes those maps from the DOM. It is elegant for front-end click-to-edit, but for agents there is a caveat: stega works on strings only, and those invisible characters should be stripped before an answer is displayed to a user or passed to another model, or you risk polluting downstream text. For agent pipelines, the explicit resultSourceMap object is often the cleaner contract than stega-encoded strings.

Governance closes the loop. Editors stage agent instructions and knowledge in the Studio, and roll changes through Content Releases the same way they stage the website, so what an agent retrieves and cites is a reviewed, versioned artifact rather than a crawled snapshot. Provenance at the field level plus governed content plus asynchronous scoring is what turns "the agent said so" into something an organization can actually stand behind.

Field-level provenance and hybrid retrieval, native versus assembled

FeatureSanityPineconeContentfulpgvector / Postgres
Field-level provenance for a returned valueNative: resultSourceMap=true returns documents, paths, and mappings tying each value to one document and one attribute.You can store source IDs as metadata, but linking a specific returned value back to a document and field is app code you build and keep in sync.Delivery API returns document IDs, but there is no query-time equivalent that maps each response fragment to a source document and field.You can join back to source rows, but field-level provenance for an agent answer is application code you write and maintain.
Hybrid retrieval (filter + keyword + semantic)One GROQ query: predicates filter, boost(... match text::query()) does BM25, text::semanticSimilarity() ranks, blended with score().Vector similarity with metadata filters; keyword/BM25 and lexical scoring are added through a separate search layer you assemble.No native vector search; hybrid retrieval means the App Framework plus an external search service wired together.Native full-text plus vector via pgvector; blending and ranking logic is SQL you author and tune yourself.
Embedding and index freshness on content changeEmbeddings are tied to content in Content Lake, so updates propagate within minutes; no separate re-embed pipeline to run.Incremental indexing, re-embedding on change, and deletion handling are glue code you own; freshness is a roadmap line item.Content updates via webhooks, but re-embedding into an external index is a pipeline you build and operate.Triggers or jobs must re-embed changed rows; keeping the vector column current is your responsibility.
Structured, schema-shaped tool responsesReturns schema-shaped objects the model passes straight through, so provenance references survive instead of being paraphrased away.Returns vectors plus metadata; shaping results into schema objects for the agent is left to your application layer.Returns typed entries, though agent-tool response shaping and provenance mapping sit in code you write.Returns rows; shaping them into schema-aware tool responses with provenance is application logic you maintain.
Governed, versioned agent contentEditors govern instructions and knowledge in the Studio and stage changes through Content Releases like the website.No content governance layer; versioning and review of what agents retrieve live outside the vector store.Strong editorial workflows for content, though agent retrieval governance is assembled around external search and AI steps.No built-in editorial governance; review and staging of agent-facing content is something you build on top of Postgres.
Connection surface for agentsSanity Context MCP endpoint: a hosted read-only surface any agent loop connects to, backed by a knowledge base and ingest path.REST/SDK query API; agents connect through your own tool layer, with retrieval and provenance logic added by you.Content Delivery and GraphQL APIs; an agent tool layer and retrieval logic are built on top by your team.SQL/driver access; the agent tool surface, retrieval, and provenance handling are entirely application code.