Building a RAG Chatbot
Build a documentation chatbot with Retrieval-Augmented Generation. Scrape the AISViz docs, index them in ChromaDB, and ground Gemini answers in real pages that every response cites.
A raw language model asked about AISdb will confidently invent function names that were never in the library. In this tutorial you build a chatbot that cannot do that, because every answer is generated from passages retrieved out of the real AISViz documentation and each response reports the source pages it leaned on. The whole pipeline, scraper to web interface, runs locally on a laptop and drops onto a Hugging Face Space unchanged when you want a public URL.
What you will learn
Scrape live documentation sites into a clean text corpus
Split long pages into overlapping chunks sized for retrieval
Embed chunks with SentenceTransformers and store them in a ChromaDB vector store
Retrieve top-k context per question and generate a grounded, source-citing Gemini answer
Serve the chatbot through Gradio and publish it as a Hugging Face Space
Prerequisites
pip install langchain "langchain[google-genai]" chromadb sentence-transformers gradio beautifulsoup4 requestsNo AIS file is needed on this page. The corpus is the documentation itself, crawled live from https://aisviz.gitbook.io/documentation and https://aisviz.cs.dal.ca in step 1. You also need a Google AI Studio API key (any LangChain-supported provider works the same way), exported before you start.
export GOOGLE_API_KEY="your-api-key-here"The pipeline has two phases. Indexing runs offline and turns the docs into a searchable vector store; retrieval and generation run at question time.
1. Scrape the documentation
The chatbot can only answer from pages it has seen, so the first step crawls both public sites, follows same-domain links, and keeps the main content block of every page along with its URL for later attribution.
The page count moves as the documentation grows, and answers are only ever as current as the last crawl, so re-run this step whenever pages change.
2. Split pages into chunks
Whole pages are too long to retrieve precisely and would not fit a prompt anyway. Splitting into roughly 1000-character chunks with 200 characters of overlap keeps each chunk focused while the overlap stops sentences from being cut mid-thought at chunk borders.
3. Embed and store in ChromaDB
Retrieval works by comparing vectors, so every chunk gets encoded once with the compact all-MiniLM-L6-v2 SentenceTransformer and written into a persistent Chroma collection. The ./chroma_db directory survives restarts, which means you index once and query many times.
4. Retrieve context and generate answers
At question time the pipeline embeds the question with the same model, pulls the four most similar chunks from Chroma, and hands them to Gemini with instructions to answer only from that context and to say so when the context does not contain the answer. That last instruction is what keeps the bot from inventing APIs.
5. Serve it with Gradio
A chat window makes the bot usable by people who will never open the script. Gradio's ChatInterface wraps answer_question in a few lines and appends the retrieved sources to every reply so users can verify claims themselves.
demo.launch() starts the app on a local URL, usually http://127.0.0.1:7860, and it comes up in under a minute once the index is built.
6. Publish as a Hugging Face Space
The same script becomes a public chatbot with no code changes. Create a Space, upload the file as app.py, list the packages from Prerequisites in a requirements.txt, and add GOOGLE_API_KEY as a Space secret. The Space runs the identical code you tested locally, so there is nothing new to debug; the full workflow is in the Hugging Face Spaces documentation.
Results
A run against a freshly indexed docs collection answers the test question like this.
The wording and the exact sources depend on which pages you indexed and which Gemini version answers, so expect the substance rather than the bytes to match. If an answer comes back thin or wrong, open the cited source page, it is usually the page that needs improving, then re-crawl and re-index.
Takeaway
Grounding a model in retrieved documentation replaces invented function names with answers that cite real pages.
The index is a snapshot. Re-run the scrape-chunk-embed steps whenever the docs change, or the bot answers from stale text.
Chunk size and overlap trade retrieval precision against context. The 1000/200 defaults work well for documentation prose.
A hosted model still sounds confident on thin context, which is why every response carries its sources for checking.
Next, A No-Code Interface wraps AISdb preprocessing and a similar chat assistant in a point-and-click Gradio app.
References
Last updated