Retrieval Augmented Generation(RAG) FAQ Generator on your docs.

Dwarakanath Rao
4 min readFeb 14, 2024

--

Retrieval Augmented Generation(RAG) FAQ Generator on your docs.

Implement the RAG technique using Langchain, and Local LLM

Here is a simple RAG application using any LLM of your choice to provide AI sovereignty, provide data locally.

Here is a simple Stream lit program using any LLM you want( Mixtral, zephyr-7B, etc ) installed locally or you can run it on Ollama or power it on a server which is served as API.

The code does the following

Asks LLM to be a question generator and grab important questions that you seek.

Connects to Local LLM and Vector locally or hugging face based on where you want to host them.

At the end it generates FAQ and stores it locally in CVS files.

Use case.

For Students to generate important Q for exams.

For teachers to generate FAQ on topics that they want to ask Q to students

For normal book or blog reader, who want to get key information.

Las but not the least reading contract and getting important details which are listed.

Here is the code and requirement first.

Code to work with your LLM

import streamlit as st

import tempfile

from langchain.text_splitter import RecursiveCharacterTextSplitter

from langchain.document_loaders import PyPDFLoader

from langchain.docstore.document import Document

from langchain.chains.summarize import load_summarize_chain

from langchain.chains import RetrievalQA

from langchain.embeddings import HuggingFaceEmbeddings

from langchain.vectorstores import Chroma

from langchain.llms import LlamaCpp

from langchain.prompts import PromptTemplate

import os

import pandas as pd

prompt_template_questions = “””

You are an expert in creating Frequently Asked Questions Based on the material you are provided.

Your goal is to prepare or generate a important questions for quicker and better understanding of the Topic. You do this by asking questions about the text below:

— — — — — —

{text}

— — — — — —

Create questions that will prepare the reader for their important exam or conversation, study courses or for important topics. Make sure not to lose any important information.

QUESTIONS:

“””

PROMPT_QUESTIONS = PromptTemplate(template=prompt_template_questions, input_variables=[“text”])

refine_template_questions = “””

You are an expert in creating Frequently asked questions based on material.

Your goal is to prepare or generate a important questions for quicker and better understanding of the Topic.

We have received some practice questions to a certain extent: {existing_answer}.

We have the option to refine the existing questions or add new ones.

(only if necessary) with some more context below.

— — — — — —

{text}

— — — — — —

Given the new context, refine the original questions in English.

If the context is not helpful, please provide the original questions.

QUESTIONS:

“””

REFINE_PROMPT_QUESTIONS = PromptTemplate(

input_variables=[“existing_answer”, “text”],

template=refine_template_questions,

)

# Initialize Streamlit app

st.title(‘Frequently asked Questions and answer Generator with your Local LLM of your choice’)

st.markdown(‘<style>h1{color: blue; text-align: left;}</style>’, unsafe_allow_html=True)

# File upload widget

uploaded_file = st.sidebar.file_uploader(“Upload the document of your choice, please select only PDF file”, type=[“pdf”])

# Set file path

file_path = None

# Check if a file is uploaded

if uploaded_file:

# Save the uploaded file to a temporary location

with tempfile.NamedTemporaryFile(delete=False, suffix=”.pdf”) as temp_file:

temp_file.write(uploaded_file.read())

file_path = temp_file.name

# Check if file_path is set

if file_path:

# Load data from the uploaded PDF

loader = PyPDFLoader(file_path)

data = loader.load()

# Combine text from Document into one string for question generation

text_question_gen = ‘’

for page in data:

text_question_gen += page.page_content

# Initialize Text Splitter for question generation

text_splitter_question_gen = RecursiveCharacterTextSplitter(chunk_size=50000, chunk_overlap=1000)

# Split text into chunks for question generation

text_chunks_question_gen = text_splitter_question_gen.split_text(text_question_gen)

# Convert chunks into Documents for question generation

docs_question_gen = [Document(page_content=t) for t in text_chunks_question_gen]

# Initialize Large Language Model for question generation

llm_question_gen = LlamaCpp(

streaming = True,

model_path=”/Users/dwarakaprao/.cache/lm-studio/models/TheBloke/zephyr-7B-beta-GGUF/zephyr-7b-beta.Q4_0.gguf”,

temperature=0.50,

top_p=1,

verbose=True,

n_ctx=4096

)

# Initialize question generation chain

question_gen_chain = load_summarize_chain(llm=llm_question_gen, chain_type=”refine”, verbose=True,

question_prompt=PROMPT_QUESTIONS, refine_prompt=REFINE_PROMPT_QUESTIONS)

# Run question generation chain

questions = question_gen_chain.run(docs_question_gen)

# Initialize Large Language Model for answer generation

llm_answer_gen = LlamaCpp(

streaming = True,

model_path=”/Users/dwarakaprao/.cache/lm-studio/models/TheBloke/zephyr-7B-beta-GGUF/zephyr-7b-beta.Q4_0.gguf”,

temperature=0.50,

top_p=1,

verbose=True,

n_ctx=4096)

# Create vector database for answer generation

embeddings = HuggingFaceEmbeddings(model_name=”sentence-transformers/all-MiniLM-L6-v2", model_kwargs={“device”: “cpu”})

# Initialize vector store for answer generation

vector_store = Chroma.from_documents(docs_question_gen, embeddings)

# Initialize retrieval chain for answer generation

answer_gen_chain = RetrievalQA.from_chain_type(llm=llm_answer_gen, chain_type=”stuff”,

retriever=vector_store.as_retriever(k=2))

# Split generated questions into a list of questions

question_list = questions.split(“\n”)

# Answer each question and save to a file

question_answer_pairs = []

for question in question_list:

st.write(“Question: “, question)

answer = answer_gen_chain.run(question)

question_answer_pairs.append([question, answer])

st.write(“Answer: “, answer)

st.write(“ — — — — — — — — — — — — — — — — — — — — — — — — — \n\n”)

# Create a directory for storing answers

answers_dir = os.path.join(tempfile.gettempdir(), “answers”)

os.makedirs(answers_dir, exist_ok=True)

# Create a DataFrame from the list of question-answer pairs

qa_df = pd.DataFrame(question_answer_pairs, columns=[“Question”, “Answer”])

# Save the DataFrame to a CSV file

csv_file_path = os.path.join(answers_dir, “questions_and_answers.csv”)

qa_df.to_csv(csv_file_path, index=False)

# Create a download button for the questions and answers CSV file

st.markdown(‘### Download Questions and Answers in CSV’)

st.download_button(“Download Questions and Answers (CSV)”, csv_file_path)

# Cleanup temporary files

if file_path:

os.remove(file_path)

Final out put

--

--

No responses yet