o
    Zh&                     @   s   d dl Z d dlZd dlmZmZ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)ListOptionalSequence)#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   W/var/www/html/lang_env/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-   r0   )r   )clsr,   r1   r2   r/   r0   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_queriesr0   appendaretrieve_documentsunique_unionr   r5   r6   queriesr#   r   r   r   _aget_relevant_documents[   s   

z,MultiQueryRetriever._aget_relevant_documentsr!   c                    sX   | 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: )r-   ainvoke	get_child
isinstancer   r.   loggerinfor   r!   r6   responser   r   r   r   r8   o   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@   rA   N)r,   rD   rE   )r$   r5   r6   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=   r6   Zdocument_listsr   rL   r   r:      s   
z'MultiQueryRetriever.aretrieve_documentsc                C   s2   |  ||}| jr|| | ||}| |S )r7   )generate_queriesr0   r9   retrieve_documentsr;   r<   r   r   r   _get_relevant_documents   s
   

z+MultiQueryRetriever._get_relevant_documentsc                 C   sP   | j jd|id| id}t| j tr|d }n|}| jr&td|  |S )r?   r!   r@   rA   r   rC   )r-   invokerE   rF   r   r.   rG   rH   rI   r   r   r   rQ      s   
z$MultiQueryRetriever.generate_queriesc                 C   s4   g }|D ]}| j j|d| id}|| q|S )rK   r@   rA   )r,   rT   rE   extend)r   r=   r6   r#   r5   rN   r   r   r   rR      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    r0   classmethodDEFAULT_QUERY_PROMPTr   r
   r   r4   r   r   r   r>   r8   r:   r   rS   rQ   rR   r;   r   r   r   r   r+   /   s   
 





r+   )!rO   loggingtypingr   r   r   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   rG   r    r   rY   r*   r+   r   r   r   r   <module>   s(    
	