karwi
karwi

Reputation: 51

Langchain ConversationalRetrievalChain with prompt template and memory: chat_history

Im trying to create a conversational chatbot with ConversationalRetrievalChain with prompt template and memory and get error:

ValueError: Missing some input keys: {'chat_history'}.

(when calling the chain)

My question though: Why is chat_history needed as input if I have memory as hyperparameter in ConversationalRetrievalChain? I thought that would replace the need for a "manual" chat history?

Upvotes: 0

Views: 1315

Answers (2)

razimbres
razimbres

Reputation: 5005

This works for me:

history=[]

memory = ConversationBufferMemory(
        memory_key='chat_history', return_messages=True, output_key='answer')

store = FAISS.load_local("faiss_index", embeddings)

retriever = store.as_retriever(
    search_type="similarity",  # Also test "similarity", "mmr"
    search_kwargs={"k": 2},)

...
promptTemplate = """" Please answer the user question. You can use the context:

  {context},

  and the chat history: {chat_history} to

  answer the Human question: {question}.
  """
    ...
  messages = [
        SystemMessagePromptTemplate.from_template(promptTemplate),
        HumanMessagePromptTemplate.from_template("{question}")
        ]
  qa_prompt = ChatPromptTemplate.from_messages(messages)

qa_chain = ConversationalRetrievalChain.from_llm(
      code_llm, retriever, memory=memory,get_chat_history=lambda h : h,combine_docs_chain_kwargs={"prompt": qa_prompt})

answer = qa_chain({"question":question,"chat_history":history})#,return_only_outputs=True)
history.append((question, answer))

Note that you must build an index for retrieval, like FAISS. Something like this beforehand:

  trainingData = os.listdir("training/facts/")

  EMBEDDING_QPM = 100
  EMBEDDING_NUM_BATCH = 5
  embeddings = VertexAIEmbeddings(
      requests_per_minute=EMBEDDING_QPM,
      num_instances_per_batch=EMBEDDING_NUM_BATCH,
      model_name = "textembedding-gecko",max_output_tokens=512,
    temperature=0.1,
    top_p=0.8,
    top_k=40
  )

  text_splitter = RecursiveCharacterTextSplitter.from_language(
      language=Language.PYTHON,chunk_size=2000, chunk_overlap=500
  )


  docs=[]
  for training in trainingData:
      with open('training/facts/'+training) as f:
          print(f"Add {f.name} to dataset")
          texts=text_splitter.create_documents([f.read()])
          docs+=texts

  store = FAISS.from_documents(docs, embeddings)

  store.save_local("faiss_index")

Upvotes: 0

knightcool
knightcool

Reputation: 348

ConversationalRetrievalChain uses a default prompt internally to summarize the chat_history and followup question into a new question. The _template variable in site-packages/langchain/chains/conversational_retrieval/prompts.py file is used spcifically which is defined as:

_template = """Given the following conversation and a follow up question, rephrase the follow up question to be a standalone question, in its original language.

Chat History:
{chat_history}
Follow Up Input: {question}
Standalone question:"""
CONDENSE_QUESTION_PROMPT = PromptTemplate.from_template(_template)

So, if you fail to pass in either of those two variables in the input, you will get an error that you saw.

Upvotes: 0

Related Questions