| | from langchain.prompts import ChatPromptTemplate
|
| | from operator import itemgetter
|
| | from langchain_core.output_parsers import StrOutputParser
|
| | from langchain import hub
|
| | from helper import get_llm, get_retriever
|
| |
|
| | def format_qa_pair(question, answer):
|
| | """Format Q and A pair"""
|
| |
|
| | formatted_string = ""
|
| | formatted_string += f"Question: {question}\nAnswer: {answer}\n\n"
|
| | return formatted_string.strip()
|
| |
|
| |
|
| | def retrieve_and_rag(question,prompt_rag,sub_question_generator_chain, link):
|
| | """RAG on each sub-question"""
|
| |
|
| |
|
| | sub_questions = sub_question_generator_chain.invoke({"question":question})
|
| |
|
| |
|
| | rag_results = []
|
| | retrievar = get_retriever(link)
|
| | llm = get_llm()
|
| | for sub_question in sub_questions:
|
| |
|
| |
|
| | retrieved_docs = retrievar.get_relevant_documents(sub_question)
|
| |
|
| |
|
| | answer = (prompt_rag | llm | StrOutputParser()).invoke({"context": retrieved_docs,
|
| | "question": sub_question})
|
| | rag_results.append(answer)
|
| |
|
| | return rag_results,sub_questions
|
| |
|
| | def get_answer_using_query_decomposition(link: str, question: str):
|
| |
|
| |
|
| | template = """You are a helpful assistant that generates multiple sub-questions related to an input question. \n
|
| | The goal is to break down the input into a set of sub-problems / sub-questions that can be answered in isolation. \n
|
| | Generate multiple search queries related to: {question} \n
|
| | Output (3 queries):"""
|
| | prompt_decomposition = ChatPromptTemplate.from_template(template)
|
| | llm = get_llm()
|
| | generate_queries_decomposition = (
|
| | prompt_decomposition |
|
| | llm |
|
| | StrOutputParser() |
|
| | (lambda x: x.split("\n"))
|
| | )
|
| | questions = generate_queries_decomposition.invoke({"question":question})
|
| | template = """Here is the question you need to answer:
|
| |
|
| | \n --- \n {question} \n --- \n
|
| |
|
| | Here is any available background question + answer pairs:
|
| |
|
| | \n --- \n {q_a_pairs} \n --- \n
|
| |
|
| | Here is additional context relevant to the question:
|
| |
|
| | \n --- \n {context} \n --- \n
|
| |
|
| | Use the above context and any background question + answer pairs to answer the question: \n {question}
|
| | """
|
| |
|
| | decomposition_prompt = ChatPromptTemplate.from_template(template)
|
| |
|
| | q_a_pairs = ""
|
| | retrievar = get_retriever(link)
|
| | answer = ""
|
| | prompt_rag = hub.pull("rlm/rag-prompt")
|
| | for q in questions:
|
| |
|
| | rag_chain = (
|
| | {
|
| | "context": itemgetter("question") | retrievar,
|
| | "question": itemgetter("question"),
|
| | "q_a_pairs": itemgetter("q_a_pairs")
|
| | }
|
| | | decomposition_prompt
|
| | | llm
|
| | | StrOutputParser()
|
| | )
|
| |
|
| | answer = rag_chain.invoke({"question":q,"q_a_pairs":q_a_pairs})
|
| | q_a_pair = format_qa_pair(q,answer)
|
| | q_a_pairs = q_a_pairs + "\n---\n"+ q_a_pair
|
| |
|
| | answers, questions = retrieve_and_rag(question, prompt_rag, generate_queries_decomposition, link)
|
| |
|
| | return answers[0]
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|