Retriever 只给名单。产品要的是一句话答案,并且能指回 methods 那条 Node。QueryEngine 把三拍焊在一起:检索 → 可选 NodePostprocessor → ResponseSynthesizer 调 LLM,返回 Response。index.as_query_engine() 是这条焊线的捷径;要换混合检索或过滤,就显式 RetrieverQueryEngine.from_args(retriever, ...)。
段末注释:QueryEngine 输入自然语言 query,输出
Response(文本 +source_nodes)。默认是 DAG,不是带环 Agent。

1. 一句话定位
| 维度 | 内容 |
|---|---|
| 角色 | 知识层的一次问答入口:检索结果变成可引用答案 |
| 输入 → 输出 | str → Response(.response / str(resp) + .source_nodes) |
| 典型调用入口 | index.as_query_engine().query()、RetrieverQueryEngine.from_args()、aquery() |
| 与 LangChain / LangGraph | 近邻是 retriever | prompt | model;环、HITL、checkpoint 不在本对象里 |
出现背景:早期示例只有 query_engine.query。可定制检索之后,官方把引擎拆成可插拔的 Retriever + Synthesizer + Postprocessor,捷径 as_query_engine 仍然可用。
2. 前置依赖与环境
1 | pip install -U llama-index-core llama-index-llms-ollama llama-index-embeddings-ollama |
- 必须同时设
Settings.llm与Settings.embed_model - 示例用同步
query();FastAPI 用await qe.aquery(...) streaming=True时迭代response_gen,不要假定一次返回完整str
3. 实现逻辑
1 | 1. 准备 Index / Retriever |
字段级变形:
1 | "实验对象是什么物种?" |
source_nodes 默认是送进合成器之前的名单(含后处理结果),不是模型「声称引用了谁」。模型胡编时,名单里可能根本没有那句话——所以必须对读。
4. 原理说明
主轴是:query() 是三条管道的同步门面;缺任何一拍,数据停在不同层。
1 | 1. QueryEngine.query 把 str 包成 QueryBundle |
VectorStoreIndex.as_query_engine(**kwargs) 出现在步骤 2。内部用该 index 的 VectorIndexRetriever + 默认 compact 合成器。kwargs 会传给 retriever / synthesizer(如 similarity_top_k、response_mode、node_postprocessors、streaming)。
RetrieverQueryEngine.from_args(retriever, ...) 出现在步骤 2。功能:任意 Retriever(混合、Router)焊成引擎。RetrieverQueryEngine(retriever, response_synthesizer=..., node_postprocessors=...) 是更显式的构造。
Response 出现在步骤 7。常用:str(resp)、resp.source_nodes、resp.metadata。不要用 resp.response is None 判断流式对象。
SimilarityPostprocessor(similarity_cutoff=...) 可作为第 3 步的最小后处理;完整 rerank 见后处理专篇。
QueryEngine 不会在合成失败后自动再检索——那是 Agent / LangGraph。
5. 最小可运行示例
1 | pip install -U llama-index-core llama-index-llms-ollama llama-index-embeddings-ollama |
1 | from llama_index.core import Document, Settings, VectorStoreIndex, get_response_synthesizer |
流式(token 随迭代到达):
1 | qe_s = index.as_query_engine(similarity_top_k=3, streaming=True) |
6. 重要配置参数
| 参数(API 名) | 类型 / 默认值 | 功能说明 | 作用与影响 | 参考起点 / 常用范围 | 配置指导 |
|---|---|---|---|---|---|
similarity_top_k |
int,常默认 2 | 传给底层向量 Retriever 的 k | 过小漏证据;过大挤合成窗口 | 5~10 | 与 cutoff / rerank 联调 |
response_mode |
str,默认 compact |
选择合成器策略 | 决定 LLM 次数与细节保留 | compact / refine / tree_summarize / no_text | 单事实 compact;只审计用 no_text |
node_postprocessors |
list,默认 [] |
retrieve 之后、合成之前的过滤/重排 | 空列表 = 原样送 LLM | 至少可加 SimilarityPostprocessor | 顺序即流水线顺序 |
streaming |
bool,默认 False | 是否流式解码 | True 时不要当普通 str 一次用完 | SSE 接口 True | 与 aquery 独立 |
llm |
LLM,可选 | 覆盖 Settings.llm 只用于合成 | 检索仍用 embed_model | 与 Settings 成对 | 不要只设 llm |
text_qa_template |
PromptTemplate,可选 | compact/refine 的主问答模板 | 不写「只根据资料」易引入参数记忆 | 加「无证据则不知道」 | 引用约束写在这里 |
7. 适用 / 不适用
| 维度 | 适用 | 不适用 |
|---|---|---|
| 任务形态 | 单轮文档问答、要 source_nodes |
工具失败再检索、多步规划——Agent / LangGraph |
| 集成约束 | 已有 Retriever | 无私有库——直接 ChatModel |
| 工程阶段 | 同步脚本到 FastAPI aquery |
需要审批后再生成——interrupt 放在图上,QE 只当节点 |
8. 易踩坑
- 只
print(resp):丢掉引用,无法证明不是幻觉。 as_query_engine默认 k=2:混合语料时方法块排不到前两名。- cutoff 按 0.7 抄向量库教程:Simple 店分数量纲不同,可能滤空。先打印
source_nodes.score再设。 - 在 FastAPI 里同步
query():阻塞事件循环,改aquery。
小结
- QueryEngine = retrieve → postprocess → synthesize。
- 捷径
as_query_engine;可插拔用RetrieverQueryEngine.from_args。 - 审计读
source_nodes,并与答案对读。 - 要再检索、要环,把本对象当工具,不要在
query()里 while True。