// lab log

A health information chatbot that learns from what it can't answer

I wondered how automated messages were handled, so I built my own: a Python chatbot that answers health questions from a reviewed knowledge base and saves what it can't answer.

3 min read

Why I built it

Honestly, I built this to test myself. I'd always wondered how automated messages were handled, so I did the research and developed my own solution.

I chose health as the subject, but the design isn't tied to it. The same approach could work in many other sectors. Taking it from research to a live bot was fulfilling.

How it answers

The bot doesn't generate its answers. I wrote a list of questions people might ask and mapped each one to an answer. When a message comes in, it goes through three checks:

Message arrives
  -> emergency or suicidal message?  send the priority reply
  -> similar to a known question?    send the mapped answer
  -> otherwise                       point to the menu and save the question

People rarely word a question exactly as I'd written it, so the bot matches on similarity. A message has to pass a similarity threshold before the bot treats it as the intended question and answers.

Where the answers come from

The answers came from reputable sources such as the World Health Organization. Because ordinary replies can only come from the knowledge base, I know what the bot can say to someone.

It provides information, not a diagnosis. Alongside its answers, it makes clear that the person should still see a medical professional.

Emergencies come first

Some messages shouldn't wait for a normal match, so the bot treats them as a priority:

  • Serious emergencies: it tells the person to contact health services, or anyone available, immediately.
  • Suicidal messages: a separately written reply encourages them to talk to someone close to them, such as a friend, and gives them a crisis line to contact.

Learning from what it can't answer

When nothing passes the threshold, the bot says it has nothing on that topic and points the person to its menu. It then saves the question for my review.

I research the answer and add it to the knowledge base, so the next person who asks gets a reply. The knowledge base grows from questions people actually ask.

Keeping user data small

Saved questions hold only the time and the question, with nothing that identifies the sender. I was the only one with access, and they were kept only until I'd updated the knowledge base.

One program, three ways to run it

I originally meant one running copy to serve both WhatsApp and Telegram. I changed that so each copy runs on whichever channel I set: the command line, Telegram or WhatsApp. To cover several platforms, I run several copies.

The command line option also means the bot can be used without connecting to a messaging platform at all.

There's no database. The knowledge base is held in simple structured files, and I compiled the program into a standalone Windows executable with Nuitka. It runs on any Windows computer that has the Visual C++ redistributables installed.

The result

The bot went live. Once it was working, I moved on to my next project.

What I'd do differently

I should have added rate limiting. Saving every unanswered question is what makes the bot improve, but with no limit, someone could flood the review list with junk messages.

← Back to the lab log