
LlamaIndex 中基于检索器的路由查询引擎RetrieverRouterQueryEngine 深度解析【免费下载链接】llama_indexLlamaIndex is the leading document agent and OCR platform项目地址: https://gitcode.com/GitHub_Trending/ll/llama_index本篇技术指南围绕 LlamaIndex 核心库中RetrieverRouterQueryEngine基于检索器的路由查询引擎展开讲解它如何借助检索器Retriever从候选 Node 中筛选出目标查询引擎、将 Node 映射为 QueryEngine 并完成最终查询的完整机制。读完本文你将掌握该 API 的构造参数、底层执行链路、异步行为理解它为何被标记为 beta 并在后续演进中被ToolRetrieverRouterQueryEngine取代以及如何根据仓库源码判断何时该使用它、何时应迁移到推荐的替代方案。从一个 API 引用出发该引擎是什么关联文档是 LlamaIndex 自动生成的 API Reference 页它通过 mkdocstrings 指令把llama_index.core.query_engine模块中RetrieverRouterQueryEngine类的完整签名、文档字符串与成员索引渲染出来。其技术本体位于核心库源码 router_query_engine.py。要理解该引擎需要先区分两类路由范式RouterQueryEngine基于 Selector 路由给定一批已包装为QueryEngineTool的候选查询引擎用一个BaseSelector通常是 LLM selector根据每个候选的元数据与用户查询选择一个或多个引擎执行查询见 router.md。RetrieverRouterQueryEngine基于 Retriever 路由不预先固定候选引擎列表而是先用一个BaseRetriever去检索出相关 Node每个 Node 再被转换为ToolMetadata并据此取回对应的查询引擎构成QueryEngineTool最终只执行被选中引擎的查询见 retriever_router.md 所述内容。从源码的类注释可以确认其定位Use a retriever to select a set of Nodes. Each node will be converted into a ToolMetadata object, and also used to retrieve a query engine, to form a QueryEngineTool.同时源码明确标注了两条重要状态信息已弃用deprecated注释指明please use our new ToolRetrieverRouterQueryEnginebeta 特性注释提示We are figuring out the right interface between the retriever and query engine即检索器与查询引擎之间的接口仍处于探索期。因此把它当作理解 LlamaIndex 路由演进历史、以及阅读旧版代码时的关键 API 最合适新代码应优先考虑替代实现。构造签名与参数语义该类继承自BaseQueryEngine构造器接收三个参数RetrieverRouterQueryEngine( retriever: BaseRetriever, # 检索器负责根据查询取出候选 Node node_to_query_engine_fn: Callable, # 将单个 Node 映射为查询引擎的回调函数 callback_manager: Optional[CallbackManager] None, )各参数在源码中的实际作用如下retriever一个BaseRetriever实例_query执行时首先调用self._retriever.retrieve(query_bundle)得到带分数的 Node 列表NodeWithScore。node_to_query_engine_fn可调用对象接收一个BaseNode返回一个QueryEngine。它是Node → 查询引擎的桥接逻辑典型实现是根据 Node 的内容、元数据或tool_name从本地注册表/对象索引中取出对应引擎其底层思想与default_node_to_metadata_fn中依赖 Node 元数据tool_name的思路一致见 router_query_engine.py 中对 ToolMetadata 构造的约定。callback_manager可选的回调管理器_get_prompt_modules会把self._retriever作为可提示子模块暴露出去说明该引擎的提示词体系主要来自其内部检索器。构造器直接保存上述参数并调用super().__init__(callback_manager)完成基类初始化本身不引入额外状态逻辑非常轻量。底层执行链路从检索到查询的一步路由该引擎的查询过程非常短平快核心逻辑集中在_query方法router_query_engine.pynodes_with_score self._retriever.retrieve(query_bundle) if len(nodes_with_score) 1: raise ValueError(Retrieved more than one node.) node nodes_with_score[0].node query_engine self._node_to_query_engine_fn(node) return query_engine.query(query_bundle)整个链路可以拆解为四步检索把用户的QueryBundle包含查询字符串及可选的自定义嵌入/节点过滤器交给retriever.retrieve()得到候选NodeWithScore列表强制单选当前实现只支持检索出恰好一个 Node一旦超过一个便抛出ValueError(Retrieved more than one node.)。源码中以# TODO: for now we only support retrieving one node明确标注了这一限制——这是该实现半成品属性的最直接体现Node → QueryEngine 映射调用node_to_query_engine_fn(node)取回真正要执行的查询引擎执行查询返回query_engine.query(query_bundle)的结果。值得注意的是_query全程没有回调事件包装对比同一文件里RouterQueryEngine._query会触发CBEventType.QUERY事件并把selector_result写入响应元数据router_query_engine.py说明该引擎在可观测性上是相对薄弱的雏形实现。异步路径同步的封装异步方法_aquery的实现更简练——它直接委托给同步_queryasync def _aquery(self, query_bundle: QueryBundle) - RESPONSE_TYPE: return self._query(query_bundle)即调用await engine.aquery(...)时实际是在事件循环里同步执行检索、映射与查询内部并不会并发调用检索器或子引擎。这意味着在异步应用中使用它时检索/查询阶段会阻塞事件循环不适合高并发场景。说明性的端到端用法下面的示例基于上述构造语义演示一种自洽的组装方式不依赖未公开接口仅用于说明回调函数的典型形态from llama_index.core.query_engine import RetrieverRouterQueryEngine # registry: dict[str, QueryEngine] —— 按 node.metadata[tool_name] 索引的引擎表 def node_to_query_engine(node): tool_name node.metadata[tool_name] return registry[tool_name] router RetrieverRouterQueryEngine( retrievermy_retriever, # 保证只召回 1 个 node 的 BaseRetriever node_to_query_engine_fnnode_to_query_engine, ) response router.query(What is LlamaIndex?) print(response)需要再次强调当前实现要求检索结果恰好为一个 Node因此配套的检索器必须在召回层就做好 top-1 截断或保证相关性唯一否则引擎会直接抛错。模块同源的兄弟引擎与演进路线RetrieverRouterQueryEngine与另外两个引擎同处一个文件router_query_engine.py共同构成了 LlamaIndex 查询引擎多选一/多选多的完整能力带RouterQueryEngineSelector 驱动的精确路由RouterQueryEngine把候选引擎包装为QueryEngineTool交给BaseSelectorselect_multiFalse时单选择器基于各引擎的ToolMetadata描述与用户查询做 LLM 判断from_defaults通过get_selector_from_llm(llm, is_multiselect_multi)自动创建选择器。当选择器命中多个引擎时会逐一执行并用TreeSummarizecombine_responses/acombine_responses合并多个子响应最后把selector_result挂到响应metadata上。异步路径_aquery使用asyncio.gather并行执行所有被选中子引擎。它是当前文档对应类同目录下的正式替代方向之一参见 router.md。ToolRetrieverRouterQueryEngine官方推荐的演进替代这正是弃用注释中点名的新实现参见 tool_retriever_router.md。它的关键差异在于构造参数从BaseRetriever node_to_query_engine_fn变为ObjectRetriever[QueryEngineTool]即直接检索已包装好的工具对象工具本身携带query_engine与metadata彻底消除了手写 Node→Engine 回调的环节检索返回的是多个QueryEngineTool引擎会把它们全部执行同步串行、异步asyncio.gather并发超过一个结果时交给内置TreeSummarize汇总响应metadata中记录retrieved_tools字段可观测性优于旧实现combine_responses/acombine_responses两个模块级函数负责统一合并逻辑收集各子响应的source_nodes与文本调用 summarizer 得到最终响应支持Response/PydanticResponse/StreamingResponse等形态见 router_query_engine.py。从源码演进看官方把检索 路由的范式收敛为检索对象Tool 而非裸 Node 批量执行 汇总即ObjectRetriever方案RetrieverRouterQueryEngine是这一范式定型前的中间形态。三者选型速览引擎决策依据候选来源执行策略状态RetrieverRouterQueryEngineRetriever 召回单个 NodeNode →node_to_query_engine_fn回调仅执行命中的 1 个引擎超过 1 个抛错beta、已弃用RouterQueryEngineLLM Selector 读元数据选择预置QueryEngineTool列表单选或全选多选时 TreeSummarize 汇总稳定路径ToolRetrieverRouterQueryEngineObjectRetriever 召回工具可检索的QueryEngineTool对象库召回即执行多结果汇总推荐替代与相关 API 文档及测试的关系相关 API Reference本引擎与 router.mdRouterQueryEngine、tool_retriever_router.mdToolRetrieverRouterQueryEngine、retriever.mdRetrieverQueryEngine构成同一 API 组的完整参照可在阅读时相互对照。测试覆盖情况仓库测试 test_router_query_engine.py 仅直接测试了RouterQueryEngine与ToolRetrieverRouterQueryEngine的异步非阻塞特性例如通过后台任务计时断言aquery不长时间霸占事件循环并未为RetrieverRouterQueryEngine编写专门测试——这与它 beta/弃用的定位一致。若你在旧代码库中遇到它可把它视为一个仅具单节点路由能力的过渡组件在升级路径上应优先迁移到ToolRetrieverRouterQueryEngine。小结RetrieverRouterQueryEngine是 LlamaIndex 路由查询引擎家族中一个具有历史意义的 API它首次把检索器召回 Node 元数据 查询引擎路由串成一条管线但其单 Node 限制、无回调事件包装、异步同步化等特征都表明它只是一个未定型的 beta 实现。理解它的源码实现有助于看清后续RouterQueryEngineSelector 路由与ToolRetrieverRouterQueryEngine对象检索路由各自解决的问题边界前者解决候选引擎元数据如何被 LLM 阅读后者解决大量引擎如何被高效检索与批量执行。在新的代码中应遵循源码中的弃用指引优先使用 ToolRetrieverRouterQueryEngine。【免费下载链接】llama_indexLlamaIndex is the leading document agent and OCR platform项目地址: https://gitcode.com/GitHub_Trending/ll/llama_index创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考