RAG chatbot widget — flow wireframes
How a crawled corpus becomes vectors in MongoDB Atlas, and how the widget question becomes a grounded OpenAI answer. Three layouts to compare.
ARCH · lo-fi
Lane A · Indexing / Crawlrun: offline / scheduled
1 Seed URLs
abc.com sitemap + manual list of help / pricing / docs pages.
sitemap.xmlconfig.json
2 Crawler
Fetch pages, follow internal links, dedupe by URL hash.
PuppeteerCheerionode-fetch
3 Clean & chunk
Strip nav/footer, extract main text, split into ~500 token chunks w/ 50 overlap.
readabilitytiktoken
4 Embed chunks
Generate a 1536-dim vector per chunk; batch & retry on 429.
OpenAI text-embedding-3-small
5 Upsert to vector DB
{ text, embedding, url, title, crawledAt } → collection w/ vector index.
MongoDB Atlas$vectorSearch index
Lane B · Query / Chatrun: per-message, <2s
1 Widget
User types a question in the floating iframe widget on abc.com.
iframepostMessagesessionStorage
2 POST /api/ask
Express endpoint; rate-limit, sanitize, attach userId & session.
Expresshelmetexpress-rate-limit
3 Embed question
Same model as ingest. 1536-dim query vector.
OpenAI text-embedding-3-small
4 Vector search
$vectorSearch → top-K (k=5) chunks by cosine similarity, score filter >0.75.
Atlas $vectorSearchk=5
5 LLM answer
Build prompt = system rules + retrieved chunks + user question. Stream to widget.
OpenAI gpt-4o-miniSSE
process node OpenAI call Atlas vector op›› arrows = data hand-off