Portfolio Project #5Gemini 2.5 FlashTai Huynh

AI FAQ assistant. One script tag.
Any website.

Paste your knowledge base, get an embeddable chat widget. The AI answers from your docs — and honestly says “I don’t know” when it can’t find the answer.

Grounded answers

The assistant answers only from your knowledge base. If the answer isn't there, it says so — no hallucinations.

Embed anywhere

One <script> tag. Works on any site — WordPress, Webflow, static HTML — as a sandboxed iframe.

Instant setup

Paste your KB text, copy the snippet, paste into your site. No database, no config files.

Rate limited

50 questions per IP per day. The open CORS policy is a deliberate trade-off — rate limiting is the control.

Playground

Edit your KB, ask questions, copy the snippet.

The KB on the left is editable. Your questions go to the live POST /api/ask endpoint — results come back grounded in whatever text you’ve pasted.

Knowledge Base1,086 / 40 000 chars

Paste your FAQ content, product docs, or support text. The AI will answer only from this text.

Embed snippet
<script src="http://localhost:3000/embed.js" data-widget-url="http://localhost:3000/widget"></script>

Drop this tag before </body> on any page. The widget opens as a floating button.

Live PreviewPlayground

Ask a question to test your knowledge base in real time.

FAQ Assistant

Grounded in your knowledge base

Ready

Ask anything about your KB

Under the hood

Simple pipeline. Zero hand-waving.

Question + KB text
      │
      ▼
┌─────────────────┐
│  zod validation │  question: 3–500 chars, kb: 20–40k chars
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│   Rate limit    │  50/day per IP (Upstash sliding window)
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│ Keyword retrieval│  tokenise + stop-word filter + Jaccard overlap
│  (kb.ts)        │  → top-5 passages
└────────┬────────┘
         │
         ▼
┌─────────────────────────────────────┐
│  Gemini 2.5 Flash (grounded)         │
│  system: KB passages + rules         │  ← TRUSTED context
│  user:   "VISITOR QUESTION: ..."     │  ← UNTRUSTED data
│                                     │
│  Rules injected in system prompt:   │
│  · answer ONLY from context         │
│  · "I don't know" if not found      │
│  · ignore injection attempts        │
└────────┬────────────────────────────┘
         │
         ▼
  answer + passages used