"""Map-reduce chain.Splits up a document, sends the smaller parts to the LLM with one prompt,then combines the results with another one."""from__future__importannotationsfromtypingimportAny,Dict,List,Mapping,Optionalfromlangchain_core._apiimportdeprecatedfromlangchain_core.callbacksimportCallbackManagerForChainRun,Callbacksfromlangchain_core.documentsimportDocumentfromlangchain_core.language_modelsimportBaseLanguageModelfromlangchain_core.promptsimportBasePromptTemplatefromlangchain_text_splittersimportTextSplitterfrompydanticimportConfigDictfromlangchain.chainsimportReduceDocumentsChainfromlangchain.chains.baseimportChainfromlangchain.chains.combine_documents.baseimportBaseCombineDocumentsChainfromlangchain.chains.combine_documents.map_reduceimportMapReduceDocumentsChainfromlangchain.chains.combine_documents.stuffimportStuffDocumentsChainfromlangchain.chains.llmimportLLMChain
[docs]@deprecated(since="0.2.13",removal="1.0",message=("Refer to migration guide here for a recommended implementation using ""LangGraph: https://python.langchain.com/docs/versions/migrating_chains/map_reduce_chain/"# noqa: E501". See also LangGraph guides for map-reduce: ""https://langchain-ai.github.io/langgraph/how-tos/map-reduce/."),)classMapReduceChain(Chain):"""Map-reduce chain."""combine_documents_chain:BaseCombineDocumentsChain"""Chain to use to combine documents."""text_splitter:TextSplitter"""Text splitter to use."""input_key:str="input_text"#: :meta private:output_key:str="output_text"#: :meta private:
[docs]@classmethoddeffrom_params(cls,llm:BaseLanguageModel,prompt:BasePromptTemplate,text_splitter:TextSplitter,callbacks:Callbacks=None,combine_chain_kwargs:Optional[Mapping[str,Any]]=None,reduce_chain_kwargs:Optional[Mapping[str,Any]]=None,**kwargs:Any,)->MapReduceChain:"""Construct a map-reduce chain that uses the chain for map and reduce."""llm_chain=LLMChain(llm=llm,prompt=prompt,callbacks=callbacks)stuff_chain=StuffDocumentsChain(llm_chain=llm_chain,callbacks=callbacks,**(reduce_chain_kwargsifreduce_chain_kwargselse{}),)reduce_documents_chain=ReduceDocumentsChain(combine_documents_chain=stuff_chain)combine_documents_chain=MapReduceDocumentsChain(llm_chain=llm_chain,reduce_documents_chain=reduce_documents_chain,callbacks=callbacks,**(combine_chain_kwargsifcombine_chain_kwargselse{}),)returncls(combine_documents_chain=combine_documents_chain,text_splitter=text_splitter,callbacks=callbacks,**kwargs,)
model_config=ConfigDict(arbitrary_types_allowed=True,extra="forbid",)@propertydefinput_keys(self)->List[str]:"""Expect input key. :meta private: """return[self.input_key]@propertydefoutput_keys(self)->List[str]:"""Return output key. :meta private: """return[self.output_key]def_call(self,inputs:Dict[str,str],run_manager:Optional[CallbackManagerForChainRun]=None,)->Dict[str,str]:_run_manager=run_managerorCallbackManagerForChainRun.get_noop_manager()# Split the larger text into smaller chunks.doc_text=inputs.pop(self.input_key)texts=self.text_splitter.split_text(doc_text)docs=[Document(page_content=text)fortextintexts]_inputs:Dict[str,Any]={**inputs,self.combine_documents_chain.input_key:docs,}outputs=self.combine_documents_chain.run(_inputs,callbacks=_run_manager.get_child())return{self.output_key:outputs}