Building an Internal Knowledge Base Agent That Your Whole Company Can Query
Your team searches Confluence, Google Drive, and Slack for answers they already published. An internal knowledge agent grounded in your structured content gives instant, accurate answers from a single source of truth.
The Internal Knowledge Discovery Problem
Every organization has the same problem: the information exists, but nobody can find it.
Product specifications live in a wiki page last updated by someone who left the company. Brand guidelines sit in a Google Doc that only a few people know about. Engineering decisions are buried in Slack threads.
When someone needs an answer, they spend thirty minutes searching across five different tools before giving up and asking a colleague—who then spends another fifteen minutes searching before finally finding it.
This internal knowledge discovery problem quietly costs enterprises millions of dollars annually in lost productivity.
An AI agent grounded in your actual company content can answer these questions instantly. But it only works if the content is structured, searchable, and governed. A Content Operating System like Sanity provides the foundation for internal knowledge agents that actually work.
Why Generic AI Assistants Fail for Internal Knowledge
Teams often start with generic AI tools:
- Prompting ChatGPT or Claude about the company: The model has no access to proprietary information and hallucinates confidently.
- Uploading documents to a chat interface: Works for small document sets, but breaks when you need to search across thousands of documents with different types, owners, and access levels.
- Rolling a basic RAG pipeline on top of a wiki or Google Drive: This can be slightly better, but it inherits standard RAG limitations:
- Stale embeddings that don’t reflect the latest changes
- Destroyed relationships between documents and metadata
- No structural filtering or understanding of document types
In this setup, the agent can’t reliably tell the difference between a current policy and an archived one, because the embedding treats both as equally valid text.
Structured Internal Content
The fix is to model your internal knowledge as structured content.
Instead of freeform wiki pages, you define schemas for the types of knowledge your organization produces. For example:
- Product specifications
- Fields: version number, owner reference, status, related features, release date
- Brand guidelines
- Fields: tone of voice, terminology, visual standards, logo usage rules
- Engineering decisions (ADRs)
- Fields: context, decision, rationale, date, approvers, related systems
- Policies
- Fields: effective date, department scope, approval references, last-verified date, status (draft/current/archived)
This structure gives your internal knowledge agent the ability to:
- Query by type (e.g. only policies, only ADRs)
- Filter by status (e.g. current vs archived)
- Traverse ownership references (e.g. show decisions owned by a specific team)
- Combine structural precision with semantic discovery
Instead of treating your knowledge base as a pile of documents, you treat it as a graph of typed, related content that an agent can reason over.
Agent Context for Internal Use
Sanity’s Agent Context is not limited to customer-facing agents. You can create an Agent Context configuration scoped to your internal content with appropriate access controls.
Key steps:
- Scope the content with GROQ
- Configure agent instructions
- Always include the last-verified date when quoting a policy
Model Internal Knowledge as Structured Content
Example GROQ Query for an Internal Knowledge Agent
This GROQ query scopes retrieval to current policies, ADRs, and product specs within the user's departments, then ranks by hybrid search combining semantic similarity and keyword matching.
*[_type in ["policy", "adr", "productSpec"]
&& status == "current"
&& department in $userDepartments
] | score(
text::semanticSimilarity(body, $question),
match(title, $question) ^ 2
) | order(_score desc)[0...5] {
_id, _type, title, status, lastVerified,
owner->{ name, department }
}