Jul 2026
Grounded regulatory assistant for the Canadian nuclear industry
Live app ↗- 40+ documents
- 14 safety areas
- shall vs should, shown apart
- Next.js
- TypeScript
- OpenAI
- Supabase pgvector
- Cloudflare Workers
5 lines
- Built a RAG chat over 40+ Canadian Nuclear Safety Commission documents: 15 priority REGDOCs plus 26 best-practice documents spanning all 14 safety and control areas. Answers cite the source document and section, and requirements (shall/must) are visually separated from guidance (should/may).
- Ingested and chunked the documents with section metadata and a requirement-type tag, embedded with text-embedding-3-large stored as half-precision vectors in pgvector, and retrieved and reranked top-k chunks that are wrapped as untrusted context before generation.
- Wrote an evaluation harness with a golden set, LLM-as-judge faithfulness and citation-support scoring, out-of-corpus rejection probes and ID-based hit@k and MRR. Used it to justify the embedding upgrade (hit@8 95.7% to 96.7%, recall@8 82.6% to 86.0%), and later to catch a real regression when the corpus grew (hit@8 96.7% to 91.3%, 15 queries worse, none better). Root-caused it to near-identical boilerplate sections colliding in retrieval, recovered half the loss by dropping them, and held the production release pending a generation eval.
- Added production guardrails: per-tier rate limiting, input sanitization with jailbreak-pattern detection, a streaming output guard that truncates on deny-list hits, and PII-safe logging that hashes IPs and user IDs with a daily salt and never stores query or response text.
- Built a licence-manifest-driven fetcher for growing the corpus: 15 US NRC regulatory guides fetched and validated through the PDF path but held from ingestion until citations are source-aware, and 16 IAEA standards catalogued as reference-only because their licence does not allow full-corpus storage.