Building an AI Assistant for Your Product's Documentation
Your docs are already the source of truth. Turn them into a conversational AI assistant your users will actually want to use.
DocPilot Team
AI documentation research and engineering from Onzira Labs.
Why Your Product Docs Deserve Better Than a Search Bar
Most documentation sets are static. Users land on a page, scroll, give up, and open a support ticket. The information they need is almost always in the docs, but the path to finding it is broken. Search returns twenty pages that match a keyword. Navigation assumes the user already knows your mental model. Long pages force readers to Ctrl+F through walls of text.
An AI assistant flips the relationship. Instead of forcing users to find the answer, the answer finds them. They ask in natural language, the assistant replies with the relevant excerpt, the API signature, the configuration snippet, or the troubleshooting step. No new content to write. No migration to a knowledge base. Just a layer on top of what you already have.
The catch: a useful assistant is not a wrapper around a foundation model. It is a retrieval-augmented system that grounds responses in your actual documentation. Build it well, and it pays for itself in reduced support load and faster onboarding. Build it badly, and you ship a hallucinating chatbot that erodes trust.
This guide walks through the architecture, the data pipeline, the prompt design, and the failure modes that matter when you turn your docs into a conversational interface.
The Architecture: RAG Over Your Existing Docs
The pattern is retrieval-augmented generation (RAG). At query time, the system retrieves the most relevant chunks from your documentation and includes them in the prompt to a language model. The model answers using that context, not its training data.
User question
↓
Embedding model (query vector)
↓
Vector database (top-k similar chunks)
↓
Prompt: question + retrieved chunks + system instructions
↓
LLM (grounded answer)
↓
User-facing response
The four moving parts you need to think about:
- Ingestion pipeline: how docs go from your repo to a searchable index.
- Embedding model: how text becomes vectors.
- Vector store: where vectors live and how similarity is computed.
- Generation layer: how the final answer is composed and presented.
Each one has tradeoffs. The rest of this guide works through them in order.
Step 1: Build the Ingestion Pipeline
The goal is to keep your docs index in sync with the canonical source. If you maintain documentation in GitHub alongside the code, treat the repo as the source of truth and rebuild the index on every push.
Chunking Strategy
Documents are too large to embed as a single vector. A typical API reference page might be 4,000 tokens; you want chunks in the 200 to 600 token range. Smaller chunks give finer retrieval but lose context. Larger chunks keep context but dilute relevance.
The practical middle ground:
- Split on semantic boundaries (headings, code fences, list items), not arbitrary token counts.
- Keep heading hierarchy attached to each chunk as metadata so the answer can cite the section.
- Preserve code blocks as a single unit. Splitting inside a function signature breaks retrieval.
Here is a minimal chunker in Python that respects Markdown structure:
from markdown_it import MarkdownIt
def chunk_markdown(text, max_tokens=400):
md = MarkdownIt()
tokens = md.parse(text)
chunks = []
current = []
current_len = 0
for token in tokens:
if token.type == "heading_open":
if current:
chunks.append("".join(current))
current, current_len = [], 0
current.append(token.content)
current_len += len(token.content.split())
if current_len >= max_tokens:
chunks.append("".join(current))
current, current_len = [], 0
if current:
chunks.append("".join(current))
return chunks
Sync Mechanism
A webhook from your Git provider is enough. When main changes, run the ingestion job. Most teams keep the pipeline under ten minutes end-to-end: fetch, chunk, embed, upsert.
If you use a tool like DocPilot, this layer is already handled. Connect the repo, and the platform regenerates READMEs, setup guides, architecture docs, and API references on every commit, then exposes them in a format ready to feed into a vector store. That removes the most painful part of the project: keeping the index fresh.
Step 2: Pick the Embedding Model
The embedding model converts text into a fixed-size vector. Cosine similarity between query and chunk vectors is what retrieval actually measures, so the quality of the embedding model directly determines recall.
A reasonable starting lineup:
| Model | Dimensions | Notes |
|---|---|---|
OpenAI text-embedding-3-small | 1536 | Good default, low cost, multilingual |
Cohere embed-english-v3.0 | 1024 | Strong on technical English |
Voyage voyage-code-3 | 1024 | Tuned for code and docs |
BGE bge-large-en-v1.5 | 1024 | Open weights, self-hostable |
For product documentation, technical-language models like Voyage or BGE tend to outperform general-purpose ones on code-heavy chunks. The difference shows up on queries like "how to authenticate with OAuth" or "what does the retry-after header mean" where vocabulary overlap is low.
Evaluate on a held-out set of real support questions. Twenty to fifty questions with the chunk you would manually point a user to. Hit rate at top-5 is the metric that matters.
Step 3: Choose the Vector Store
For teams under a few hundred thousand chunks, any modern vector database works. The differences come down to operational concerns.
| Store | Best for |
|---|---|
| pgvector | Existing Postgres, low ops overhead |
| Pinecone | Managed, fast scale, paid |
| Qdrant | Self-hosted, strong filters |
| Weaviate | Hybrid keyword + vector search |
| Chroma | Prototyping, in-process |
One feature worth caring about: metadata filtering. If your assistant should respect URL paths, product versions, or doc tags, filtering at query time is faster and more reliable than relying on the embedding to encode that signal.
results = index.query(
vector=embed(question),
top_k=5,
filter={"version": "v2", "section": "api"},
)
Step 4: Design the Prompt
Retrieval gets you the right chunks. Prompt design is what keeps the model honest.
A production prompt usually has three parts:
- System instructions that constrain behavior.
- Retrieved context with clear delimiters.
- The user question, unmodified.
You are a documentation assistant for [Product].
Answer the question using only the context below.
If the answer is not in the context, say "I don't have that information"
and point the user to support@example.com.
Quote code snippets verbatim. Cite the section heading in parentheses.
Context:
---
[CHUNK 1]
Section: Authentication > OAuth
[CHUNK 2]
Section: API Reference > Rate Limits
...
---
Question: {user_input}
The "say I don't know" instruction matters more than people expect. Without it, the model will confabulate. With it, you trade a small amount of coverage for a large amount of trust.
Streaming and Citations
Stream the response token by token to keep latency tolerable. Long-context prompts with five chunks can take a few seconds to start generating. Streaming cuts perceived latency roughly in half.
Always include the source citation. Users who can click through to the underlying page trust the assistant more, and your support team gets fewer follow-up questions.
Step 5: Handle the Hard Cases
A working prototype takes a weekend. A working product takes longer, because of the edge cases.
Versioning
Users on v1 should not see v2 answers. Store the version in the chunk metadata and filter at query time. If you cannot determine the user's version from context, ask.
Multi-turn Conversations
Users follow up. "What about retries?" only makes sense if the previous turn was about rate limits. Either rewrite the question using the chat history, or run retrieval on the last user message plus a summary of prior turns.
Code Questions
Embeddings of code and prose are different beasts. For API reference pages, keep code blocks intact and include the surrounding prose in the same chunk. For raw code samples, consider a separate index.
Eval Pipeline
Treat the assistant like any other production system. Maintain a set of fifty to one hundred question-and-expected-answer pairs. Run them nightly. Track:
- Retrieval hit rate (was the right chunk in top-5?)
- Answer correctness (did the model produce something right?)
- Refusal rate (how often did the model say "I don't know"?)
- Citation accuracy (do the cited sections actually contain the answer?)
A drop in any of these signals a regression in ingestion, embeddings, or the prompt.
Where to Start
If you are starting from zero, the shortest path is:
- Pick an embedding model and a vector store you can run locally.
- Chunk one section of your docs and embed it.
- Wire retrieval into a chat completion call.
- Test on real user questions.
You will learn more in a week of running queries against your own docs than in a month of reading papers.
The longer path, the one most teams eventually take, looks like this: keep the docs in Git, automate the ingestion on push, run evals weekly, and version the index alongside the product. None of that requires new content. It requires treating documentation as a system, not a deliverable.
If the part you keep deferring is the documentation itself, DocPilot handles it end to end. Connect your GitHub repo and it generates READMEs, setup guides, architecture overviews, and API references from the code, then keeps them in sync through webhooks on every commit. When you are ready to wire up the assistant described above, the output is already in a format that drops straight into a vector store. Try the free tier at docpilot.io and see what your codebase already explains about itself.
Read next
ai-chat
How to Add AI Chat to Your Product Documentation in an Afternoon
Your users are searching your docs with the wrong keywords. Here's how to ship an AI chat layer over them before lunch.
Read
migration
Migrate to AI Documentation in 30 Days: A Complete Plan
Most documentation migrations die in week three. Here is the 30-day plan that survives contact with reality — week-by-week tasks, scripts, and rollout tactics that turn AI docs from a side project into your team's default.
Read
release-notes
How to Ship Better Release Notes with AI
Most release notes are an afterthought. Here's a practical workflow for turning commits, PRs, and changelogs into notes your users actually read.
Read