Conditional generation is a way of training a language model to understand the context of a document and generate answers to questions about it. We will take the following steps to build the chatbot:
- Create a corpus from the document.
- Match the user's question to the relavant passages in the corpus.
- Create a prompt that includes the context of the question.
- Send the prompt to GPT-3 to generate an answer.
- Create a function that combines steps 2-4.
- Test the chatbot by creating a question-answer loop.
- Use Gradio to create an interface for the chatbot.
Create a corpus from the documentFirst we have prepared a file HKIHRMEmployeeHandbook.txt which is text version of a sample employee handbook created by Hong Kong Institute of Human Resource Management.
To start, we are using a python library called "sentence-transformers" to create a corpus of embeddings from the text document "HKIHRMEmployeeHandbook.txt". The sentence-transformers library is an NLP library that makes use of pre-trained transformer-based models, like BERT, RoBERTa, DistilBERT, and, in this case, multi-qa-mpnet-base-cos-v1, to generate embeddings for each sentence in the corpus. This is useful for our chatbot application as it allows us to find the most relevant passage in our document for the user's query. This will help to provide more accurate and useful answers for the user.Embeddings are a way to represent text in a numerical form that can be used for comparison and similarity calculation by the model. In this case, we are using sentence-transformers library to convert the text into embeddings. These embeddings are a compact and dense representation of the text, which can be used to compare and measure similarity between different texts.
- Semantic Similarity: Embeddings capture the semantic similarity between sentences, which allows for more accurate and relevant matches between the user's query and the passages in the corpus.
- Handling synonyms and variations: Embeddings can handle synonyms and variations in the query, which are difficult to handle with traditional keyword search. For example, if the user asks "what are the benefits of working overtime?" and the document talks about "compensation for working beyond regular hours", the embeddings will be able to match the query with the relevant passage, even though the words in the query and document are different.
- Handling context: Embeddings can also capture the context in which a word is used, which allows for more accurate matches between the query and the passages in the corpus. For example, "what are the benefits of working overtime?" and "what are the drawbacks of working overtime?" have similar keywords but opposite meaning, embeddings can help to understand the context and give the correct answer.
- Scalability: Embeddings can handle large datasets and can be used to match queries against a large corpus of documents efficiently.
Match the user's question to the relavant passages in the corpusOnce we have the embeddings, we can find the most similar passages in the document to the given query. The
util.semantic_searchmethod to find the most similar passages in the corpus based on the query embedding and the corpus embeddings. The
top_kvariable controls how many passages to retrieve. After getting the passages from the corpus, they are joined as a whole piece together with linebreak to form the context. The result is as follows: You can observed that all passages retrieved are more or less relavant to the overtime question.
Create a prompt that includes the context of the questionThen, we can creating a prompt template. The prompt will be created and send for GPT-3 to generate an answer for the query based on the context. The following prompt will be created You can try a few other forms like:
- Answer the following question. If the answer cannot be found in the context, write "I don't know"
- Answer the following question. If the answer cannot be found in the context, rewrite the question that is more related to the context by starting with "Do you want to ask" and then elaborate the answer
Send the prompt to GPT-3 to generate an answerThe following code is using the OpenAI API to generate a response for the prompt using GPT-3. GPT-3 will come up with an answer that fits the context:
Create a function that wraps up everythingWrapping the code into a function called
answer(query)allows for easy reuse of the code and inputting of different queries. This function takes in a query string, and return the response of the API. This makes it easy to input different queries and get an answer without having to repeat the previous steps every time.
Test the chatbot by creating a question-answer loopHere, we have an infinite loop that repeatedly prompts the user for a query, and exits the loop when the user enters "xxx". You can input multiple queries and get answers without having to restart the code. It allows easy testing of the function by allowing the user to input different queries and see the answers generated by GPT-3. The output will be as follows:
Use Gradio to create an interface for the chatbotFinally, let's use gradio library to create a (GUI) for the
answer(query)function defined earlier: Now you have a more user friendly GUI to ask the questions: