
    Ah                     &   S SK r S SKrS SKJr  S SKJr  S SKJrJr  S SK	J
r
  S SKJr  S SKJr  S SKJr  S S	KJr  S S
KJr  S SKJr  S SKJr  \R2                  " \5      r " S S\\\      5      r\" S/SS9rS\\
   S\\
   4S jr  " S S\5      r!g)    N)Sequence)Optional)#AsyncCallbackManagerForRetrieverRunCallbackManagerForRetrieverRun)Document)BaseLanguageModel)BaseOutputParser)BasePromptTemplate)PromptTemplate)BaseRetriever)Runnable)LLMChainc                   0    \ rS rSrSrS\S\\   4S jrSrg)LineListOutputParser   z"Output parser for a list of lines.textreturnc                 j    UR                  5       R                  S5      n[        [        S U5      5      $ )N
)stripsplitlistfilter)selfr   liness      X/var/www/html/shao/venv/lib/python3.13/site-packages/langchain/retrievers/multi_query.pyparseLineListOutputParser.parse   s*    

""4(F4'((     N)	__name__
__module____qualname____firstlineno____doc__strr   r   __static_attributes__r    r   r   r   r      s    ,)# )$s) )r   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                 `    [        U 5       VVs/ sH  u  pX S U ;  d  M  UPM     snn$ s  snnf )N)	enumerate)r+   idocs      r   _unique_documentsr0   ,   s.    '	2O2FAc2A6NC2OOOs   **c                   j   \ rS rSr% Sr\\S'   \\S'   Sr\	\S'   Sr
\\S'    S	r\	\S
'    \\SS	4S\S\S\S\\   S
\	SS 4S jj5       rS\S\S\\   4S jrS\S\S\\   4S jrS\\   S\S\\   4S jrS\S\S\\   4S jrS\S\S\\   4S jrS\\   S\S\\   4S jrS\\   S\\   4S jrSrg)MultiQueryRetriever0   zGiven 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                 4    [        5       nX2-  U-  nU " UUUS9$ )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
)r4   r5   r8   )r   )clsr4   r9   r:   r7   r8   output_parserr5   s           r   from_llmMultiQueryRetriever.from_llm>   s.    , -.L=0	-
 	
r   queryrun_managerc                   #    U R                  X5      I Sh  vN nU R                  (       a  UR                  U5        U R                  X25      I Sh  vN nU R	                  U5      $  NP N7f)Get relevant documents given a user query.

Args:
    query: user query

Returns:
    Unique union of relevant documents from all generated queries
N)agenerate_queriesr8   appendaretrieve_documentsunique_unionr   r@   rA   queriesr+   s        r   _aget_relevant_documents,MultiQueryRetriever._aget_relevant_documents\   s_      ..uBB  NN5!227HH	  ++	 C Is!   A,A(:A,A*A,*A,r(   c                   #    U R                   R                  SU0SUR                  5       0S9I Sh  vN n[        U R                   [        5      (       a  US   OUnU R
                  (       a  [        R                  SU5        U$  NS7f)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)r5   ainvoke	get_child
isinstancer   r6   loggerinfor   r(   rA   responser   s        r   rD   %MultiQueryRetriever.agenerate_queriesp   s|      //"!6!6!89 0 
 
 %/t~~x$H$H h<<KK/7
s   0BBABrI   c                    ^ ^#    [         R                  " UU 4S jU 5       6 I Sh  vN nU VVs/ sH  oD H  oUPM     M     snn$  Ns  snnf 7f)hRun all LLM generated queries.

Args:
    queries: query list

Returns:
    List of retrieved Documents
c              3   v   >#    U H/  nTR                   R                  US TR                  5       0S9v   M1     g7f)rN   rO   N)r4   rR   rS   ).0r@   rA   r   s     r   	<genexpr>:MultiQueryRetriever.aretrieve_documents.<locals>.<genexpr>   sD      
 %E	 &&')>)>)@A '  %s   69N)asynciogather)r   rI   rA   document_listsdocsr/   s   ` `   r   rF   'MultiQueryRetriever.aretrieve_documents   sT       '~~
 % 
 
 !/?$3$??
 @s    "AA	AAAAc                    U R                  X5      nU R                  (       a  UR                  U5        U R                  X25      nU R	                  U5      $ )rC   )generate_queriesr8   rE   retrieve_documentsrG   rH   s        r   _get_relevant_documents+MultiQueryRetriever._get_relevant_documents   sJ     '';  NN5!++GA	  ++r   c                     U R                   R                  SU0SUR                  5       0S9n[        U R                   [        5      (       a  US   OUnU R
                  (       a  [        R                  SU5        U$ )rM   r(   rN   rO   r   rQ   )r5   invokerS   rT   r   r6   rU   rV   rW   s        r   rf   $MultiQueryRetriever.generate_queries   so     >>(("!6!6!89 ) 
 %/t~~x$H$H h<<KK/7r   c                     / nU H>  nU R                   R                  USUR                  5       0S9nUR                  U5        M@     U$ )r[   rN   rO   )r4   rk   rS   extend)r   rI   rA   r+   r@   rc   s         r   rg   &MultiQueryRetriever.retrieve_documents   sX     	E>>((#[%:%:%<= ) D T"  r   r+   c                     [        U5      $ )zyGet unique Documents.

Args:
    documents: List of retrieved Documents

Returns:
    List of unique retrieved Documents
)r0   )r   r+   s     r   rG    MultiQueryRetriever.unique_union   s     !++r   r    )r!   r"   r#   r$   r%   r   __annotations__r   r6   boolr7   r&   r8   classmethodDEFAULT_QUERY_PROMPTr   r
   r   r>   r   r   r   rJ   rD   rF   r   rh   rf   rg   rG   r'   r    r   r   r2   r2   0   s   
 GTJO"d"Q
 &:$(!&
 
 
 #	

 SM
 
 

 
:,, 9	,
 
h,( 9 
c	,@c@ 9@ 
h	@0,, 4	,
 
h,( 4 
c	,c 4 
h	,	,d8n 	,h 	,r   r2   )"r`   loggingcollections.abcr   typingr   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!   rU   r   r&   r   ru   r0   r2   r    r   r   <module>r      s      $  . < : 5 8 3 - )			8	$)+DI6 ) &LF	 P(!3 PX Pw,- w,r   