Clinic Knowledge Bot
Overview
A small family clinic answers the same questions on WhatsApp all day: opening hours, prices, whether BPJS is accepted, how long to fast before a blood test. The answers already exist in the clinic's documents, but someone still has to look them up and type them out.
I built this bot to practice retrieval-augmented generation (RAG) with n8n. It answers only from the clinic's own documents, says so when it does not know, and never gives medical advice. It is a demo project: the clinic (Cempaka Family Clinic, Surabaya) and its documents are fictional, and the workflows run on a live n8n server.
The Build
What I Built
The clinic keeps four Google Docs: services and prices, doctors and opening hours, booking and payment policies, and a patient guide. A separate update workflow, which I run by hand whenever a document changes, splits them by heading into 24 parts and stores them in Supabase (pgvector). It saves the new parts before deleting the old ones, so the bot never answers from an empty knowledge base.
- Fixed rules sort every message first. Greetings, stickers, photos, very long messages and too many messages per hour get a ready-made reply and never reach the AI.
- The AI only suggests. Plain rules decide the final status, and the workflow builds the source line under each answer, so the AI cannot make one up.
- Health questions get a short medical message (call 119 or visit the clinic). Requests for other patients' data are refused.
- If the documents do not cover a question, the patient is pointed to the front desk on WhatsApp and the staff get a Telegram alert with the question.
- Every message is saved to a Google Sheet before the reply is sent. If any step fails, the patient gets a short apology and a third workflow alerts the staff with the name of the step that broke.
The bot is built around the documents, not around this clinic. Swap the Google Docs, run the update workflow, and it answers from the new content. The reply texts, the language, the limits and the matching threshold sit in a Config tab, so the clinic can change them without opening n8n. In this demo the document folder and the sheet are set inside the workflows, so a new setup means pointing those to the new files.
What I Learned
- Letting the AI suggest and letting plain rules decide kept the results predictable. My one Fail came from exactly that boundary. For "who owns the clinic", the AI answered with a category outside its list, and my rules treated that as an error instead of handing the question to the staff. I changed the rule so an unknown category is handed off, and the same question now gets the WhatsApp message and a staff alert.
- The similarity score is only a rough filter. The AI's own "not in the documents" flag does most of the work of deciding when to hand off.
- The order of steps matters. The log row is written before the reply is sent, and new document parts are saved before the old ones are deleted, so a failure never leaves the bot silent or answering from nothing.
Outcome
I wrote 20 test questions with an expected result for each before tuning anything. Every reply was graded Pass, Partial (every fact correct, but a useful detail left out, like "medicines are charged separately") or Fail.
- First run, 20 questions: 13 Pass, 7 Partial, 0 Fail.
- The same 19 questions run three times: 11 to 12 Pass, 7 to 8 Partial, 0 Fail.
- 15 new questions written later: 12 Pass, 2 Partial, 1 Fail (fixed, now passes).
- 6 scenario tests, all passed.
The scenario tests covered what a clinic would actually worry about. I changed the GP price in a document and ran the update, and the bot quoted the new price straight away. Two Telegram accounts asked different questions at the same moment and each got only its own answer, with two separate rows in the log. I renamed the log tab on purpose, and the patient got the apology while the staff alert named the step that failed. A question typed in Indonesian was answered correctly in English, the language set in Config.
In the final demo, answered questions took about 3 to 9 seconds from sending the message to the reply.
Before using something like this for real, keep these in mind:
- The same question can be worded a little differently from one run to the next, which is why I report ranges and not one number.
- Most tests were sent as scripted Telegram messages. The demo conversation in the screenshots and the two-account test were typed in the Telegram app.
- The patient's message goes to OpenAI, and the first name and Telegram chat id are stored in the log sheet. A real clinic would need to tell patients this and decide how long to keep the log.
Tools & Stack