Building a Mental Health QA Chatbot Using FalkorDB Knowledge Graph and LlamaIndex

Plaban Nayak
The AI Forum
Published in
8 min readMar 26, 2024

Introduction

A Knowledge Graph converts data into machine-understandable knowledge. But what is the difference between ‘data’ and ‘knowledge’?

Real-world knowledge is:

  • situational: it alters depending on time and circumstances
  • layered: associations between concepts can vary across gender, region, dialect, and more
  • changing: meaning is not fixed; it changes with the discovery of new ideas and associations

In short, knowledge adds the ‘context’ that is often missing from raw data. Traditional data management systems aren’t trained to capture the meaning or relationships in a structured way. Knowledge Graphs (KGs), on the other hand, are built to capture the inherently semantic nature of knowledge, offering a foundation for applications to store new data, definitions, events, situations, or concepts.

Essentially, a knowledge graph is a structured representation of knowledge that captures entities, their properties, and the relationships between them. It is designed to make it easier for applications to understand and reason about the real world.

Knowledge graphs are often used in NLP and other AI applications. By providing applications with a structured representation of knowledge, we can build systems that can better understand the meaning of text.

In summary, a Knowledge Graph is a flexible data layer used for answering complex queries across data silos. They allow connectedness with contextualized data, represented and organized in the form of graphs. An Enterprise Knowledge Graph is simply a Knowledge Graph of enterprise data.

In this article, we will build a healthcare chatbot using OpenAI, the Knowledge Graph FalkorDB, and LlamaIndex. But before we begin, let’s understand why we have chosen a Knowledge Graph to build this RAG instead of a Vector Database.

Why Knowledge Graphs Can Be More Reliable Than Vector Databases

The unpredictable nature of LLMs can lead to hallucinations, posing challenges for businesses looking for accuracy and reliability. Retrieval Augmented Generation (RAG) is an approach that has been used to overcome these challenges, by grounding the LLM. Knowledge Graphs and vector databases are the two principal choices for implementing RAG. But which one offers a more reliable and explainable foundation for your LLM?

Knowledge graphs are increasingly being chosen over vector databases in RAG applications for several reasons. Firstly, Knowledge Graphs have a human-readable representation of data, making them easier to understand and interpret. This is in contrast to vector databases, which operate using vector embeddings, and are, therefore, challenging to understand. Secondly, Knowledge Graphs provide explainable results, as they show the relationships and connections between entities, allowing users to understand the reasoning behind the results. Vector databases, on the other hand, are not as explainable, as they do not provide the same level of transparency into the reasoning behind their results.

In the healthcare domain, especially, explainability of results is vital. By using Knowledge Graphs, we would be able to adjust the data layer that grounds our LLM, and ensure that results have higher accuracy. So, we are going to try and build our chatbot using a Knowledge Graph.

FalkorDB: Super Low Latency Knowledge Graph

FalkorDB, by their own definition, ‘is a blazing fast graph database used for low latency & high throughput scenarios’. It is recognized for its exceptionally low latency and can be run using Docker.

I chose FalkorDB because of the following reasons:

  • Super Low Latency: FalkorDB’s exceptionally low latency is well-suited for applications that require rapid response times.
  • Powerful: FalkorDB employs powerful knowledge graphs by efficiently representing and querying structured data, and capturing relationships and attributes of entities like people, places, events, and products.
  • Combination with LLMs: By integrating Knowledge Graphs with LLMs, FalkorDB capitalizes on the strengths of both.

To learn more about FalkorDB, visit their website.

Code Implementation

Install Required Dependencies

pip install openai
!pip install llama-index
!pip install llama-index-llms-openai
!pip install llama-index-graph-stores-falkordb

Start FalkorDB Locally Using Docker

The easiest way to start FalkorDB as a Graph Database is by using the falkordb docker image. The docker image has the FalkorDB Browser built in, which allows you to visualize graphs.

Launch the image as follows:

docker run -p 6379:6379 -p 3000:3000 -it --rm falkordb/falkordb:latest


/FalkorDB/build/docker/run.sh: 11: [: -eq: unexpected operator
8:C 21 Jan 2024 13:25:35.914 # WARNING Memory overcommit must be enabled! Without it, a background save or replication may fail under low memory conditions. Being disabled, it can also cause failures without low memory condition, see https://github.com/jemalloc/jemalloc/issues/1328. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
8:C 21 Jan 2024 13:25:35.915 * oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
8:C 21 Jan 2024 13:25:35.915 * Redis version=7.2.3, bits=64, commit=00000000, modified=0, pid=8, just started
8:C 21 Jan 2024 13:25:35.915 * Configuration loaded
8:M 21 Jan 2024 13:25:35.915 * monotonic clock: POSIX clock_gettime
_._
_.-``__ ''-._
_.-`` `. `_. ''-._ Redis 7.2.3 (00000000/0) 64 bit
.-`` .-```. ```\/ _.,_ ''-._
( ' , .-` | `, ) Running in standalone mode
|`-._`-...-` __...-.``-._|'` _.-'| Port: 6379
| `-._ `._ / _.-' | PID: 8
`-._ `-._ `-./ _.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' | https://redis.io
`-._ `-._`-.__.-'_.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' |
`-._ `-._`-.__.-'_.-' _.-'
`-._ `-.__.-' _.-'
`-._ _.-'
`-.__.-'

8:M 21 Jan 2024 13:25:35.940 * <graph> Enabled role change notification
8:M 21 Jan 2024 13:25:35.941 * <graph> Starting up FalkorDB version 4.0.3.
8:M 21 Jan 2024 13:25:35.943 * <graph> Thread pool created, using 12 threads.
8:M 21 Jan 2024 13:25:35.943 * <graph> Maximum number of OpenMP threads set to 12
8:M 21 Jan 2024 13:25:35.943 * <graph> Query backlog size: 1000
8:M 21 Jan 2024 13:25:35.943 * Module 'graph' loaded from /FalkorDB/bin/linux-x64-release/src/falkordb.so
8:M 21 Jan 2024 13:25:35.944 * Server initialized
8:M 21 Jan 2024 13:25:35.945 * Ready to accept connections tcp

Instantiate the Knowledge Graph

from llama_index.graph_stores.falkordb import FalkorDBGraphStore
import logging
import sys


logging.basicConfig(stream=sys.stdout, level=logging.INFO)


graph_store = FalkorDBGraphStore(
"redis://localhost:6379", decode_responses=True
)

Download the Data

In this case, we will use a PDF about mental health published by the Australian government. In your case, you can create a much bigger list of documents as the knowledge source as well.

mkdir data
wget "https://www.slhd.nsw.gov.au/mentalhealth/pdf/what_is_mental_illness.pdf" -P "./data"
wget "https://www.hhs.gov/sites/default/files/sg-youth-mental-health-social-media-advisory.pdf" -P "./data"
wget "https://files.eric.ed.gov/fulltext/EJ1154566.pdf" -P "./data"

Import the Required Dependencies

import os
from llama_index.core import Settings
from llama_index.llms.openai import OpenAI
from llama_index.core import StorageContext
from IPython.display import Markdown, display
from llama_index.core import SimpleDirectoryReader, KnowledgeGraphIndex
os.environ["OPENAI_API_KEY"] = "<your OpenAI API key here>"

Read the Data and Process the Documents

documents = SimpleDirectoryReader("./data").load_data()

Convert the Documents into Triplets, and Store FalkorDB

llm = OpenAI(temperature=0, model="gpt-3.5-turbo")
Settings.llm = llm
Settings.chunk_size = 512


storage_context = StorageContext.from_defaults(graph_store=graph_store)


# NOTE: can take a while!
index = KnowledgeGraphIndex.from_documents(
documents,
max_triplets_per_chunk=20,
storage_context=storage_context,

Visualizing the Graph

To visualize the graph, you can simply load up the following url in the browser.

http://localhost:3000.

This will pull up an interface that looks like this:

Note: If you are running your code on a remote machine, you would need to open the 3000 port, and use the following url:

http://[remote_host_ip]:3000

Instantiate the Query Engine

query_engine = index.as_query_engine(
include_text=True, response_mode="tree_summarize", verbose=True
)

Ask a Question

response = query_engine.query(
"What is mental health?",
)
display(Markdown(f"<b>{response}</b>"))

Response Generated

Mental health refers to a person's emotional, psychological, and social well-being. It involves how individuals think, feel, and act, and also helps determine how they handle stress, relate to others, and make choices. Good mental health is essential for overall well-being and can impact various aspects of a person's life.

Installing Gradio UI

!pip install --upgrade gradio

Launch Gradio Chatbot

import gradio as gr


def response_function(message, history):
resp = query_engine.query(message)
resp = f"{resp}"
print(resp)
return resp


gr.ChatInterface(
response_function,
chatbot=gr.Chatbot(height=500),
textbox=gr.Textbox(placeholder="Ask any question related to mental health", container=False, scale=7),
title="Mental Health Chatbot",
description="You can ask this chatbot any question related to mental health",
theme="soft",
examples=["What is mental health?", "What is mental health a challenging topic?", "Where should you go to seek help?"],
cache_examples=True,
retry_btn=None,
undo_btn="Delete Previous",
clear_btn="Clear",
).launch(share=True)

This will launch the Gradio chatbot UI. You will see it in your notebook, and also on a public link that would expire in 72 hours. If you open it in a browser, here’s how this would look:

Let’s test it out with a question. Suppose we ask “What is Mental Health?”.

The response, as you can see, is fairly on point:

“Mental health refers to a person’s emotional, psychological, and social well-being. It involves how individuals think, feel, and act as they cope with life and its challenges. Good mental health contributes to one’s overall well-being and helps in forming positive relationships, making sound decisions, and handling stress effectively.”

Manipulating the Graph

You can manipulate the graph further by adding triplets yourself, without relying on the KnowledgeGraphIndex() function.

Here’s an example of how to do so:

MERGE (depression:MentalIllnessType {name: "Depression"})
MERGE (anxiety:MentalIllnessType {name: "Anxiety"})
MERGE (schizophrenia:MentalIllnessType {name: "Schizophrenia"})
MERGE (bipolar:MentalIllnessType {name: "Bipolar Mood Disorder"})
MERGE (personalityDisorders:MentalIllnessType {name: "Personality Disorders"})
MERGE (eatingDisorders:MentalIllnessType {name: "Eating Disorders"})


MERGE (mi)-[:IS_A_TYPE_OF]->(mhp)


MERGE (mhp)-[:CAN_DEVELOP_INTO]->(mi)


MERGE (depression)-[:IS_A]->(mi)
MERGE (anxiety)-[:IS_A]->(mi)
MERGE (schizophrenia)-[:IS_A]->(mi)
MERGE (bipolar)-[:IS_A]->(mi)
MERGE (personalityDisorders)-[:IS_A]->(mi)
MERGE (eatingDisorders)-[:IS_A]->(mi)


"""
graph_store.query(cypher_query)

Results

Let’s now test the chatbot with a few questions.

You can continue the conversation and ask follow up questions, as below.

As you can see, the answers are fairly accurate and showcase the capabilities of knowledge graph LLMs. You can apply a similar approach to a number of domains.

Conclusion

The incorporation of Knowledge Graph into the RAG pipeline enables us to ground the LLMs. In domains like healthcare, this is vital, as LLM hallucinations can be extremely problematic. In this article, we have demonstrated how to build a simple medical chatbot using a combination of FalkorDB Knowledge Graph, OpenAI and LlamaIndex. We have also shown ways to manipulate the graph, and launch a basic chatbot UI using Gradio. Stay tuned for more such experiments in the future, where we dive deeper into Knowledge Graph manipulation using LLMs.

References

--

--