An HPV website where the AI assistant answers only from validated texts.
A pharmaceutical company wanted to talk to 18 to 30 year olds about HPV in their own language, chat included. In healthcare, though, an assistant that improvises is a risk: this one answers only from texts a clinical reviewer has approved, one by one.
We built an HPV awareness website as a Laravel and Filament application: 13 pages arranged as a journey across six themes, a quiz, eight downloadable sheets, a section for sharing personal stories and a chat assistant. The assistant answers only from the 55 FAQ, glossary and myth entries approved by the clinical reviewer; when no entry is close enough to the question, it says it doesn't know. Requests about emergencies or personal treatment get a fixed reply and never reach the model.
Context
The audience is young and wants quick answers, often to questions that are awkward to ask out loud. The client is a pharmaceutical company, with a clinical reviewer who validates every health text and a privacy officer who approves the privacy notice and consents. The design came from the creative agency's PDFs, with vector illustrations and a navigation metaphor built around planets.
The problem
A language-model assistant left to itself answers from general knowledge: often well, sometimes not, and in healthcare a wrong answer given with confidence is worse than none. Writing also had to be separated from approving, and the stories people would share on the site had to be handled under the GDPR rules for health data.
What we did
- 01
One knowledge base, one source
FAQs, glossary and myths live in the database and feed both the pages and the assistant: there are never two copies of the same text. Every entry has a status. If someone edits it from the panel it goes back to draft and its vector is cleared: a changed text doesn't reach the assistant until the reviewer approves it again.
- 02
Answers only from approved entries
The assistant looks up the entries closest to the question and answers using only those, with a disclaimer added by the system rather than the model. Below the similarity threshold it says it doesn't know. The language model sits behind a swappable driver, so the provider can change without touching the rest.
- 03
Sensitive questions don't reach the model
A rule-based pre-filter recognises clinical emergencies, requests for personal treatment and signs of distress, and answers with texts prepared in advance. Before the chat, consent is recorded server-side: without it the model is never called.
- 04
Separate roles in the panel
Editorial, clinical review, legal and administration have distinct permissions: only the reviewer approves entries for the assistant, only legal edits consent texts, and the administrator manages users without access to content. The rules live in policies, not in hidden buttons.
- 05
Privacy written into the code
Stories require a declaration of legal age; unpublished ones are deleted after 30 days, published ones stay after 36 months only if made anonymous. Conversations are kept for 90 days with the IP address truncated. Fonts, illustrations and scripts are served from the site's own domain, and analytics start only after consent, through our CF-Consent banner.
How it went
The site has been live and indexable since 12 October 2026, with analytics running behind consent. The editors update texts, quiz and sheets from the panel without going through us, and the clinical reviewer decides what the assistant may say.
Tools
FAQ
Can an AI assistant give health information safely?
Only within tight limits: answers drawn from validated content, an explicit way to say I don't know and fixed rules for sensitive requests. Here the model phrases the answer, but the clinical reviewer decides the content.
What happens if a text is edited after approval?
It goes back to draft and the assistant stops using it until it is approved again. The page can keep showing the published version.
Why no external CDNs?
Every resource loaded from another domain is a transfer to a third party that has to be declared. Serving everything from the site's own domain keeps the list of data recipients short and verifiable.