The tree index is a tree-structured index, where each node is a summary of
the children nodes. During index construction, the tree is constructed
in a bottoms-up fashion until we end up with a set of root_nodes.
There are a few different options during query time (see :ref:Ref-Query).
The main option is to traverse down the tree from the root nodes.
A secondary answer is to directly synthesize the answer from the root nodes.
classTreeIndex(BaseIndex[IndexGraph]):"""Tree Index. The tree index is a tree-structured index, where each node is a summary of the children nodes. During index construction, the tree is constructed in a bottoms-up fashion until we end up with a set of root_nodes. There are a few different options during query time (see :ref:`Ref-Query`). The main option is to traverse down the tree from the root nodes. A secondary answer is to directly synthesize the answer from the root nodes. Args: summary_template (Optional[BasePromptTemplate]): A Summarization Prompt (see :ref:`Prompt-Templates`). insert_prompt (Optional[BasePromptTemplate]): An Tree Insertion Prompt (see :ref:`Prompt-Templates`). num_children (int): The number of children each node should have. build_tree (bool): Whether to build the tree during index construction. show_progress (bool): Whether to show progress bars. Defaults to False. """index_struct_cls=IndexGraphdef__init__(self,nodes:Optional[Sequence[BaseNode]]=None,objects:Optional[Sequence[IndexNode]]=None,index_struct:Optional[IndexGraph]=None,llm:Optional[LLM]=None,summary_template:Optional[BasePromptTemplate]=None,insert_prompt:Optional[BasePromptTemplate]=None,num_children:int=10,build_tree:bool=True,use_async:bool=False,show_progress:bool=False,**kwargs:Any,)->None:"""Initialize params."""# need to set parameters before building index in base class.self.num_children=num_childrenself.summary_template=summary_templateorDEFAULT_SUMMARY_PROMPTself.insert_prompt:BasePromptTemplate=insert_promptorDEFAULT_INSERT_PROMPTself.build_tree=build_treeself._use_async=use_asyncself._llm=llmorSettings.llmsuper().__init__(nodes=nodes,index_struct=index_struct,show_progress=show_progress,objects=objects,**kwargs,)defas_retriever(self,retriever_mode:Union[str,TreeRetrieverMode]=TreeRetrieverMode.SELECT_LEAF,embed_model:Optional[BaseEmbedding]=None,**kwargs:Any,)->BaseRetriever:# NOTE: lazy importfromllama_index.core.indices.tree.all_leaf_retrieverimport(TreeAllLeafRetriever,)fromllama_index.core.indices.tree.select_leaf_embedding_retrieverimport(TreeSelectLeafEmbeddingRetriever,)fromllama_index.core.indices.tree.select_leaf_retrieverimport(TreeSelectLeafRetriever,)fromllama_index.core.indices.tree.tree_root_retrieverimport(TreeRootRetriever,)self._validate_build_tree_required(TreeRetrieverMode(retriever_mode))ifretriever_mode==TreeRetrieverMode.SELECT_LEAF:returnTreeSelectLeafRetriever(self,object_map=self._object_map,**kwargs)elifretriever_mode==TreeRetrieverMode.SELECT_LEAF_EMBEDDING:embed_model=embed_modelorSettings.embed_modelreturnTreeSelectLeafEmbeddingRetriever(self,embed_model=embed_model,object_map=self._object_map,**kwargs)elifretriever_mode==TreeRetrieverMode.ROOT:returnTreeRootRetriever(self,object_map=self._object_map,**kwargs)elifretriever_mode==TreeRetrieverMode.ALL_LEAF:returnTreeAllLeafRetriever(self,object_map=self._object_map,**kwargs)else:raiseValueError(f"Unknown retriever mode: {retriever_mode}")def_validate_build_tree_required(self,retriever_mode:TreeRetrieverMode)->None:"""Check if index supports modes that require trees."""ifretriever_modeinREQUIRE_TREE_MODESandnotself.build_tree:raiseValueError("Index was constructed without building trees, "f"but retriever mode {retriever_mode} requires trees.")def_build_index_from_nodes(self,nodes:Sequence[BaseNode],**build_kwargs:Any)->IndexGraph:"""Build the index from nodes."""index_builder=GPTTreeIndexBuilder(self.num_children,self.summary_template,llm=self._llm,use_async=self._use_async,show_progress=self._show_progress,docstore=self._docstore,)returnindex_builder.build_from_nodes(nodes,build_tree=self.build_tree)def_insert(self,nodes:Sequence[BaseNode],**insert_kwargs:Any)->None:"""Insert a document."""# TODO: allow to customize insert promptinserter=TreeIndexInserter(self.index_struct,llm=self._llm,num_children=self.num_children,insert_prompt=self.insert_prompt,summary_prompt=self.summary_template,docstore=self._docstore,)inserter.insert(nodes)def_delete_node(self,node_id:str,**delete_kwargs:Any)->None:"""Delete a node."""raiseNotImplementedError("Delete not implemented for tree index.")@propertydefref_doc_info(self)->Dict[str,RefDocInfo]:"""Retrieve a dict mapping of ingested documents and their nodes+metadata."""node_doc_ids=list(self.index_struct.all_nodes.values())nodes=self.docstore.get_nodes(node_doc_ids)all_ref_doc_info={}fornodeinnodes:ref_node=node.source_nodeifnotref_node:continueref_doc_info=self.docstore.get_ref_doc_info(ref_node.node_id)ifnotref_doc_info:continueall_ref_doc_info[ref_node.node_id]=ref_doc_inforeturnall_ref_doc_info