Repetitive answer and not getting source of documents
Labels: name: area: memory, name: auto:bug, name: auto:question, name: area: models, name: integration: chroma

@dosu-bot 

Below is my code in python about creating a Q & A using Langchain with openai API. I have 3 issues I want to fix:

1) The answer is always being repeated twice.
2) I am using ConversationalRetrievalChain from LangChain therefore, I want to retrieve the source of the document when I get my answer.
3) I want to change the chain_type = "stuff" into Map Re Rank.



from langchain.chat_models import ChatOpenAI
from langchain.prompts.prompt import PromptTemplate
from langchain.memory import ConversationBufferMemory
from langchain.chains import ConversationalRetrievalChain
from langchain.document_loaders import WebBaseLoader
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.document_loaders import DirectoryLoader, PyPDFLoader
from dotenv import load_dotenv
import time
import warnings
# warnings.filterwarnings("ignore")

load_dotenv()
def print_letter_by_letter(text):
    for char in text:
        print(char, end='', flush=True)
        time.sleep(0.02)

# Create embeddings
def langchain(customer_prompt, chat_history):

    directory_path = "C:\\Users\\Asus\\Documents\\Vendolista"

    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")

    llm = ChatOpenAI(temperature = 0, model_name='gpt-3.5-turbo', callbacks=[StreamingStdOutCallbackHandler()], streaming = True)


    # Split into chunks
    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)


    # Create a custom prompt for your use case
    prompt_template = """
    Answer the Question as a AI assistant that is answering based on the documents only. 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." Do not ever answer with "I don't know" to any question.
    You either give an answer or mention it's not related.

    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",
        combine_docs_chain_kwargs={"prompt":PROMPT}
    )

    return conversation({"question": customer_prompt, "chat_history": memory})

def main():
    chat_history = []


    while True:
        customer_prompt = input("Ask me anything about the files (type 'exit' to quit): ")

        if customer_prompt.lower() in ["exit"] and len(customer_prompt) == 4:
            end_chat = "Thank you for visiting us! Have a nice day"
            print_letter_by_letter(end_chat)
            break

        if customer_prompt:
            with get_openai_callback() as cb:
                response = langchain(customer_prompt, chat_history)
            print(response['answer'])
            print(cb)

if __name__ == "__main__":
    main()