~ portfolio

Satvik Sawhney

software engineer

loading000%
essay Building this site

Grounding a portfolio chatbot so it can't be jailbroken into nonsense

How I keep an LLM that answers as me on-script: a tight knowledge brief, server-side guardrails, and refusal templates — without killing the conversational feel.

SS
Satvik Sawhney
May 12, 2026 · 1 min read
share

The chatbot on this site answers questions as me. That's useful — and a liability. An ungrounded model will happily invent a job I never had or follow a "ignore your instructions" prompt straight off a cliff.

Three layers, not one

  1. A compact knowledge brief. ~2.5k tokens of verified facts — roles, projects, metrics — injected as the system prompt. The model paraphrases from this, it doesn't free-associate.
  2. Server-side guardrails. Before any model call, the request is checked against a set of jailbreak patterns. A match short-circuits to a static refusal — no tokens spent, no chance to comply.
  3. Refusal templates. When asked to step outside its role, it declines in a consistent, on-brand voice instead of improvising.
const JAILBREAK = [
  /ignore\s+(all|previous|prior)\s+(instructions?|rules?)/i,
  /you\s+are\s+now\b/i,
];
if (JAILBREAK.some((rx) => rx.test(userText))) return refusal();

What I deliberately didn't do

I didn't bolt on a vector database. For a corpus this small, retrieval adds latency and failure modes without improving answers — the whole brief fits in context. The right amount of infrastructure is sometimes none.

The result feels conversational but stays factual. Ask it about my work and it pulls real numbers; try to break it and it stays in character.

more in “Building this site
Grounding a portfolio chatbot so it can't be jailbroken into nonsense — Satvik Sawhney