RAG-powered KB chatbot — "Ask Our Docs"
Ingest a real documentation set, ship a chat UI, and prove quality with a RAGAS evaluation.
After Phase 2 you have all the pieces. This project assembles them into a polished, defensible RAG product.
What you ship
A chatbot for a real document corpus (your company handbook, a course's PDF set, a legal codebook, or the FastAPI docs). Web UI (Streamlit or Next.js), citations on every answer, evaluation dashboard, and "I do not know" path for out-of-corpus questions.
Tech stack
- Ingest: Unstructured (or LlamaParse for tabular PDFs).
- Chunking: structure-aware Markdown splitter + parent-child + contextual chunking (Anthropic 2024).
- Embeddings:
text-embedding-3-small. Optionallyvoyage-3-largefor v2. - Stores: ChromaDB (dev) and pgvector (production parallel build).
- Hybrid:
bm25s+ dense + RRF. - Rerank: Cohere
rerank-3(free tier 1k/month). - LLM:
gpt-4.1-minifor synthesis;claude-haiku-4-5for context-prepend (with prompt caching). - Evaluator: RAGAS v0.2 (Faithfulness, Context Recall, Context Precision, Answer Relevancy, Factual Correctness).
- Frontend: Streamlit (fastest path) or Next.js + FastAPI for fancier.
- Tracing: LangSmith (free tier).
Architecture (mermaid)
mermaid
flowchart LR
U[User] --> UI[Streamlit Chat]
UI -->|/ask| API[FastAPI]
API --> Q[Multi-query expand + HyDE]
Q --> R1[BM25 search]
Q --> R2[Vector search (Chroma + pgvector)]
R1 --> RRF[RRF Fuse]
R2 --> RRF
RRF --> RR[Cohere rerank-3]
RR --> GEN[LLM synthesis with citations]
GEN --> UI
GEN --> TR[LangSmith]
EV[RAGAS eval suite] --> CI[GitHub Actions]Step-by-step
Day 1 — Ingest
- Pick the corpus. Convert all to Markdown via Unstructured.
- Save raw + cleaned text to
data/raw/anddata/clean/. - Tag every doc with
source,tenant,updated_at,tags.
Day 2 — Chunking
- Implement parent-child split. Parents = 2000-token chapters. Children = 300-token sections.
- Add contextual chunking that prepends a 1-sentence "where this chunk fits" using Claude Haiku with prompt caching. Save costs to a CSV.
- Index children in Chroma + pgvector with metadata
{parent_id, source, h1, h2, h3}.
Day 3 — Hybrid retrieval
- Build a
bm25sindex over the same children. - Implement
rrf(...). Confirm fused recall beats either alone on 30 hand-written queries.
Day 4 — Rerank + synthesis
- Add Cohere rerank-3 on top-50 candidates.
- LLM synthesis prompt: "Answer using ONLY the provided sources. Cite as [n]. If not in sources, say 'I do not know.'"
- Make sure parent chunks are passed (not children) for context.
Day 5 — Evaluation
- Generate 50 Q/A with RAGAS
TestsetGenerator. Hand-review. - Run
evaluate(...)with all 6 metrics. Store CSV per run. - Add a baseline (vector-only) and the full pipeline. Tabulate Δ.
Day 6 — UI + tracing
- Streamlit page: input box, streaming answer, expandable sources panel.
- LangSmith env vars set. Streamlit calls a FastAPI
/askthat wraps the chain.
Day 7 — Polish
- Write the post: problem → architecture diagram → eval results → cost breakdown → lessons learned.
- Record a 60-second demo video.
- Push to GitHub with a
makecommand that runs the eval gate.
Acceptance checklist
- 100% citations for every claim.
- Faithfulness ≥ 0.85, Context Recall ≥ 0.80 on golden set.
- p95 latency under 1.5s on a laptop.
- "I do not know" path triggers cleanly on 5 out-of-corpus questions.
- LangSmith trace link in README.
- Mermaid diagram + UMAP plot of embeddings + RAGAS table in README.
- One-liner Docker
docker compose upruns the whole stack.
What hiring managers are looking for
- A clear before/after RAGAS table proving each technique helped.
- Cost transparency: how many tokens per query? Caching savings?
- Honest "what I would do next" section.
This single project demonstrates 80% of "RAG Engineer" interview rubrics. Polish it.