Sherpa
The assistant in the corner of this site. Ask it anything about my work and it answers from my actual projects, resume, and blog posts, rather than from a model's imagination. A retrieval-augmented (RAG) chatbot I built end to end.
PRIVATE · NO PUBLIC URL
- Role
- Solo build
- Backend
- FastAPI · pgvector
- Frontend
- Vue · Nuxt
- Type
- RAG · streaming
- Client
- Personal project
- Timeline
- 2026
47
grounded in my own work, not guesses
CONTEXT
Sherpa is the chat button in the corner of this site. A visitor, often a recruiter, can ask it anything about me, my experience, my projects, my writing, and get a straight answer with sources, instead of scrolling to find it.
It answers only from my own content: the same projects and resume data that build this site, plus every blog post. Nothing about me is invented.
THE HARD PART
A chatbot on a personal site is a trap if it hallucinates. It cannot invent a job I never had or a skill I do not have, and it must not wander off into whatever a visitor asks. It also sits on a public endpoint that calls a paid API, so it has to be cheap and abuse-resistant.
So the real work was not "call an LLM", it was grounding, scoping, and hardening: make every answer traceable to my content, refuse everything else, and make sure a stranger cannot run up the bill.
WHAT I BUILT
- A build step turns my projects, resume, and blog into one corpus, which is chunked, embedded, and stored in pgvector on Postgres.
- On a question, the closest chunks are retrieved and the model answers only from them, citing the sources; the answer streams back token by token.
- A FastAPI service behind nginx, deployed with Docker alongside my other projects; the browser talks to it same-origin so the API key never leaves the server.
REVISIONS · THE CALLS I MADE
Retrieval, not fine-tuning
What is true about me changes: a new project, a new post. RAG means I update the bot by editing content, never by retraining, and every answer stays grounded in and traceable to my own content, so it is checkable rather than a black box.
A relevance gate plus a scoped persona
Two layers keep it honest. If retrieval finds nothing relevant it declines instead of guessing, and the persona keeps it answering as a guide to my work and nothing else. A public bot that will confidently say anything is worse than no bot.
pgvector on Postgres, not a separate vector database
The corpus is small and I already run Postgres, so the vectors live next to everything else instead of adding a new system to operate, with room to grow if the content does.
Guards before the model call
It is a public endpoint spending real money per request, so per-IP rate limiting and an input-length cap run before any paid call, output tokens are capped, and a hard monthly spend cap sits behind all of it.
OUTCOME
- Live on this site: ask it anything about my work.
- Answers are grounded in my real content; it says it does not know rather than inventing.
- Public-safe: per-IP rate limiting, input and output caps, and off-topic refusal.