Agent Governance & Evaluation7 min readยท

How to Govern Agent Instructions With Content Releases

Your support agent tells a customer to escalate a case it should have resolved, or your shopping assistant goes off-brand during a campaign. The fix should take a marketing manager five minutes.

Your support agent tells a customer to escalate a case it should have resolved, or your shopping assistant goes off-brand during a campaign. The fix should take a marketing manager five minutes. Instead it takes a pull request, a code review, and a deploy window, because the instruction that decided that behavior lives as a string in src/agents/prompts.ts that only engineering can touch. Brand voice drifts out of date for a sprint, and nobody notices until a customer does.

This is upside down. Sanity Context (previously Agent Context) is built on the Content Operating System for the AI era, the intelligent backend for companies building AI content operations at scale, and it treats the application system prompt for what it actually is: customer-facing behavior that many teams have a stake in. The engineer's instinct is right that a prompt needs versioning, review, validation, and a test gate. That instinct is an argument for a content backend, not against one.

This guide shows how to author agent instructions like content and gate them like code, using Content Releases to stage agent behavior the same way you stage your website, with an eval bench as the safety catch.

Why the system prompt is behavior, not configuration

The application system prompt is a paragraph of English that decides real behavior. It decides which escalation the support agent recommends, whether the shopping assistant pitches the in-stock item, and whether the travel agent uses brand voice or holiday voice. These are product decisions, brand decisions, and compliance decisions, dressed up as a string literal.

In most teams that string lives in the codebase. The marketing team can't read it. The compliance team can't review it. The support manager can't update the escalation language. When the agent says something embarrassing in production, the fix is a pull request. When the brand voice changes for a campaign, the prompt drifts out of date and nobody notices for a sprint. The people who own the behavior are locked out of the artifact that produces it, and the person with the keys, one engineer, has no context on the campaign, the escalation policy, or the never-say list.

The reflex is to reach for more rigor: put it behind types, tests, and CI, and treat it as code. That reflex identifies the right requirements (versioning, review, validation, a test gate) and then reaches for the wrong home for them. The real choice isn't content, loose versus code, rigorous. It's governed, with the right people able to edit and a test gate on the way out, versus a string only engineering can touch. Once an agent is real in production, the prompt stops being code and starts being a thing four or five teams have a stake in. Governing it as configuration in a repo guarantees that the people who should be tuning it never do.

Illustration for How to Govern Agent Instructions With Content Releases
Illustration for How to Govern Agent Instructions With Content Releases

Splitting the prompt into role-owned fields is access control

The first move is to stop treating the prompt as one opaque blob and model it as a document. Instead of a single string, you define fields: role (what the agent is and can do), voice (tone and brand), userContext (how the agent uses per-turn identity and session state), escalation (when and how to hand off), and mustNotSay (the topics the agent must refuse). This maps directly to the Model your business pillar: the prompt becomes a content model with a shape your organization can reason about.

Splitting the prompt into fields isn't cosmetic. It's access control. Brand owns voice. Product owns how the agent uses user context. Support owns escalation. Compliance owns the never-say list. None of them files a pull request. None waits for a deploy. In the Studio schema that looks as plain as defineField({ name: 'mustNotSay', title: 'Forbidden Topics', type: 'array', of: [{ type: 'string' }], description: "Topics the agent must refuse. Owned by Compliance." }). Ownership is legible in the schema itself.

At runtime the fields stitch together into one final system prompt, the same way a page builder stitches sections, references, and logic into a page. The agent still receives a single coherent instruction; the difference is that four teams composed it in the surfaces they already work in, rather than one engineer transcribing everyone's intent into a string. This is exactly what customers ask for once they've shipped. Vipps came to Sanity wanting the whole organization to contribute to prompt writing, with product managers owning it, not just engineers. That is the tell: when the agent is real, the prompt is a shared artifact, and the content model is what makes shared ownership safe rather than chaotic.

Staging agent behavior with Content Releases

Editing a live agent's instructions in place is the same mistake as editing a live website in place. You want to preview the change, coordinate it with a campaign, ship it at a scheduled moment, and roll it back cleanly if it misbehaves. That is what Content Releases provide, and it is the heart of the Automate everything pillar for agent governance: stage agent behavior with Content Releases the same way you stage your website, and preview before you ship.

Because the prompt is content in the Studio, you get real-time collaboration, version history, scheduled publishing, and rollback without building any of it. A brand manager can draft a holiday-voice variant inside a release, a support lead can adjust escalation language in the same release, and the whole bundle previews together before anyone touches production. The governance you already use for the website, drafts, scheduling, history, permission gating, and audit trails, applies unchanged to agent instructions. As one Nearform engineer put it: "Storing the system prompt in a Sanity document is genuinely useful. Editors tuned the agent's voice without any code changes."

The payoff compounds across surfaces. Update the instruction once, and web, co-work, apps, and customer agents stay in sync, because they all resolve the same governed document through the Sanity Context MCP endpoint. You stop maintaining a prompt-per-surface and start maintaining one release-scoped source of truth. The line that captures it: the release that ships a homepage change ships a prompt change. Editors author in the Studio, not in YAML, and tune voice and scope without waiting on a deploy window.

The eval bench: gating it like code

Letting brand, support, and compliance edit the prompt is only safe if there is a gate on the way out. Otherwise anyone can edit becomes anyone can break production. The gate is evals, and it is the half of the equation that makes prompt-as-content trustworthy rather than reckless.

An eval bench is a frozen set of representative conversations, twenty to start, each scored against a rubric you wrote. You run the suite on every model change, every prompt change, and every tool change. The bar to ship anything to production is the eval bench staying green. When a support lead edits escalation language inside a Content Release, that change runs the eval bench in CI before it can ship. A brand or support edit ships only if the bench holds. The editing surface is friendly; the gate is unforgiving, and that combination is the point.

The eval gate runs in your CI, not on Sanity's infrastructure: you wire the bench into the same pipeline that gates your code, and the release simply doesn't promote unless the run passes. This preserves the engineer's original requirement (a test gate a bad change can't slip past) while removing the engineer as the bottleneck for every voice tweak. You keep versioning, attribution, scheduled release, rollback, role-based edit, an eval gate, and separation from code deploys. A well-built content backend has these by construction. Author it like content, gate it like code, and keep both in the same system instead of splitting the artifact across a repo and a spreadsheet.

Knowing which prompt layer a behavior comes from

Before you can govern the prompt, you have to know which prompt you're governing, because the prompt is actually a stack composed into the context window every turn, written by four or five parties. Knowing which layer a behavior comes from is half the debugging.

At the bottom sits the provider system prompt from Anthropic, OpenAI, or Google, which you inherit and cannot customize. Above that, every Model Context Protocol server you connect ships tool descriptions that land in your prompt budget every turn; the Sanity Context MCP endpoint's initial_context, groq_query, and schema_explorer descriptions are examples. Then comes your application system prompt, the role, voice, scope, escalation, and never-say list your team writes. This is the layer that should live in your content backend, and the one Content Releases governs. On top of that sits per-turn runtime context (user identity, current page, session state), an optional customer-customizable layer for multi-tenant products, and tool-internal prompts that run outside your application boundary entirely.

This matters for governance because these layers have different owners and lifetimes. Static instructions are release-scoped and owned by product and brand. Per-turn runtime state is single-turn and owned by your app. Retrieved content is stable and owned by the content team. Agent-authored notes are cross-session and owned by the agent. If you treat all four as one bucket, the wrong people end up deciding behavior they don't own, and a misfire in a tool description gets debugged as if it were a brand-voice bug. Governing the application layer as content, and leaving the others to their proper owners, is what keeps the debugging honest.

Putting it together: a governed prompt lifecycle

Assembled end to end, the lifecycle looks nothing like a Friday-afternoon string edit. A campaign kicks off. The brand manager opens a Content Release and drafts a seasonal voice variant. Support adjusts the escalation field in the same release because the campaign changes which cases route to a human. Compliance reviews the mustNotSay list for the new promotion. Nobody has opened an editor or filed a pull request; each team worked in the field it owns, inside the Studio.

The release previews as a bundle, so stakeholders see the composed prompt exactly as the agent will receive it, not four disconnected diffs. When the team is satisfied, the release is scheduled to publish alongside the homepage change it belongs with. Before it can promote, the eval bench runs in CI against the frozen conversation set; if the seasonal voice quietly broke an escalation path, the bench catches it and the release doesn't ship. If a shipped change misbehaves in production, rollback is one action in version history, not a hotfix deploy.

This is where Sanity Context earns its framing as the intelligent backend for companies building AI content operations at scale. Legacy CMSes stop at publishing; this operates content end-to-end, from authoring an instruction to gating it to shipping it across every agent surface. Legacy tools make you work their way; this adapts to yours, so the release that ships a homepage change ships a prompt change. The prompt stops being an engineering liability edited under pressure and becomes a governed content asset that the people accountable for it actually control, without giving up a single guarantee an engineer would demand.

Governing agent instructions: content authoring plus an eval gate versus tooling and repo defaults

FeatureSanityLangSmithBraintrustPrompt-in-repo (default)
Where the prompt livesA structured document in the Studio with role, voice, userContext, escalation, and mustNotSay fields, alongside your website content.Prompts and datasets live in LangSmith's own store, a developer tooling layer beside your app, separate from where content teams work.Prompts live in Braintrust's prompt-management system, a separate platform from your content operations stack.A string literal in src/agents/prompts.ts, behind types and tests, readable and editable only by engineering.
Who can editBrand, Product, Support, and Compliance each own their fields with role-based permissions; none files a pull request or waits for a deploy.Engineer-facing by design; non-engineers can use the prompt playground, but role-scoped field ownership for brand and compliance is not native.Eval and prompt editing is engineer-oriented; native role-based authoring for brand, support, and compliance is not the model.Only engineering can touch it; every brand, escalation, or never-say change is a pull request and a deploy.
Staging and rollbackContent Releases stage the prompt like the website: preview the composed bundle, schedule it, and roll back from version history in one action.Prompt versions and tags support promotion, but changes are not staged alongside the website or bundled with a marketing release.Version history and promotion exist, but the prompt is not staged with the site and release bundling with content is not native.Git gives you versioning and rollback, but every change rides a code deploy rather than a content release schedule.
Eval gate on shipYou wire the frozen eval bench into your CI; a Content Release only promotes if the bench stays green, so brand edits ship gated like code.Strong eval runs and tracing; the gate is well supported, though it sits in a separate system from where content is authored.Good frozen-eval workflow and scoring that can gate changes, but the gate is decoupled from a content release process.CI can run an eval or test suite as a gate, but only on changes an engineer commits, so non-engineers stay blocked.
Sync across agent surfacesUpdate once and web, co-work, apps, and customer agents resolve the same governed document through the Sanity Context MCP endpoint.Prompt fetch by name is supported, but keeping every surface in sync is app-side integration rather than a shared content backend.Surfaces can pull a prompt version, but a single governed source shared across web and apps is not the product's model.Each surface reads a bundled string; keeping multiple agents in sync means coordinated deploys across repos.
Observability and tracingFocused on authoring, staging, and gating instructions; deep trace-level observability is expected to come from your chosen eval or tracing tool.Tracing and observability are core strengths, with detailed run inspection for debugging agent behavior.Strong scoring and eval observability for comparing prompt and model versions across runs.No built-in observability; you add logging and tracing yourself around the string.