Context-First Agent Design for Content Operations at Scale
sanity · Tech · 2026 · source Agentic: yes · promotional bias: med · source-backed · extracted with prompt 0.5.6 (schema v2)
Generated from extraction.json — do not edit by hand. Every claim cites verbatim source evidence; stated means the quote directly asserts the claim, implied means it supports it indirectly.
Problem
Domain: Content operations over structured CMS data
Sanity needed a Content Agent that could audit, generate, edit, update, export, and mutate large structured content collections without drowning the model in schemas, tool choices, or raw document payloads. Early tool proliferation made the agent less consistent and worse at choosing what to do.
Constraints:
- Sanity customers can have hundreds of content types and tens or hundreds of thousands of documents.
- Real schemas can include many document types, nested objects, arrays, references, validations, and reusable object types.
- Large query results cannot all be pushed into the main context window.
- Mutation is risky because Sanity documents are nested and machine-shaped for live collaboration.
- The user must be able to verify the set and action before expensive or risky work runs.
Architecture
Sanity shifted from adding more tools to shaping context: show compressed schema shape first, represent large query results as reusable sets with metadata, use code to validate and repair model-drafted GROQ queries, keep one strong main agent with a few broad tools, and use specialized subagents only for clearly bounded mutation tasks.
Diagram confidence: explicit (topology described by the source).
flowchart LR main-content-agent["Main content agent"] --> schema-shape-summary["Schema shape summary"] main-content-agent --> set-primitive["Set primitive"] set-primitive --> user-verification-ui["User verification UI"] main-content-agent --> groq-query-validator["GROQ query validator"] groq-query-validator --> execution-layer["Execution layer"] main-content-agent --> mutation-subagent["Mutation subagent"] mutation-subagent --> execution-layer set-primitive --> execution-layer
Components
| Component | Role | Interacts with |
|---|---|---|
Main content agent |
Primary agent that orients, plans, queries, inspects sets, and coordinates content operations. | Schema shape summary, Set primitive, GROQ query validator, Mutation subagent, User verification UI |
Schema shape summary |
Compressed overview of document types, fields, references, and relationship hints. | Main content agent |
Set primitive |
Reusable handle to a large query result with metadata such as counts, ranges, type breakdowns, query, title, and description. | Main content agent, User verification UI, Execution layer |
GROQ query validator |
Code layer that parses, validates, inspects, repairs, serializes, and executes model-drafted GROQ queries. | Main content agent, Execution layer |
Mutation subagent |
Specialized subagent spawned with local schema/path/document context for difficult Sanity document mutations. | Main content agent, Execution layer |
Execution layer |
Runs expensive or risky actions: processing sets, mutating many documents, running code, or exporting files. | Set primitive, GROQ query validator, Mutation subagent |
User verification UI |
Lets the user inspect the set and verify that the agent is acting on the correct content slice. | Set primitive, Main content agent |
Data flow
The agent first receives schema summaries and set metadata rather than full raw data. It queries into a set, inspects the set shape, verifies whether it is the right slice, and only then performs deep analysis, code execution, export, or document mutation. For queries, the model drafts GROQ and code parses, repairs, serializes, and executes it.
Why this architecture
Sanity found that broad, clear tools plus better context shape outperformed slicing capabilities into many overlapping tools. The architecture gives the model enough structure to orient before fetching details or running expensive actions, keeping context clean and user trust higher.
Models used: LLM content agent · Specialized mutation subagent · GROQ-aware model behavior
Scale
- Sanity customers can have hundreds of content types and tens of thousands of documents.“Some have hundreds of content types and tens of thousands of documents.”transcript, stated
- The set primitive is explicitly meant for hundreds, thousands, or hundreds of thousands of documents.“How do we let the model work on hundreds, thousands, or hundreds of thousands of documents without pushing all of that into the main context?”transcript, stated
- The schema example included 843 incoming references from blog posts to author.“Author has eight hundred and forty-three incoming references from blog post.”transcript, stated
- The system supports bulk operations such as updating hundreds of documents safely.“updating hundreds of documents safely, or even just stuff like creating a CSV for sales or support.”transcript, stated
Alternatives considered (roads not taken)
Add more small tools
Rejected because: More tools made the agent less consistent and more likely to choose the nearly right tool.
Dump full schemas into context
Rejected because: Huge schemas expose detail without clarity and cause the model to miss relationships.
Push all large query results into the main context
Rejected because: The agent only needs the shape of the result and next action, not thousands of documents in its head.
Use complex multi-agent systems broadly
Rejected because: Subagents lost useful context from the main conversation, so Sanity uses them only where the gain is clear.
Patterns
context-compaction (context)
Sanity compresses schemas into shape summaries and large query results into sets rather than raw data dumps.
tool-use-orchestration (orchestration)
The agent relies on fewer broader tools with clear boundaries and instructions instead of many overlapping tools.
structured-output-contract (reliability)
Model-drafted GROQ is parsed, validated, repaired, serialized, and executed by code rather than blindly trusted.
multi-agent-orchestration (orchestration)
Sanity keeps one strong main agent and uses specialized subagents only for clear bounded tasks like mutations with exact local context.
human-in-the-loop-gate (governance)
The UI exposes sets so users can verify that the agent is acting on the right content before expensive or risky work.
Tradeoffs
Agent context strategy
Chose shape first, detail on demand, execution last over showing raw schemas/results and acting immediately.
Rationale: The shape gives enough orientation to decide whether to inspect, stop, or safely proceed without bloating context.
Large-result representation
Chose sets as reusable handles over loading thousands of documents into the model context.
Rationale: Sets preserve query, metadata, and user-verifiable shape while keeping the raw payload out of context.
Query execution
Chose model draft plus code validation/repair over shipping model-written GROQ directly.
Rationale: Close queries are not enough when IDs/types are required for linking and safe operations.
Subagent usage
Chose specialized mutation subagent with local shape over broad multi-agent architecture everywhere.
Rationale: Mutation is hard enough to justify a subagent, but only if it starts with exact local context rather than a generic short instruction.
Gotchas (what bit them)
Overlapping tools degrade action selection.
Root cause: Similar-sounding tools make the model spend effort selecting tools instead of solving the user's problem.
Resolution: Use broader tools with clear boundaries and better instructions.
Full schema detail hides relationship clarity.
Root cause: Large schemas contain many fields, nested objects, arrays, references, and validations, so raw JSON overwhelms the model.
Resolution: Show a compressed schema graph/overview first and let the model zoom into exact structure only when needed.
Subagents can erase accumulated conversation nuance.
Root cause: The main agent may pass only a short instruction, losing tone, structure, intent, and shared working memory.
Resolution: Bias toward one main agent; when using mutation subagents, spawn them with schema type, field path, studio context, and document context.
Evaluation
The transcript reports qualitative production learning rather than a formal benchmark: fewer broader tools improved consistency, compressed schema views fixed relationship errors, sets enable user verification, and code validation enforces GROQ correctness.
Metrics: tool-selection consistency · schema relationship correctness · set size/count/range/type metadata · user verification before expensive work · query validation/repair success
Outcomes
- Compressed schema views fixed many relationship-based mistakes.
- Sets let the agent work with very large content collections without holding raw documents in context.
- Fewer broader tools plus one main agent helped Sanity do more with less tool complexity.
The system is designed for Sanity deployments with hundreds of content types and up to hundreds of thousands of documents; sets provide counts, ranges, and type breakdowns before large work proceeds.