Portfolio RAG Chatbot — Career, Projects & Blog Q&A Assistant
2026-08 – Present
A retrieval-augmented chatbot embedded on this website that answers visitor questions strictly from my own career history, projects, and blog posts — with strict topic guardrails and inline source citations on every answer.
Overview
A floating chat widget on this site that lets visitors ask about my career, education, projects, and blog posts in natural language - and nothing else. Most portfolio chatbots either hallucinate freely or need a human to babysit them; the goal here was a small, strictly-scoped RAG system that refuses gracefully outside its domain and never fabricates a source.
Architecture
Ingestion. An admin-triggered "Rebuild Knowledge Base" action pulls content directly from the site's own data layer - career entries, project descriptions, published blog posts (including markdown reports resolved from file), and a static bio/education document. Each source is chunked into ~1000-character passages, embedded with OpenAI's text-embedding-3-small, and upserted into a Pinecone serverless index alongside metadata (title, source type, and a real internal URL for citation).
Query flow. A question is embedded and matched against the index via cosine similarity. If the best match falls below a confidence threshold, the system returns a canned refusal without ever calling the chat model - cheaper, faster, and immune to prompt-injection tricks that rely on the model seeing the question at all. If the match is strong enough, the retrieved passages are passed to gpt-4o-mini inside a system prompt that restricts it to answering only from that context and explicitly instructs it to ignore any embedded instructions trying to override those rules.
Citations are never model-generated. The source list returned to the user is built programmatically from the retrieval results own metadata, not asked of the LLM - so a citation can never point to a page that wasn't actually used to answer the question.
Guardrails
- Input length caps and a per-IP rate limit (Flask-Limiter) to control cost and abuse on a public, unauthenticated endpoint.
- A similarity-threshold gate that turns away off-topic questions before they reach a paid model call.
- A system prompt hardened against prompt injection embedded in the user's question.
- Deterministic, retrieval-derived source citations on every substantive answer.
Result
A visitor can ask "What projects have you built with multi-agent RAG?" and get a synthesized answer citing the specific project and blog pages it drew from - while a question like "what's the capital of France?" is refused outright, before it ever reaches OpenAI.