ConversationalRetrievalChain error
Labels: name: auto:bug, name: auto:question, name: area: models, name: integration: chroma

Can someone help me fix this code please.

My error: Traceback (most recent call last):
  File "C:\Users\Asus\Documents\Vendolista\app2.py", line 130, in <module>
    main()
  File "C:\Users\Asus\Documents\Vendolista\app2.py", line 99, in main
    qa = ConversationalRetrievalChain.from_llm(
  File "C:\Users\Asus\AppData\Local\Programs\Python\Python310\lib\site-packages\langchain\chains\conversational_retrieval\base.py", line 356, in from_llm
    return cls(
  File "C:\Users\Asus\AppData\Local\Programs\Python\Python310\lib\site-packages\langchain\load\serializable.py", line 75, in __init__
    super().__init__(**kwargs)
  File "pydantic\main.py", line 341, in pydantic.main.BaseModel.__init__
pydantic.error_wrappers.ValidationError: 1 validation error for ConversationalRetrievalChain
retriever
  value is not a valid dict (type=type_error.dict)
PS C:\Users\Asus\Documents\Vendolista> python app2.py
100%|████████████████████████████████████████████████████████████████████████████████████████████████████████| 33/33 [00:02<00:00, 11.17it/s]
87 documents loaded
Traceback (most recent call last):
  File "C:\Users\Asus\Documents\Vendolista\app2.py", line 130, in <module>
    main()
  File "C:\Users\Asus\Documents\Vendolista\app2.py", line 99, in main
    qa = ConversationalRetrievalChain.from_llm(
  File "C:\Users\Asus\AppData\Local\Programs\Python\Python310\lib\site-packages\langchain\chains\conversational_retrieval\base.py", line 356, in from_llm
    return cls(
  File "C:\Users\Asus\AppData\Local\Programs\Python\Python310\lib\site-packages\langchain\load\serializable.py", line 75, in __init__
    super().__init__(**kwargs)
  File "pydantic\main.py", line 341, in pydantic.main.BaseModel.__init__
pydantic.error_wrappers.ValidationError: 1 validation error for ConversationalRetrievalChain
retriever
  value is not a valid dict (type=type_error.dict)


My code:

from dotenv import load_dotenv
import csv
import PyPDF2
from PyPDF2 import PdfReader
from langchain.document_loaders import DirectoryLoader, PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.callbacks import get_openai_callback
from langchain.chat_models import ChatOpenAI
from langchain.chains import ConversationalRetrievalChain
from langchain.memory import ConversationBufferMemory
from langchain.prompts import PromptTemplate
import time
from langchain.vectorstores import Qdrant
from langchain.vectorstores import Chroma
from langchain.vectorstores import deeplake
from langchain.chains.qa_with_sources import load_qa_with_sources_chain
from langchain.callbacks import StreamingStdOutCallbackHandler
import pandas as pd
from docx import Document
from nltk.tokenize import sent_tokenize, word_tokenize
from collections import Counter
from nltk.corpus import stopwords
import os

def print_letter_by_letter(text):
    for char in text:
        print(char, end='', flush=True)
        time.sleep(0.02)

def main():
    load_dotenv()
    my_activeloop_org_id = "yazanrisheh"
    my_activeloop_dataset_name = "langchain_course_customer_support"
    dataset_path = f"hub://{my_activeloop_org_id}/{my_activeloop_dataset_name}"
    # directory_path = input("Copy your directory path here or upload a file: ")
    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=100,
    )
    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)

    # weird_knowledge_base = deeplake(chunks, dataset_path=dataset_path, embedding=embeddings)
    # knowledge_base = Qdrant(documents, embeddings)

    p_template = """Given the following conversation and a follow up question, rephrase the follow up question to be a standalone question, in its original language.
    If the Standalone question is empty or cannot be generated, use the follow up question as Standalone question.
    Chat History:
    {chat_history}
    Follow Up Input: {question}
    Standalone question:"""

    #CONDENSE_QUESTION_PROMPT = PromptTemplate.from_template(_template)
    CONDENSE_QUESTION_PROMPT = PromptTemplate(input_variables=["chat_history","question"],
    template=p_template)
    memory = ConversationBufferMemory(memory_key="chat_history",input_key="question",output_key='answer',return_messages=True)

    chatTemplate = """
    Important: You are an intelligent chatbot designed to help agents by answering questions only on Enterprise services & activities.
    Answer the question only if there is information in the chat history(delimited by ) and context(delimited by ) below.

    If context is not empty and answer cannot be determined from context, say "I cannot detemine the answer from context".
    If you don't know the answer, just say that you don't know, don't try to make up an answer.
    Do not print your answer starting with "Answer:"
    {context} ----------- {chat_history} ----------- Question: {question} Answer: Answer the question only if there is information based on the chat history(delimited by ) and context(delimited by ) below. 1. If context is not empty and answer cannot be determined from context, say "I cannot detemine the answer from context". 2. If you don't know the answer, just say that you don't know, don't try to make up an answer. 3. Do not print your answer starting with "Answer:"
    """

    promptHist = PromptTemplate(
    input_variables=["context", "question", "chat_history"],
    template=chatTemplate
    )

    qa = ConversationalRetrievalChain.from_llm(
    llm = llm,
    retriever = new_knowledge_base,
    condense_question_prompt=CONDENSE_QUESTION_PROMPT,
    verbose=False,
    memory=memory,
    condense_question_llm=llm,
    return_generated_question=True,
    combine_docs_chain_kwargs={"prompt": promptHist},
    return_source_documents=True,
    )

    while True:
        question = input("Ask me anything about the files (type 'exit' to quit): ")

        if question.lower() in ["exit"] and len(question) == 4:
            end_chat = "Thank you for visiting us! Have a nice day"
            print_letter_by_letter(end_chat)
            break

        if question:

            # chat_history = []
            # with get_openai_callback() as cb:
            response = qa({"question": question}, return_only_outputs = True)

            # chat_history.append(('user', question))
            # chat_history.append(('AI', response))
            print("AI:", response)

if __name__ == '__main__':
    main()