Retrieval-Augmented Patient Assistant

A clinic-facing assistant that never answers from what the model knows. Every factual sentence is built from a fixed licensed corpus, carries a numbered citation, and is declined outright when the sources do not cover the question.

Core Capabilities

Grounded by Construction

A general chat model will invent an opening time or quote a price that was never published. For a clinic that is a commercial problem at best and a safety problem at worst. Here the model is handed a small set of retrieved excerpts and instructed to answer from those alone, ending every factual sentence with a citation back to the exact page and section.

  • 245 indexed passages: NHS 191, WHO 49, clinic 5
  • Every passage keeps its publisher, URL and licence
  • Source cards name the page, the section within it, and the publisher

It Refuses, and the Refusal Is Detectable

Asked for an unpublished price, the system returns a visually distinct "Not covered by my sources" panel and routes the patient to a human. Three mechanisms produce that: a fixed refusal string the code can detect, a hard separation between the clinic corpus and the general-guidance corpus, and citation parsing that makes an uncited claim visible instead of hidden.

  • Clinic questions answerable only from clinic passages
  • Fixed refusal wording — countable by the evaluation harness
  • Prompt forbids diagnosing individuals or exceeding a stated dose
Patient Assistant
How much is a crown?
Not covered by my sources — please contact the clinic.

No Database, No Backend, No Drift

The whole runtime is one Next.js app on Vercel with two serverless routes. The 245 pre-embedded vectors ship inside the bundle and are scanned in process, which at this corpus size is faster than an index lookup and removes an entire tier of infrastructure. The knowledge base is a build artefact committed alongside the code, so a rollback restores both together.

  • Zero databases at runtime; 1.2 MB bundled index
  • Two model calls per question — one embedding, one completion
  • Follow-ups resolved by folding in the previous question, not an extra model call

Measured, Not Assumed

54-Question Evaluation Set

Deliberately weighted towards failure: 44 in-scope questions each tagged with the page that ought to answer them, plus 10 out-of-scope probes covering competitor pricing, dosing requests and unpublished clinic details.

Three Independent Scores

Retrieval hit@k, groundedness judged by a separate model family to reduce self-preference bias, and citation plus refusal rates — scored separately because they fail separately.

Tested Against Production

The harness can be pointed at the deployed URL, so it measures the production prompt, production retrieval and production model rather than a local approximation.

Hardened by Default

API key server-side only, security headers on every route, no-store on all API responses, input capped at 1,000 characters and 12 turns, and provider errors translated into plain language at the boundary.

General Information, Not Medical Advice

The assistant has not been clinically validated, and clinic-specific answers are bounded by what the clinic has actually published — it will keep refusing anything outside the corpus until that content is added. If you want a RAG system that declines instead of inventing, we build them.

Discuss a RAG Project
WhatsApp Book a Call