o
    Jjg.                     @  sZ  d Z ddlmZ ddlZddlZddlmZ ddlmZm	Z	m
Z
mZ ddlmZ ddlmZmZmZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZmZmZ ddl m!Z! ddl"m#Z# ddl$m%Z% ddl&m'Z' ddl(m)Z) ddl*m+Z+ eddddG dd de!Z,eddddG dd de,Z-eddddG dd de,Z.dS )7Chain for question-answering against a vector database.    )annotationsN)abstractmethod)AnyDictListOptional)
deprecated)AsyncCallbackManagerForChainRunCallbackManagerForChainRun	Callbacks)Document)BaseLanguageModel)PromptTemplate)BaseRetriever)VectorStore)
ConfigDictFieldmodel_validator)Chain)BaseCombineDocumentsChain)StuffDocumentsChain)LLMChainload_qa_chain)PROMPT_SELECTORz0.2.13z1.0zThis class is deprecated. Use the `create_retrieval_chain` constructor instead. See migration guide here: https://python.langchain.com/v0.2/docs/versions/migrating_chains/retrieval_qa/)sinceremovalmessagec                   @  s   e Zd ZU dZded< 	 dZded< dZded< d	Zd
ed< 	 eddddZ	e
d8ddZe
d8ddZe			d9d:d d!Ze	"	d;d<d%d&Zed=d+d,Z	d>d?d0d1Zed@d3d4Z	d>dAd6d7ZdS )BBaseRetrievalQAz)Base class for question-answering chains.r   combine_documents_chainquerystr	input_keyresult
output_keyFboolreturn_source_documentsTforbid)populate_by_namearbitrary_types_allowedextrareturn	List[str]c                 C  s   | j gS )z,Input keys.

        :meta private:
        )r#   self r0   Z/var/www/html/zoom/venv/lib/python3.10/site-packages/langchain/chains/retrieval_qa/base.py
input_keys8   s   zBaseRetrievalQA.input_keysc                 C  s   | j g}| jr|dg }|S )z-Output keys.

        :meta private:
        source_documents)r%   r'   )r/   _output_keysr0   r0   r1   output_keys@   s   
zBaseRetrievalQA.output_keysNllmr   promptOptional[PromptTemplate]	callbacksr   llm_chain_kwargsOptional[dict]kwargsr   c           
      K  sZ   |pt |}td	|||d|pi }tdgdd}t|d||d}	| d	|	|d|S )
zInitialize from LLM.)r6   r7   r9   page_contentzContext:
{page_content})input_variablestemplatecontext)	llm_chaindocument_variable_namedocument_promptr9   )r    r9   Nr0   )r   
get_promptr   r   r   )
clsr6   r7   r9   r:   r<   _promptrA   rC   r    r0   r0   r1   from_llmK   s*   
zBaseRetrievalQA.from_llmstuff
chain_typechain_type_kwargsc                 K  s.   |pi }t |fd|i|}| dd|i|S )zLoad chain from chain type.rI   r    Nr0   r   )rE   r6   rI   rJ   r<   _chain_type_kwargsr    r0   r0   r1   from_chain_typei   s   	zBaseRetrievalQA.from_chain_typequestionrun_managerr   List[Document]c                C     dS z,Get documents to do question answering over.Nr0   r/   rM   rN   r0   r0   r1   	_get_docsx   s    zBaseRetrievalQA._get_docsinputsDict[str, Any]$Optional[CallbackManagerForChainRun]c                 C  sz   |pt  }|| j }dt| jjv }|r| j||d}n| |}| jj|||	 d}| j
r8| j|d|iS | j|iS )h  Run get_relevant_text and llm on input query.

        If chain has 'return_source_documents' as 'True', returns
        the retrieved documents as well under the key 'source_documents'.

        Example:
        .. code-block:: python

        res = indexqa({'query': 'This is my query'})
        answer, docs = res['result'], res['source_documents']
        rN   rN   input_documentsrM   r9   r3   )r   get_noop_managerr#   inspect	signaturerS   
parametersr    run	get_childr'   r%   r/   rT   rN   _run_managerrM   accepts_run_managerdocsanswerr0   r0   r1   _call   s   



zBaseRetrievalQA._callr
   c                  s   dS rQ   r0   rR   r0   r0   r1   
_aget_docs   s    zBaseRetrievalQA._aget_docs)Optional[AsyncCallbackManagerForChainRun]c                   s   |pt  }|| j }dt| jjv }|r"| j||dI dH }n| |I dH }| jj|||	 dI dH }| j
rB| j|d|iS | j|iS )rW   rN   rX   NrY   r3   )r
   r[   r#   r\   r]   rg   r^   r    arunr`   r'   r%   ra   r0   r0   r1   _acall   s   


zBaseRetrievalQA._acall)r,   r-   )NNN)r6   r   r7   r8   r9   r   r:   r;   r<   r   r,   r   )rH   N)
r6   r   rI   r"   rJ   r;   r<   r   r,   r   rM   r"   rN   r   r,   rO   )N)rT   rU   rN   rV   r,   rU   rM   r"   rN   r
   r,   rO   )rT   rU   rN   rh   r,   rU   )__name__
__module____qualname____doc____annotations__r#   r%   r'   r   model_configpropertyr2   r5   classmethodrG   rL   r   rS   rf   rg   rj   r0   r0   r0   r1   r      sD   
 

"r   z0.1.17c                   @  sF   e Zd ZU dZeddZded< dddZdddZe	dddZ
dS )RetrievalQAa  Chain for question-answering against an index.

    This class is deprecated. See below for an example implementation using
    `create_retrieval_chain`:

        .. code-block:: python

            from langchain.chains import create_retrieval_chain
            from langchain.chains.combine_documents import create_stuff_documents_chain
            from langchain_core.prompts import ChatPromptTemplate
            from langchain_openai import ChatOpenAI


            retriever = ...  # Your retriever
            llm = ChatOpenAI()

            system_prompt = (
                "Use the given context to answer the question. "
                "If you don't know the answer, say you don't know. "
                "Use three sentence maximum and keep the answer concise. "
                "Context: {context}"
            )
            prompt = ChatPromptTemplate.from_messages(
                [
                    ("system", system_prompt),
                    ("human", "{input}"),
                ]
            )
            question_answer_chain = create_stuff_documents_chain(llm, prompt)
            chain = create_retrieval_chain(retriever, question_answer_chain)

            chain.invoke({"input": query})

    Example:
        .. code-block:: python

            from langchain_community.llms import OpenAI
            from langchain.chains import RetrievalQA
            from langchain_community.vectorstores import FAISS
            from langchain_core.vectorstores import VectorStoreRetriever
            retriever = VectorStoreRetriever(vectorstore=FAISS(...))
            retrievalQA = RetrievalQA.from_llm(llm=OpenAI(), retriever=retriever)

    T)excluder   	retrieverrM   r"   rN   r   r,   rO   c                C  s   | j j|d| idS )	Get docs.r9   config)rw   invoker`   rR   r0   r0   r1   rS     s   zRetrievalQA._get_docsr
   c                  s    | j j|d| idI dH S )rx   r9   ry   N)rw   ainvoker`   rR   r0   r0   r1   rg     s   zRetrievalQA._aget_docsc                 C  rP   )Return the chain type.retrieval_qar0   r.   r0   r0   r1   _chain_type     zRetrievalQA._chain_typeNrk   rl   r,   r"   )rm   rn   ro   rp   r   rw   rq   rS   rg   rs   r   r0   r0   r0   r1   ru      s   
 
-

ru   c                   @  s   e Zd ZU dZedddZded< 	 dZded< 	 d	Zd
ed< 	 ee	dZ
ded< 	 edded%ddZedded%ddZd&ddZd'd d!Zed(d"d#Zd$S ))
VectorDBQAr   Tvectorstore)rv   aliasr      intk
similarityr"   search_type)default_factoryrU   search_kwargsbefore)modevaluesr   r,   r   c                 C  s   t d |S )NzR`VectorDBQA` is deprecated - please use `from langchain.chains import RetrievalQA`)warningswarn)rE   r   r0   r0   r1   raise_deprecation9  s   zVectorDBQA.raise_deprecationc                 C  s,   d|v r|d }|dvrt d| d|S )zValidate search type.r   )r   mmrsearch_type of  not allowed.)
ValueError)rE   r   r   r0   r0   r1   validate_search_typeB  s
   zVectorDBQA.validate_search_typerM   rN   r   rO   c                C  sf   | j dkr| jj|fd| ji| j}|S | j dkr*| jj|fd| ji| j}|S td| j  d)rx   r   r   r   r   r   )r   r   similarity_searchr   r   max_marginal_relevance_searchr   )r/   rM   rN   rd   r0   r0   r1   rS   L  s&   
	
zVectorDBQA._get_docsr
   c                  s
   t d)rx   z!VectorDBQA does not support async)NotImplementedErrorrR   r0   r0   r1   rg   _  s   zVectorDBQA._aget_docsc                 C  rP   )r}   vector_db_qar0   r.   r0   r0   r1   r   h  r   zVectorDBQA._chain_typeN)r   r   r,   r   rk   rl   r   )rm   rn   ro   rp   r   r   rq   r   r   dictr   r   rt   r   r   rS   rg   rs   r   r0   r0   r0   r1   r   $  s(   
 


	r   )/rp   
__future__r   r\   r   abcr   typingr   r   r   r   langchain_core._apir	   langchain_core.callbacksr
   r   r   langchain_core.documentsr   langchain_core.language_modelsr   langchain_core.promptsr   langchain_core.retrieversr   langchain_core.vectorstoresr   pydanticr   r   r   langchain.chains.baser   'langchain.chains.combine_documents.baser   (langchain.chains.combine_documents.stuffr   langchain.chains.llmr   #langchain.chains.question_answeringr   0langchain.chains.question_answering.stuff_promptr   r   ru   r   r0   r0   r0   r1   <module>   sN    	 (	L	