o
    `+ i.                     @  sJ  d Z ddlmZ ddlZddlmZ ddl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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/docs/versions/migrating_chains/retrieval_qa/)ZsinceZ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_documentsTZforbid)Zpopulate_by_nameZarbitrary_types_allowedextrareturn	list[str]c                 C  s   | j gS )z,Input keys.

        :meta private:
        )r   self r)   n/home/app/PaddleOCR-VL-test/.venv_paddleocr/lib/python3.10/site-packages/langchain/chains/retrieval_qa/base.py
input_keys7   s   zBaseRetrievalQA.input_keysc                 C  s   | j g}| jrg |d}|S )z-Output keys.

        :meta private:
        source_documents)r!   r#   )r(   Z_output_keysr)   r)   r*   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.)r.   r/   r1   Zpage_contentzContext:
{page_content})Zinput_variablestemplatecontext)	llm_chainZdocument_variable_namedocument_promptr1   )r   r1   Nr)   )r   Z
get_promptr   r   r   )
clsr.   r/   r1   r2   r4   Z_promptr7   r8   r   r)   r)   r*   from_llmJ   s0   
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.r<   r   Nr)   r   )r9   r.   r<   r=   r4   Z_chain_type_kwargsr   r)   r)   r*   from_chain_typel   s   	zBaseRetrievalQA.from_chain_typequestionrun_managerr	   list[Document]c                C     dS z,Get documents to do question answering over.Nr)   r(   r?   r@   r)   r)   r*   	_get_docs}   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']
        r@   r@   Zinput_documentsr?   r1   r,   )r	   get_noop_managerr   inspect	signaturerE   
parametersr   run	get_childr#   r!   r(   rF   r@   Z_run_managerr?   Zaccepts_run_managerdocsZanswerr)   r)   r*   _call   s   


zBaseRetrievalQA._callr   c                  s   dS rC   r)   rD   r)   r)   r*   
_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 )rI   r@   rJ   NrK   r,   )r   rL   r   rM   rN   rU   rO   r   ZarunrQ   r#   r!   rR   r)   r)   r*   _acall   s    

zBaseRetrievalQA._acall)r%   r&   )NNN)r.   r   r/   r0   r1   r
   r2   r3   r4   r   r%   r   )r;   N)
r.   r   r<   r   r=   r3   r4   r   r%   r   r?   r   r@   r	   r%   rA   )N)rF   rG   r@   rH   r%   rG   r?   r   r@   r   r%   rA   )rF   rG   r@   rV   r%   rG   )__name__
__module____qualname____doc____annotations__r   r!   r#   r   Zmodel_configpropertyr+   r-   classmethodr:   r>   r   rE   rT   rU   rW   r)   r)   r)   r*   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   	retrieverr?   r   r@   r	   r%   rA   c                C  s   | j j|d| idS )	Get docs.r1   config)rc   ZinvokerQ   rD   r)   r)   r*   rE     s   
zRetrievalQA._get_docsr   c                  s    | j j|d| idI dH S )rd   r1   re   N)rc   ZainvokerQ   rD   r)   r)   r*   rU     s
   
zRetrievalQA._aget_docsc                 C  rB   )Return the chain type.Zretrieval_qar)   r'   r)   r)   r*   _chain_type'     zRetrievalQA._chain_typeNrX   rY   r%   r   )rZ   r[   r\   r]   r   rc   r^   rE   rU   r_   rh   r)   r)   r)   r*   ra      s   
 
-

ra   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d$ddZd%ddZed&d d!Zd"S )'
VectorDBQAr   Tvectorstore)rb   aliasr      intk
similarityr   search_type)default_factoryrG   search_kwargsbefore)modevaluesdictr%   r   c                 C  s0   d|v r|d }|dvrd| d}t ||S )zValidate search type.rr   )rq   mmrsearch_type of  not allowed.)
ValueError)r9   rw   rr   msgr)   r)   r*   validate_search_typeB  s   zVectorDBQA.validate_search_typer?   r@   r	   rA   c                C  sj   | j dkr| jj|fd| ji| j}|S | j dkr*| jj|fd| ji| j}|S d| j  d}t|)rd   rq   rp   ry   rz   r{   )rr   rl   Zsimilarity_searchrp   rt   Zmax_marginal_relevance_searchr|   )r(   r?   r@   rS   r}   r)   r)   r*   rE   M  s(   

zVectorDBQA._get_docsr   c                  s   d}t |)rd   z!VectorDBQA does not support async)NotImplementedError)r(   r?   r@   r}   r)   r)   r*   rU   e  s   zVectorDBQA._aget_docsc                 C  rB   )rg   Zvector_db_qar)   r'   r)   r)   r*   rh   o  ri   zVectorDBQA._chain_typeN)rw   rx   r%   r   rX   rY   rj   )rZ   r[   r\   r]   r   rl   r^   rp   rr   rx   rt   r   r`   r~   rE   rU   r_   rh   r)   r)   r)   r*   rk   -  s"   
 

	

rk   ),r]   
__future__r   rM   abcr   typingr   r   Zlangchain_core._apir   Zlangchain_core.callbacksr   r	   r
   Zlangchain_core.documentsr   Zlangchain_core.language_modelsr   Zlangchain_core.promptsr   Zlangchain_core.retrieversr   Zlangchain_core.vectorstoresr   Zpydanticr   r   r   Zlangchain.chains.baser   Z'langchain.chains.combine_documents.baser   Z(langchain.chains.combine_documents.stuffr   Zlangchain.chains.llmr   Z#langchain.chains.question_answeringr   Z0langchain.chains.question_answering.stuff_promptr   r   ra   rk   r)   r)   r)   r*   <module>   sL    	 0	N	