o
    `+ i                     @   s   d dl Z d dlZd dlmZ d dlmZ d dl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 d dlmZ d dlmZ eeZG dd deee  ZedgddZdee
 dee
 fddZ G dd deZ!dS )    N)Sequence)Optional)#AsyncCallbackManagerForRetrieverRunCallbackManagerForRetrieverRun)Document)BaseLanguageModel)BaseOutputParser)BasePromptTemplate)PromptTemplate)BaseRetriever)Runnable)LLMChainc                   @   s&   e Zd ZdZdedee fddZdS )LineListOutputParserz"Output parser for a list of lines.textreturnc                 C   s   |  d}ttd |S )N
)stripsplitlistfilter)selfr   lines r   l/home/app/PaddleOCR-VL-test/.venv_paddleocr/lib/python3.10/site-packages/langchain/retrievers/multi_query.pyparse   s   zLineListOutputParser.parseN)__name__
__module____qualname____doc__strr   r   r   r   r   r   r      s    r   questiona  You are an AI language model assistant. Your task is
    to generate 3 different versions of the given user
    question to retrieve relevant documents from a vector  database.
    By generating multiple perspectives on the user question,
    your goal is to help the user overcome some of the limitations
    of distance-based similarity search. Provide these alternative
    questions separated by newlines. Original question: {question})Zinput_variablestemplate	documentsr   c                    s    fddt  D S )Nc                    s$   g | ]\}}| d | vr|qS )Nr   ).0idocr"   r   r   
<listcomp>-   s   $ z%_unique_documents.<locals>.<listcomp>)	enumerater&   r   r&   r   _unique_documents,   s   r)   c                   @   s:  e Zd ZU dZeed< eed< dZeed< dZ	e
ed< 	 dZeed	< 	 eed
dfdedededee
 d	edd fddZde
dedee fddZde
dedee
 fddZdee
 dedee fddZde
dedee fddZde
dedee
 fddZdee
 dedee fddZd ee dee fd!d"Zd
S )#MultiQueryRetrieverzGiven a query, use an LLM to write a set of queries.

    Retrieve docs for each query. Return the unique union of all retrieved docs.
    	retriever	llm_chainTverboser   
parser_keyFinclude_originalNllmpromptr   c                 C   s    t  }||B |B }| |||dS )a  Initialize from llm using default template.

        Args:
            retriever: retriever to query documents from
            llm: llm for query generation using DEFAULT_QUERY_PROMPT
            prompt: The prompt which aims to generate several different versions
                of the given user query
            include_original: Whether to include the original query in the list of
                generated queries.

        Returns:
            MultiQueryRetriever
        )r+   r,   r/   )r   )clsr+   r0   r1   r.   r/   Zoutput_parserr,   r   r   r   from_llm>   s   zMultiQueryRetriever.from_llmqueryrun_managerc                   s@   |  ||I dH }| jr|| | ||I dH }| |S )Get relevant documents given a user query.

        Args:
            query: user query

        Returns:
            Unique union of relevant documents from all generated queries
        N)agenerate_queriesr/   appendaretrieve_documentsunique_unionr   r4   r5   queriesr"   r   r   r   _aget_relevant_documents\   s   

z,MultiQueryRetriever._aget_relevant_documentsr    c                    sR   | j jd|id| idI dH }t| j tr|d n|}| jr'td| |S )Generate queries based upon user input.

        Args:
            question: user query

        Returns:
            List of LLM generated queries that are similar to the user input
        r    	callbacksconfigNr   Generated queries: %s)r,   ainvoke	get_child
isinstancer   r-   loggerinfor   r    r5   responser   r   r   r   r7   p   s   
z%MultiQueryRetriever.agenerate_queriesr<   c                    s0   t j fdd|D  I dH }dd |D S )Run all LLM generated queries.

        Args:
            queries: query list

        Returns:
            List of retrieved Documents
        c                 3   s(    | ]}j j|d   idV  qdS )r?   r@   N)r+   rC   rD   )r#   r4   r5   r   r   r   	<genexpr>   s    

z:MultiQueryRetriever.aretrieve_documents.<locals>.<genexpr>Nc                 S   s   g | ]	}|D ]}|qqS r   r   )r#   docsr%   r   r   r   r'      s    z;MultiQueryRetriever.aretrieve_documents.<locals>.<listcomp>)asynciogather)r   r<   r5   Zdocument_listsr   rK   r   r9      s   
	z'MultiQueryRetriever.aretrieve_documentsc                C   s2   |  ||}| jr|| | ||}| |S )r6   )generate_queriesr/   r8   retrieve_documentsr:   r;   r   r   r   _get_relevant_documents   s
   

z+MultiQueryRetriever._get_relevant_documentsc                 C   sJ   | j jd|id| id}t| j tr|d n|}| jr#td| |S )r>   r    r?   r@   r   rB   )r,   invokerD   rE   r   r-   rF   rG   rH   r   r   r   rP      s   
z$MultiQueryRetriever.generate_queriesc                 C   s4   g }|D ]}| j j|d| id}|| q|S )rJ   r?   r@   )r+   rS   rD   extend)r   r<   r5   r"   r4   rM   r   r   r   rQ      s   
z&MultiQueryRetriever.retrieve_documentsr"   c                 C   s   t |S )zGet unique Documents.

        Args:
            documents: List of retrieved Documents

        Returns:
            List of unique retrieved Documents
        )r)   )r   r"   r   r   r   r:      s   	z MultiQueryRetriever.unique_union)r   r   r   r   r   __annotations__r   r-   boolr.   r   r/   classmethodDEFAULT_QUERY_PROMPTr   r	   r   r3   r   r   r   r=   r7   r9   r   rR   rP   rQ   r:   r   r   r   r   r*   0   s   
 





r*   )"rN   loggingcollections.abcr   typingr   Zlangchain_core.callbacksr   r   Zlangchain_core.documentsr   Zlangchain_core.language_modelsr   Zlangchain_core.output_parsersr   Zlangchain_core.promptsr	   Zlangchain_core.prompts.promptr
   Zlangchain_core.retrieversr   Zlangchain_core.runnablesr   Zlangchain.chains.llmr   	getLoggerr   rF   r   r   r   rX   r)   r*   r   r   r   r   <module>   s*    
	