Agent Architecture7 min readยท

How to Build an AI Customer Support Bot From Help Center Content

Your help center has three hundred well-written articles, and your support bot still tells customers to click a button that was removed in last quarter's redesign. Worse, it invents a refund policy that your finance team never approved.

Your help center has three hundred well-written articles, and your support bot still tells customers to click a button that was removed in last quarter's redesign. Worse, it invents a refund policy that your finance team never approved. The content is right there, indexed, embedded, retrieved, and the answers are still wrong. That gap between "we have the content" and "the bot answers correctly" is where most support-bot projects quietly stall, and every hallucinated answer erodes the trust that made customers self-serve in the first place.

The usual diagnosis blames the model. The real problem is upstream: retrieval that returns approximately-relevant chunks, embeddings that drift out of sync the moment an article is edited, and agent instructions that live in a config file no support lead can review. Sanity Context is the AI Content Operating System's grounding layer, an intelligent backend that keeps a support agent answering from governed, current help center content instead of a stale snapshot of it.

This guide walks the full architecture: shaping help center content so it retrieves cleanly, wiring hybrid retrieval that combines meaning and exact matching, keeping embeddings fresh as articles change, and putting agent instructions under editorial control. The goal is a bot that stays correct as your product does.

Why help center content breaks support bots

The failure is rarely the language model. It is the shape of what the model is fed. Most help centers store articles as HTML blobs or Markdown files, which means the retrieval step has nothing structured to grab: it slices articles into arbitrary chunks, embeds each chunk, and hopes the nearest vector is the right paragraph. When a customer asks "how do I cancel and get a refund," the retriever may surface a chunk about cancellation and a separate chunk about refund eligibility from an unrelated plan, and the model stitches them into a confident, wrong answer.

Three structural problems compound this. First, unstructured content has no fields, so the retriever cannot filter to "only articles for the Enterprise plan" or "only content marked current." Second, embeddings computed by a separate pipeline go stale the instant an editor fixes an article, because nothing tells the vector store to recompute. Third, chunk boundaries destroy context: a step-by-step guide loses its ordering, a table loses its columns, a warning callout gets divorced from the step it warns about.

Modeling your business is the first pillar, and it applies directly here. When help center content lives as structured documents with real fields, plan, product area, audience, status, last-reviewed date, the retrieval layer has handles to filter and rank on, not just a wall of text. The bot stops guessing which article applies because the content itself carries that answer. Fixing the model is the last thing you should try; fixing the content shape is the first.

Illustration for How to Build an AI Customer Support Bot From Help Center Content
Illustration for How to Build an AI Customer Support Bot From Help Center Content

Model help center content so an agent can retrieve it cleanly

Start by treating each help center article as a typed document, not a page. A support article schema might carry a title, a body in Portable Text, a plan or product-area reference, an audience tag, a status field (draft, in review, published, deprecated), and a last-reviewed timestamp. Because the body is Portable Text rather than a rendered HTML string, structured blocks like ordered steps, tables, and callouts keep their semantics all the way into retrieval, so a procedure stays a procedure instead of collapsing into a flat paragraph.

That structure pays off twice. At query time, GROQ can filter to exactly the documents that apply before ranking them, so an Enterprise customer never gets an answer sourced from a Starter-plan article. And the same fields let you enforce editorial hygiene: a scheduled query can surface every article whose last-reviewed date is older than six months, which is how you keep the corpus the bot answers from actually current.

Content Lake, Sanity's queryable content store, is the backbone here. It is the store the retrieval path reads from, which means there is no export step, no nightly sync into a separate search index, and no window where the bot answers from a snapshot that no longer matches what a human would read on your site. Beyond your own articles, Knowledge Bases turn datasets, websites, PDFs, and support databases into agent-readable documents that share the same retrieval path, so a bot can draw on a policy PDF and a published article through one query surface. The modeling work you do once becomes the substrate every downstream retrieval and governance step relies on.

Wire hybrid retrieval so the bot finds the right answer, not an approximate one

Pure vector search is good at meaning and bad at specifics. Ask it about "error code E-4021" and semantic similarity may return articles that are broadly about errors while missing the one document that names E-4021 exactly, because an alphanumeric code carries little semantic signal. Pure keyword search has the opposite failure: it nails the code but misses the customer who described the symptom in their own words without ever typing the code. Support questions need both at once.

Inside Content Lake, hybrid retrieval is native, not an assembly job. A single GROQ query blends semantic and lexical signals: `text::semanticSimilarity()` scores documents by meaning, a BM25-style `match()` scores exact term and code hits, and you combine them with `score()` and `boost()` to weight the blend for your corpus. Because it is one query against the store your content already lives in, you are not maintaining a vector database alongside a search engine and reconciling two sets of results in application code.

That single-query design also means the structured fields from your model are available in the same breath as the ranking. You can filter to published, in-plan, current documents and then rank the survivors by the hybrid score, so relevance and governance are enforced together rather than in separate passes. The practical result for a support bot is fewer confidently-wrong answers: the retriever returns the article a human agent would have opened, with its steps and tables intact, and the model summarizes rather than invents. Retrieval quality, not model choice, is where support-bot accuracy is won or lost.

Keep embeddings fresh so the bot never answers from a stale article

The quietest way a support bot goes wrong is drift. An editor corrects a pricing article on Monday; the embedding for that article was computed last Tuesday against the old text; the bot keeps confidently citing the deprecated price until someone remembers to rerun the embedding job. In a standalone vector-database architecture, that reconciliation is your responsibility: you build change-detection, you queue re-embeds, you handle the failures, and you accept a window of wrong answers in between.

With dataset embeddings, the embeddings are tied to the content itself, so when an article changes the embeddings propagate within minutes with no separate vector pipeline for your team to build or babysit. The store the bot retrieves from and the store editors publish into are the same store, which closes the drift window that causes the most damaging class of support errors: an answer that was correct last month and is confidently wrong today.

This is the difference between bolting AI onto a content system and building the content backend for AI. Legacy CMSes stop at publishing and leave the AI plumbing to you; the freshness problem is exactly the seam where bolt-on architectures leak. When embeddings are a property of the content rather than a downstream artifact, correctness becomes the default state instead of a maintenance chore, and your support content and your support bot cannot disagree with each other. For a bot whose whole value is trust, eliminating that class of error is worth more than any prompt-engineering tweak.

Govern agent instructions the way you govern the website

A support bot's behavior is not just its retrieval; it is also its instructions. What tone does it use, what topics does it refuse, when does it escalate to a human, how does it handle a refund request it is not authorized to approve? In most stacks that policy lives in a system prompt buried in a repository, which means the people who own support policy, the support leads and the legal reviewers, cannot see it, cannot review it, and cannot change it without a developer and a deploy.

That is a governance gap, and for a bot that speaks to customers in your company's voice it is a real risk. Sanity closes it by treating agent instructions as governed content. In the Studio, the same interface where editors manage articles, agent instructions become reviewable, versioned content rather than opaque code. With Content Releases, a change to how the bot handles cancellations can be staged, previewed, and shipped as a unit, the same way you stage a website change, so a risky instruction change gets reviewed before it reaches a single customer.

Agent Actions provide schema-aware APIs for LLM-driven content workflows like generate, transform, and translate, which means the same governed corpus can power a multilingual bot without a parallel translation pipeline drifting out of sync. Production agents connect through the Sanity Context MCP endpoint, so the agent your customers talk to queries the exact governed content and instructions your team reviewed, not a copy that diverged. Legacy CMSes create silos between the content, the AI config, and the people accountable for both; the Content Operating System gives all three a shared foundation.

An end-to-end architecture and where each piece lives

Put the pieces together and the architecture is legible. Help center content is modeled as typed documents in Content Lake, with fields for plan, product area, audience, status, and review date, and bodies in Portable Text that preserve steps, tables, and callouts. External material, policy PDFs, a support-ticket database, a public docs site, enters through Knowledge Bases and lands on the same retrieval path, so there is one place to query rather than four.

At request time, the bot issues a single GROQ query that filters to published, in-plan, current documents and ranks them with a hybrid blend of `text::semanticSimilarity()` and `match()`, tuned with `score()` and `boost()`. Because dataset embeddings track the content, the ranking reflects what editors published today, not last week. The retrieved, structured context goes to the model, which summarizes intact procedures rather than reassembling orphaned chunks. Governance wraps all of it: instructions live as reviewable content in the Studio, changes ship through Content Releases, and the running agent reaches everything through the Sanity Context MCP endpoint.

The operational payoff is that scaling the bot does not mean scaling headcount. Rigid CMSes force you to add people to add languages, plans, or product lines; here the same modeled corpus and the same retrieval path absorb new content, so you scale output instead of staff. Sanity Context (previously Agent Context) is the intelligent backend for companies building AI content operations at scale, which in support terms means one governed source of truth that the bot, the editors, and the auditors all read from. On the compliance side, Sanity offers SOC 2 Type II, GDPR alignment, regional hosting for data residency, and a published sub-processor list, so a customer-facing bot built on it starts from a defensible security posture rather than retrofitting one.

Building a support bot on help center content: architecture comparison

FeatureSanityPinecone + glueContentful + external searchpgvector / Neon
Hybrid retrieval (meaning + exact match)Native: text::semanticSimilarity() and match() blended with score() and boost() in one GROQ query against Content Lake.Supports sparse-dense hybrid vectors, but keyword and metadata logic is assembled in application code alongside the vector index.No native vector search; hybrid retrieval means integrating an external search or vector service and reconciling results yourself.pgvector gives ANN search and Postgres full-text; blending and ranking the two is hand-rolled SQL you own and tune.
Embedding freshness on content editsDataset embeddings are tied to content, so an edited article re-embeds within minutes with no separate pipeline to run.You detect changes, re-embed, and upsert; the reconciliation pipeline and any drift window are your responsibility.Content edits fire webhooks, but re-embedding into the external store is custom integration code you build and maintain.No built-in embedding lifecycle; a trigger or job to recompute vectors on row change is yours to write.
Structured content model for filteringTyped documents with plan, audience, status, and review-date fields queried directly in GROQ before ranking.Metadata filters exist on vectors, but the content model itself lives in a separate system you keep in sync.Strong structured content modeling; the model just is not queryable together with vector ranking in one call.Full relational schema for filtering, joined to vectors in SQL; you own the query design and its performance.
Governing agent instructionsInstructions are reviewable, versioned content in the Studio, staged and shipped through Content Releases like a site change.No instruction governance; system prompts live in your app code and deploy pipeline, outside editorial review.Editors can model instruction content, but staging agent behavior as a release and previewing it is not a built-in flow.Instruction storage is possible in a table; review, versioning, and staged rollout are entirely up to your app.
Unifying PDFs, sites, and databasesKnowledge Bases turn datasets, websites, PDFs, and support databases into documents on the same retrieval path.Each source needs its own ingestion and chunking before it reaches the index; unification is a pipeline you build.Ingesting external PDFs and databases requires custom import into the content model, then into the search layer.Load and chunk each source into tables yourself; there is no managed ingestion for mixed source types.
Multilingual support contentAgent Actions provide schema-aware generate, transform, and translate over the governed corpus, no parallel pipeline.Translation is upstream; you translate, re-embed, and index each locale before the bot can serve it.Localization fields are first class, but AI translation and its re-indexing are integrations you assemble.No content-layer translation; locale handling and re-embedding are application concerns you implement.
Production agent connectionAgents connect through the Sanity Context MCP endpoint to the exact governed content and instructions the team reviewed.Agents hit your API and the vector index directly; there is no product-shaped endpoint tying content and governance together.Agents use the delivery API for content and a separate service for retrieval, wired together in your application.Agents query Postgres via your own service layer; the retrieval contract is whatever your code exposes.