o
    粪g&                     @   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   \/var/www/html/chatdoc2/venv/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})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.   r1   )r   )clsr-   r2   r3   r0   r1   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_queriesr1   appendaretrieve_documentsunique_unionr   r7   r8   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!   r8   responser   r   r   r   r:   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 )rB   rC   N)r-   rF   rG   )r%   r7   r8   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?   r8   document_listsr   rN   r   r<      s   
z'MultiQueryRetriever.aretrieve_documentsc                C   s2   |  ||}| jr|| | ||}| |S )r9   )generate_queriesr1   r;   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 )rA   r!   rB   rC   r   rE   )r.   invokerG   rH   r   r/   rI   rJ   rK   r   r   r   rT      s   
z$MultiQueryRetriever.generate_queriesc                 C   s4   g }|D ]}| j j|d| id}|| q|S )rM   rB   rC   )r-   rW   rG   extend)r   r?   r8   r$   r7   rP   r   r   r   rU      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/   boolr0   r    r1   classmethodDEFAULT_QUERY_PROMPTr   r
   r   r6   r   r   r   r@   r:   r<   r   rV   rT   rU   r=   r   r   r   r   r,   /   s   
 





r,   )!rQ   loggingtypingr   r   r   langchain_core.callbacksr   r   langchain_core.documentsr   langchain_core.language_modelsr   langchain_core.output_parsersr	   langchain_core.promptsr
   langchain_core.prompts.promptr   langchain_core.retrieversr   langchain_core.runnablesr   langchain.chains.llmr   	getLoggerr   rI   r    r   r\   r+   r,   r   r   r   r   <module>   s(    
	