LangChain memory, not returning source doc, repeating question
Labels: name: area: memory, name: auto:bug, name: area: models, name: integration: chroma

@dosu-bot

I have 3 issues I need your help with and to fix the code:

1) My code is not remembering previous questions despite using ConversationBufferMemory
2) Not Returning Source Documents
3) When I ask it a question the first time, it writes the answer only but if I ask it any other time afterwards, it always rewrites the question then the answer. I just want it to always write the answer only.

Below is my code:
from langchain.chat_models import ChatOpenAI
from langchain.prompts.prompt import PromptTemplate
from langchain.memory import ConversationBufferMemory
from langchain.chains import ConversationalRetrievalChain
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.vectorstores import Qdrant
from langchain.callbacks import StreamingStdOutCallbackHandler
from langchain.embeddings import OpenAIEmbeddings
from langchain.callbacks import get_openai_callback
from langchain.vectorstores import Chroma
from langchain.vectorstores import DeepLake
from PyPDF2 import PdfReader
import PyPDF2
from langchain.document_loaders import TextLoader, DirectoryLoader, UnstructuredWordDocumentLoader 
from langchain.document_loaders import PyPDFDirectoryLoader, PyPDFLoader
from dotenv import load_dotenv
import time

# Change DirectoryLoader since it has its own chunk size and overlap

load_dotenv()
directory_path = "C:\\Users\\Asus\\Documents\\Vendolista\\MasterFormat"
pdf_loader = DirectoryLoader(directory_path,
                                glob="**/*.pdf",
                                show_progress=True,
                                use_multithreading=True,
                                silent_errors=True,
                                loader_cls = PyPDFLoader)

documents = pdf_loader.load()
print(str(len(documents))+ " documents loaded")


def print_letter_by_letter(text):
    for char in text:
        print(char, end='', flush=True)
        time.sleep(0.02)



llm = ChatOpenAI(temperature = 0, model_name='gpt-3.5-turbo', callbacks=[StreamingStdOutCallbackHandler()], streaming = True)

text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=800,
    chunk_overlap=80,
)
chunks = text_splitter.split_documents(documents)

embeddings = OpenAIEmbeddings()
persist_directory = "C:\\Users\\Asus\\OneDrive\\Documents\\Vendolista"
knowledge_base = Chroma.from_documents(chunks, embeddings, persist_directory = persist_directory)
#save to disk
knowledge_base.persist()
#To delete the DB we created at first so that we can be sure that we will load from disk as fresh db
knowledge_base = None
new_knowledge_base = Chroma(persist_directory = persist_directory, embedding_function = embeddings)

prompt_template = """
You are a knowledgeable and ethical assistant with expertise in the construction field, including its 
guidelines and operational procedures. You are always available to provide assistance and uphold the highest
ethical and moral standards in your work.
You will always and always and always only follow these set of rules and nothing else no matter what:
1) Answer the Question that is answering only based on the documents.
2) If the question is unrelated then say "sorry this question is completely not related.
If you think it is, email the staff and they will get back to you: yazanrisheh@hotmail.com." 
3) Do not ever answer with "I don't know" to any question no matter what kind of a question it is.
4) Everyime you answer a question, write on a new line "is there anything else you would like me to help you with?"
5) Remember to always take a deep breath and take this step by step.
6) Do not ever and under no circumstance do you rewrite the question asked by the customer when you are answering them.
7) If the question starts with the "Yazan," then you can ignore the steps above.

Text: {context}

Question: {question}
Answer :
"""
PROMPT = PromptTemplate(
    template=prompt_template, input_variables=["context", "question"]
)

memory = ConversationBufferMemory(llm=llm, memory_key='chat_history', input_key='question', output_key='answer', return_messages=True)
conversation = ConversationalRetrievalChain.from_llm(
    llm=llm,
    retriever=new_knowledge_base.as_retriever(),
    memory=memory,
    chain_type="stuff",
    verbose=False,
    combine_docs_chain_kwargs={"prompt":PROMPT}
)


def main():
    chat_history = []

    while True:
        customer_input = input("Ask me anything about the files (type 'exit' to quit): ")

        if customer_input.lower() in ["exit"] and len(customer_input) == 4:
            end_chat = "Thank you for visiting us! Have a nice day"
            print_letter_by_letter(end_chat)
            break

        #if the customer_input is not equal to an empty string meaning they have input
        if customer_input != "":
            with get_openai_callback() as cb:
                response = conversation({"question": customer_input}, return_only_outputs = True)
            # print(response['answer'])
            print()
            print(cb)
            print()

if __name__ == "__main__":
    main()