56.llama_index-查询引擎(查看默认的查询引擎源码)
2026/7/17 4:15:45 网站建设 项目流程

内容参考于:图灵AI大模型全栈

查询引擎

Query Engine(查询引擎)它在llamaindex中是最常用的一个抽象接口,用来接收问题,自动完成检索相关文档片段(Node)然后调用llm大模型生成最终答案,只需要一行代码就可以实现

文档地址

https://developers.llamaindex.ai/python/framework-api-reference/query_engine/

基础使用的代码

效果图:

可以正常回答问题

# 从 llama_index 核心库导入向量索引、简易目录读取器、存储上下文和从存储加载索引的函数 # 这些组件用于构建文档索引、持久化索引以及后续的查询操作 from llama_index.core import VectorStoreIndex, SimpleDirectoryReader, StorageContext, load_index_from_storage # 从自定义模块 base_llm 中导入大语言模型实例和嵌入模型实例 # 入参:llm 和 embed_model 是由 base_llm 模块提供的预配置对象,来源为项目中的 base_llm.py 文件 # 具体实现细节未知,但这里假设它们已经正确初始化并符合 llama_index 的接口要求 from base_llm import llm, embed_model # 加载文档 # 使用 SimpleDirectoryReader 读取指定路径的文本文件(./data_file/小说.txt) # input_files 参数:一个列表,指定要读取的文件路径,来源为硬编码的字符串常量 # load_data() 方法返回一个文档对象列表,每个文档包含文本内容和元数据 documents = SimpleDirectoryReader(input_files=["./data_file/小说.txt"]).load_data() # 创建索引对象 # VectorStoreIndex.from_documents 根据文档列表构建向量索引 # 参数 documents:上一步加载的文档列表;embed_model:用于生成文本向量的嵌入模型实例(来自 base_llm) # 该索引会为每个文档块生成向量,便于后续的相似性检索 index = VectorStoreIndex.from_documents(documents, embed_model=embed_model) # 将索引持久化到本地磁盘,存储在名为 'test' 的目录中 # persist 方法将索引的向量数据、文档元数据等保存到指定路径,以便后续无需重新构建即可加载 index.storage_context.persist('test') # 创建查询引擎并执行查询 # as_query_engine 方法将索引转换为查询引擎,参数: # llm:用于生成回答的大语言模型实例(来自 base_llm) # streaming=True:启用流式响应,即逐步生成回答文本 # query() 方法传入查询字符串 "萧炎的爸爸叫什么名字?",返回一个响应对象 res res = index.as_query_engine(llm=llm, streaming=True).query("萧炎的爸爸叫什么名字?") # 遍历响应对象的 response_gen 生成器,该生成器逐个输出流式响应的文本片段 # 每个片段 i 是一个字符串,将其打印到控制台,实现逐字打印效果 for i in res.response_gen: print(i) # 以下是注释掉的代码段,用于从本地加载已存储的索引并执行查询 # 这些代码提供了另一种工作流:从持久化目录恢复索引,无需重新构建 # # 从本地加载已存储的索引数据 # # 使用 StorageContext.from_defaults 从默认路径或指定目录加载存储上下文 # # persist_dir="test" 指定索引持久化的目录,来源为之前 persist 方法保存的 'test' 目录 # new_storage_context = StorageContext.from_defaults(persist_dir="test") # # # 从存储上下文加载索引对象 # # load_index_from_storage 根据存储上下文和嵌入模型重建索引 # # embed_model 参数必须与构建时使用的嵌入模型相同,否则向量维度不匹配,来源同上的 embed_model # new_index = load_index_from_storage(new_storage_context, embed_model=embed_model) # # # 查询引擎用来提问 # # 检索对应的上下文 -> 组合用户问题 + 检索的上下文交给 LLM,去总结回复 # # as_query_engine 同样使用 llm 实例(来自 base_llm)和 streaming=True 流式响应 # # query() 传入相同的问题 "萧炎的爸爸叫什么名字?" # res = new_index.as_query_engine(llm=llm, streaming=True).query("萧炎的爸爸叫什么名字?") # # # 遍历流式响应生成器并打印输出 # for i in res.response_gen: # print(i) # # # 打印响应对象的 repr 表示,可能用于调试,显示响应对象的内部结构 # # print(repr(res))

as_query_engine实现的逻辑

首先鼠标左键单击下图红框位置,出现下图红框的红点即可

点击下图红框或蓝框,这俩点击谁都可以

然后代码就会在下图红框位置停住(断点住)

然后点击下图红框,进入as_query_engine中

点击上图红框后,鼠标左键再点击下图红框,也就是选择进入as_query_engine中

现在就进入了as_query_engine中,它的入参是我们传的大模型

然后再下图红框位置导入一个问题检索引擎,默认的问题检索引擎

然后下图红框位置,创建了一个检索器,之前我们都是手动创建的,as_query_engine给我们创建了,我们就不用写了

然后如下图红框,判断我们传没传大模型,如果没传它会找Settings.llm获取大模型,也就是从全局配置中获取大模型

然后把创建的大模型、检索器给到问题引擎

现在as_query_engine就分析完了,它就是给我们创建了大模型、检索器,问题引擎,并返回问题引擎的对象,然后接下来看下图红框的query

然后如下图的操作,先点击蓝框位置设置断点,然后再点击红框位置,让代码运行到断点位置,然后再点击四次黄框位置运行一行代码

然后再次点击下图红框位置,让它进入query中

然后它会进入下图红框的wrapper里面,这个方法是llamaindex用来追用调用过程方法

它执行原方法的位置是下图红框位置,result = func(*args, **kwargs)

根据下图红框的步骤操作,要进入result = func(*args, **kwargs)

然后就进入了query中

下图红框位置才是真正的query方法,所以要进入它

如下图红框依旧三步骤进入query

它还是会来到wrapper里,所以要是要进入result = func(*args, **kwargs)

如下图红框就可以看到熟悉的代码了self.retrieve是检索器,检索器就会得到跟问题相关的文档(Node)

选中下图红框的文字

鼠标右击选择下图红框

然后点击下图红框

上图红框点击完会运行输入框里的代码,也就是运行self.retrieve(query_bundle)这个代码,如下图self.retrieve(query_bundle)运行完的结果,查到了相关文档

下图红框就是响应合成器,然后就结束了

总结:

首先调用as_query_engine初始化,检索器、大模型、查询引擎(RetrieverQueryEngine)

然后调用query检索文档,创建响应合成器拼接文档,然后给大模型回答问题

响应合成器默认的模式是ResponseMode.COMPACT,按着键盘上的CTRL键鼠标左键单击下图红框位置

然后再按着键盘上的CTRL键鼠标左键单击下图红框位置

如下图红框位置默认COMPACT模式

图示:


需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询