案例目标本案例演示了如何使用RouterRetriever构建一个智能路由系统该系统能够根据查询内容动态选择最适合的检索器。智能路由选择根据查询类型和内容自动选择最合适的检索器多检索器集成集成多种不同类型的检索器包括列表检索器、向量检索器和关键词检索器单选与多选模式支持单选器(PydanticSingleSelector)和多选器(PydanticMultiSelector)两种模式基于LLM的决策利用大语言模型的推理能力进行检索器选择通过路由检索器我们可以构建更加灵活和智能的检索系统能够根据不同的查询需求动态选择最适合的检索策略从而提高检索效率和准确性。技术栈与核心依赖核心库llama-index-llms-openaillama-index路由与选择RouterRetrieverPydanticSingleSelectorPydanticMultiSelectorLLMSingleSelectorLLMMultiSelector检索器与索引RetrieverToolVectorStoreIndexSummaryIndexSimpleKeywordTableIndexSentenceSplitter环境配置安装依赖%pip install llama-index-llms-openai !pip install llama-index环境设置# NOTE: This is ONLY necessary in jupyter notebook. import nest_asyncio nest_asyncio.apply() import logging import sys logging.basicConfig(streamsys.stdout, levellogging.INFO) logging.getLogger().handlers [] logging.getLogger().addHandler(logging.StreamHandler(streamsys.stdout))注意需要设置有效的OpenAI API密钥才能运行此示例。此外在Jupyter notebook中运行需要使用nest_asyncio来处理嵌套事件循环。案例实现1. 数据准备与索引构建下载Paul Graham的文章并创建三种不同类型的索引# 下载数据 !mkdir -p data/paul_graham/ !wget https://raw.githubusercontent.com/run-llama/llama_index/main/docs/examples/data/paul_graham/paul_graham_essay.txt -O data/paul_graham/paul_graham_essay.txt # 加载文档 documents SimpleDirectoryReader(./data/paul_graham/).load_data() # 初始化LLM和分割器 llm OpenAI(modelgpt-4) splitter SentenceSplitter(chunk_size1024) nodes splitter.get_nodes_from_documents(documents) # 初始化存储上下文 storage_context StorageContext.from_defaults() storage_context.docstore.add_documents(nodes) # 创建三种不同类型的索引 summary_index SummaryIndex(nodes, storage_contextstorage_context) vector_index VectorStoreIndex(nodes, storage_contextstorage_context) keyword_index SimpleKeywordTableIndex(nodes, storage_contextstorage_context)2. 创建检索器工具为每种索引创建对应的检索器并将其包装为RetrieverTool# 创建检索器 list_retriever summary_index.as_retriever() vector_retriever vector_index.as_retriever() keyword_retriever keyword_index.as_retriever() # 创建检索器工具 from llama_index.core.tools import RetrieverTool list_tool RetrieverTool.from_defaults( retrieverlist_retriever, description( Will retrieve all context from Paul Grahams essay on What I Worked On. Dont use if the question only requires more specific context. ), ) vector_tool RetrieverTool.from_defaults( retrievervector_retriever, description( Useful for retrieving specific context from Paul Graham essay on What I Worked On. ), ) keyword_tool RetrieverTool.from_defaults( retrieverkeyword_retriever, description( Useful for retrieving specific context from Paul Graham essay on What I Worked On (using entities mentioned in query) ), )3. 单选路由检索器实现使用PydanticSingleSelector创建单选路由检索器每次只选择一个最佳检索器from llama_index.core.selectors import ( PydanticMultiSelector, PydanticSingleSelector, ) from llama_index.core.retrievers import RouterRetriever # 创建单选路由检索器 retriever RouterRetriever( selectorPydanticSingleSelector.from_defaults(llmllm), retriever_tools[ list_tool, vector_tool, ], )PydanticSingleSelector使用OpenAI的Function Call API来生成结构化的选择对象而不是解析原始JSON。这种方式更加可靠目前支持gpt-4-0613和gpt-3.5-turbo-0613模型。4. 单选路由检索器查询示例执行两种不同类型的查询观察路由检索器的选择行为# 查询1获取作者生活的所有上下文 nodes retriever.retrieve( Can you give me all the context regarding the authors life? ) # 输出Selecting retriever 0: This choice is most relevant as it mentions retrieving all context from the essay... # 查询2获取特定细节 nodes retriever.retrieve(What did Paul Graham do after RISD?) # 输出Selecting retriever 1: The question asks for a specific detail from Paul Grahams essay...观察结果对于第一个查询路由器选择了列表检索器(list_tool)因为查询要求获取所有上下文对于第二个查询路由器选择了向量检索器(vector_tool)因为查询要求获取特定细节。5. 多选路由检索器实现使用PydanticMultiSelector创建多选路由检索器可以选择多个检索器# 创建多选路由检索器 retriever RouterRetriever( selectorPydanticMultiSelector.from_defaults(llmllm), retriever_tools[list_tool, vector_tool, keyword_tool], )PydanticMultiSelector可以选择多个检索器来处理查询这对于需要从多个角度检索信息的复杂查询特别有用。6. 多选路由检索器查询示例执行包含多个实体的查询观察多选路由检索器的选择行为# 查询包含多个实体的复杂查询 nodes retriever.retrieve( What were noteable events from the authors time at Interleaf and YC? ) # 输出 # Selecting retriever 1: This choice is relevant as it allows for retrieving specific context... # Selecting retriever 2: This choice is also relevant as it allows for retrieving specific context using entities... # query keywords: [interleaf, events, noteable, yc] # Extracted keywords: [interleaf, yc]观察结果对于包含多个实体(Interleaf和YC)的查询多选路由器同时选择了向量检索器和关键词检索器并提取了查询中的关键词进行进一步处理。案例效果我们比较了单选和多选路由检索器在不同类型查询下的表现单选路由检索器查询1Can you give me all the context regarding the authors life?选择列表检索器(list_tool)结果返回文档中的所有节点适合获取全面信息查询2What did Paul Graham do after RISD?选择向量检索器(vector_tool)结果返回与查询最相关的节点相似度0.80-0.79多选路由检索器查询What were noteable events from the authors time at Interleaf and YC?选择向量检索器 关键词检索器关键词提取[interleaf, yc]结果结合语义搜索和关键词匹配返回更全面的相关节点结论路由检索器能够根据查询内容和类型智能选择最适合的检索器。单选模式适合简单查询多选模式适合包含多个实体或需要多角度检索的复杂查询。通过LLM的推理能力路由检索器能够理解查询意图并做出合理的选择决策。路由决策示例# 单选路由决策示例 Selecting retriever 0: This choice is most relevant as it mentions retrieving all context from the essay, which could include information about the authors life. Selecting retriever 1: The question asks for a specific detail from Paul Grahams essay on What I Worked On. Therefore, the second choice, which is useful for retrieving specific context, is the most relevant. # 多选路由决策示例 Selecting retriever 1: This choice is relevant as it allows for retrieving specific context from the essay, which is needed to answer the question about notable events at Interleaf and YC. Selecting retriever 2: This choice is also relevant as it allows for retrieving specific context using entities mentioned in the query, which in this case are Interleaf and YC.案例实现思路路由检索器工作流程步骤1检索器工具创建为每种检索器创建RetrieverTool对象包含检索器实例和描述信息。描述信息对于路由器选择合适的检索器至关重要它提供了关于每个检索器功能和适用场景的详细信息。步骤2选择器初始化根据需求选择合适的选择器(PydanticSingleSelector或PydanticMultiSelector)并配置LLM模型。选择器负责分析查询内容并决定使用哪些检索器。步骤3路由检索器构建将选择器和检索器工具列表传递给RouterRetriever创建完整的路由检索系统。路由检索器封装了选择逻辑和检索器调用。步骤4查询处理与路由决策当收到查询时选择器使用LLM分析查询内容和意图根据检索器工具的描述信息选择最合适的检索器。对于多选模式可能会选择多个检索器。步骤5检索执行与结果返回路由检索器调用选定的检索器执行查询收集检索结果并返回。对于多选模式可能会合并多个检索器的结果。Pydantic选择器与LLM选择器的区别Pydantic选择器• 使用OpenAI Function Call API• 生成结构化的Pydantic对象• 更可靠减少解析错误• 仅支持特定模型(gpt-4-0613, gpt-3.5-turbo-0613)LLM选择器• 生成原始JSON响应• 需要解析JSON文本• 兼容更多模型• 可能出现解析错误扩展建议1. 自定义选择器实现实现自定义选择器基于查询特征(如长度、关键词、实体等)使用规则或机器学习模型进行检索器选择减少对LLM的依赖。2. 动态检索器权重调整在多选模式下根据查询类型和检索器历史性能动态调整不同检索器的权重优化结果融合效果。3. 检索器性能监控实现检索器性能监控系统记录不同类型查询下各检索器的表现为选择器优化提供数据支持。4. 分层路由系统构建多级路由系统第一级选择检索器类别第二级选择具体检索器支持更复杂的检索场景。5. 查询意图分类集成查询意图分类模块将查询分为事实查询、概念查询、比较查询等类型为路由决策提供更精确的依据。6. 检索器协同机制设计检索器之间的协同机制允许一个检索器的输出作为另一个检索器的输入实现更复杂的检索流程。总结路由检索器(RouterRetriever)是LlamaIndex中一个强大的组件它能够根据查询内容动态选择最适合的检索器。通过集成多种不同类型的检索器并使用LLM进行智能路由决策路由检索器可以显著提高检索系统的灵活性和准确性。本案例展示了如何使用PydanticSingleSelector和PydanticMultiSelector构建单选和多选路由检索器并通过实际查询演示了它们的工作原理。单选模式适合简单查询能够选择最合适的单个检索器多选模式适合复杂查询能够结合多个检索器的优势。路由检索器的核心价值在于它能够理解查询意图并做出合理的选择决策从而避免使用不适合的检索器提高检索效率和结果质量。这种设计模式特别适合处理多样化的查询需求和集成多种数据源的场景为构建智能检索系统提供了坚实的基础。
【RAG】【retrievers14】路由检索器
案例目标本案例演示了如何使用RouterRetriever构建一个智能路由系统该系统能够根据查询内容动态选择最适合的检索器。智能路由选择根据查询类型和内容自动选择最合适的检索器多检索器集成集成多种不同类型的检索器包括列表检索器、向量检索器和关键词检索器单选与多选模式支持单选器(PydanticSingleSelector)和多选器(PydanticMultiSelector)两种模式基于LLM的决策利用大语言模型的推理能力进行检索器选择通过路由检索器我们可以构建更加灵活和智能的检索系统能够根据不同的查询需求动态选择最适合的检索策略从而提高检索效率和准确性。技术栈与核心依赖核心库llama-index-llms-openaillama-index路由与选择RouterRetrieverPydanticSingleSelectorPydanticMultiSelectorLLMSingleSelectorLLMMultiSelector检索器与索引RetrieverToolVectorStoreIndexSummaryIndexSimpleKeywordTableIndexSentenceSplitter环境配置安装依赖%pip install llama-index-llms-openai !pip install llama-index环境设置# NOTE: This is ONLY necessary in jupyter notebook. import nest_asyncio nest_asyncio.apply() import logging import sys logging.basicConfig(streamsys.stdout, levellogging.INFO) logging.getLogger().handlers [] logging.getLogger().addHandler(logging.StreamHandler(streamsys.stdout))注意需要设置有效的OpenAI API密钥才能运行此示例。此外在Jupyter notebook中运行需要使用nest_asyncio来处理嵌套事件循环。案例实现1. 数据准备与索引构建下载Paul Graham的文章并创建三种不同类型的索引# 下载数据 !mkdir -p data/paul_graham/ !wget https://raw.githubusercontent.com/run-llama/llama_index/main/docs/examples/data/paul_graham/paul_graham_essay.txt -O data/paul_graham/paul_graham_essay.txt # 加载文档 documents SimpleDirectoryReader(./data/paul_graham/).load_data() # 初始化LLM和分割器 llm OpenAI(modelgpt-4) splitter SentenceSplitter(chunk_size1024) nodes splitter.get_nodes_from_documents(documents) # 初始化存储上下文 storage_context StorageContext.from_defaults() storage_context.docstore.add_documents(nodes) # 创建三种不同类型的索引 summary_index SummaryIndex(nodes, storage_contextstorage_context) vector_index VectorStoreIndex(nodes, storage_contextstorage_context) keyword_index SimpleKeywordTableIndex(nodes, storage_contextstorage_context)2. 创建检索器工具为每种索引创建对应的检索器并将其包装为RetrieverTool# 创建检索器 list_retriever summary_index.as_retriever() vector_retriever vector_index.as_retriever() keyword_retriever keyword_index.as_retriever() # 创建检索器工具 from llama_index.core.tools import RetrieverTool list_tool RetrieverTool.from_defaults( retrieverlist_retriever, description( Will retrieve all context from Paul Grahams essay on What I Worked On. Dont use if the question only requires more specific context. ), ) vector_tool RetrieverTool.from_defaults( retrievervector_retriever, description( Useful for retrieving specific context from Paul Graham essay on What I Worked On. ), ) keyword_tool RetrieverTool.from_defaults( retrieverkeyword_retriever, description( Useful for retrieving specific context from Paul Graham essay on What I Worked On (using entities mentioned in query) ), )3. 单选路由检索器实现使用PydanticSingleSelector创建单选路由检索器每次只选择一个最佳检索器from llama_index.core.selectors import ( PydanticMultiSelector, PydanticSingleSelector, ) from llama_index.core.retrievers import RouterRetriever # 创建单选路由检索器 retriever RouterRetriever( selectorPydanticSingleSelector.from_defaults(llmllm), retriever_tools[ list_tool, vector_tool, ], )PydanticSingleSelector使用OpenAI的Function Call API来生成结构化的选择对象而不是解析原始JSON。这种方式更加可靠目前支持gpt-4-0613和gpt-3.5-turbo-0613模型。4. 单选路由检索器查询示例执行两种不同类型的查询观察路由检索器的选择行为# 查询1获取作者生活的所有上下文 nodes retriever.retrieve( Can you give me all the context regarding the authors life? ) # 输出Selecting retriever 0: This choice is most relevant as it mentions retrieving all context from the essay... # 查询2获取特定细节 nodes retriever.retrieve(What did Paul Graham do after RISD?) # 输出Selecting retriever 1: The question asks for a specific detail from Paul Grahams essay...观察结果对于第一个查询路由器选择了列表检索器(list_tool)因为查询要求获取所有上下文对于第二个查询路由器选择了向量检索器(vector_tool)因为查询要求获取特定细节。5. 多选路由检索器实现使用PydanticMultiSelector创建多选路由检索器可以选择多个检索器# 创建多选路由检索器 retriever RouterRetriever( selectorPydanticMultiSelector.from_defaults(llmllm), retriever_tools[list_tool, vector_tool, keyword_tool], )PydanticMultiSelector可以选择多个检索器来处理查询这对于需要从多个角度检索信息的复杂查询特别有用。6. 多选路由检索器查询示例执行包含多个实体的查询观察多选路由检索器的选择行为# 查询包含多个实体的复杂查询 nodes retriever.retrieve( What were noteable events from the authors time at Interleaf and YC? ) # 输出 # Selecting retriever 1: This choice is relevant as it allows for retrieving specific context... # Selecting retriever 2: This choice is also relevant as it allows for retrieving specific context using entities... # query keywords: [interleaf, events, noteable, yc] # Extracted keywords: [interleaf, yc]观察结果对于包含多个实体(Interleaf和YC)的查询多选路由器同时选择了向量检索器和关键词检索器并提取了查询中的关键词进行进一步处理。案例效果我们比较了单选和多选路由检索器在不同类型查询下的表现单选路由检索器查询1Can you give me all the context regarding the authors life?选择列表检索器(list_tool)结果返回文档中的所有节点适合获取全面信息查询2What did Paul Graham do after RISD?选择向量检索器(vector_tool)结果返回与查询最相关的节点相似度0.80-0.79多选路由检索器查询What were noteable events from the authors time at Interleaf and YC?选择向量检索器 关键词检索器关键词提取[interleaf, yc]结果结合语义搜索和关键词匹配返回更全面的相关节点结论路由检索器能够根据查询内容和类型智能选择最适合的检索器。单选模式适合简单查询多选模式适合包含多个实体或需要多角度检索的复杂查询。通过LLM的推理能力路由检索器能够理解查询意图并做出合理的选择决策。路由决策示例# 单选路由决策示例 Selecting retriever 0: This choice is most relevant as it mentions retrieving all context from the essay, which could include information about the authors life. Selecting retriever 1: The question asks for a specific detail from Paul Grahams essay on What I Worked On. Therefore, the second choice, which is useful for retrieving specific context, is the most relevant. # 多选路由决策示例 Selecting retriever 1: This choice is relevant as it allows for retrieving specific context from the essay, which is needed to answer the question about notable events at Interleaf and YC. Selecting retriever 2: This choice is also relevant as it allows for retrieving specific context using entities mentioned in the query, which in this case are Interleaf and YC.案例实现思路路由检索器工作流程步骤1检索器工具创建为每种检索器创建RetrieverTool对象包含检索器实例和描述信息。描述信息对于路由器选择合适的检索器至关重要它提供了关于每个检索器功能和适用场景的详细信息。步骤2选择器初始化根据需求选择合适的选择器(PydanticSingleSelector或PydanticMultiSelector)并配置LLM模型。选择器负责分析查询内容并决定使用哪些检索器。步骤3路由检索器构建将选择器和检索器工具列表传递给RouterRetriever创建完整的路由检索系统。路由检索器封装了选择逻辑和检索器调用。步骤4查询处理与路由决策当收到查询时选择器使用LLM分析查询内容和意图根据检索器工具的描述信息选择最合适的检索器。对于多选模式可能会选择多个检索器。步骤5检索执行与结果返回路由检索器调用选定的检索器执行查询收集检索结果并返回。对于多选模式可能会合并多个检索器的结果。Pydantic选择器与LLM选择器的区别Pydantic选择器• 使用OpenAI Function Call API• 生成结构化的Pydantic对象• 更可靠减少解析错误• 仅支持特定模型(gpt-4-0613, gpt-3.5-turbo-0613)LLM选择器• 生成原始JSON响应• 需要解析JSON文本• 兼容更多模型• 可能出现解析错误扩展建议1. 自定义选择器实现实现自定义选择器基于查询特征(如长度、关键词、实体等)使用规则或机器学习模型进行检索器选择减少对LLM的依赖。2. 动态检索器权重调整在多选模式下根据查询类型和检索器历史性能动态调整不同检索器的权重优化结果融合效果。3. 检索器性能监控实现检索器性能监控系统记录不同类型查询下各检索器的表现为选择器优化提供数据支持。4. 分层路由系统构建多级路由系统第一级选择检索器类别第二级选择具体检索器支持更复杂的检索场景。5. 查询意图分类集成查询意图分类模块将查询分为事实查询、概念查询、比较查询等类型为路由决策提供更精确的依据。6. 检索器协同机制设计检索器之间的协同机制允许一个检索器的输出作为另一个检索器的输入实现更复杂的检索流程。总结路由检索器(RouterRetriever)是LlamaIndex中一个强大的组件它能够根据查询内容动态选择最适合的检索器。通过集成多种不同类型的检索器并使用LLM进行智能路由决策路由检索器可以显著提高检索系统的灵活性和准确性。本案例展示了如何使用PydanticSingleSelector和PydanticMultiSelector构建单选和多选路由检索器并通过实际查询演示了它们的工作原理。单选模式适合简单查询能够选择最合适的单个检索器多选模式适合复杂查询能够结合多个检索器的优势。路由检索器的核心价值在于它能够理解查询意图并做出合理的选择决策从而避免使用不适合的检索器提高检索效率和结果质量。这种设计模式特别适合处理多样化的查询需求和集成多种数据源的场景为构建智能检索系统提供了坚实的基础。