查询引擎

QueryEngine 是「对索引问一句、拿一段回答」的高层接口。最简单的一行是 index.as_query_engine()。查询实际包含三步:Retrieval(取 Node)→ Postprocessing(过滤 / 重排)→ Response synthesis(把块和问题交给 LLM)。只关心取回、自己拼 Prompt 时,用 检索 的 Retriever,不必每次都走完整引擎。

示例合成仍建议显式 Settings.llm = OpenAI(model="gpt-4o-mini")。历史默认生成模型是 gpt-3.5-turbo,以官方文档为准。


as_query_engine

query_engine = index.as_query_engine()
response = query_engine.query("作者在大学期间做了什么?")
print(response)
print(response.source_nodes)  # 引用了哪些块

常用开关:

query_engine = index.as_query_engine(
    similarity_top_k=5,
    response_mode="compact",
    verbose=True,
)

默认 top-k 偏小(文档里常见默认 2)。召回不够就先加大 similarity_top_k,再考虑重排。异步用 await query_engine.aquery(...),方便塞进 FunctionAgent 工具。


合成模式 response_mode

取回之后,synthesizer 决定怎么把多块文本喂给 LLM:

模式行为适合
compact能塞进窗口的块尽量塞进同一次调用默认首选,省调用
**default / refine逐 Node 调用,后一块 refine 前一块答案要更细、可接受多次 LLM
tree_summarize递归树状归纳总结、多文档综述
no_text只检索不生成,看 source_nodes调试召回
accumulate对每块单独回答再拼接要对每一段都执行同一问题
qe = index.as_query_engine(response_mode="tree_summarize", similarity_top_k=8)
print(qe.query("用三段话总结 data/ 目录。"))

低层组装:RetrieverQueryEngine

需要自定义 top-k、相似度阈值时,不要只靠 as_query_engine 的 kwargs,显式拼装:

from llama_index.core import get_response_synthesizer
from llama_index.core.retrievers import VectorIndexRetriever
from llama_index.core.query_engine import RetrieverQueryEngine
from llama_index.core.postprocessor import SimilarityPostprocessor

retriever = VectorIndexRetriever(index=index, similarity_top_k=10)
synth = get_response_synthesizer(response_mode="compact")
query_engine = RetrieverQueryEngine(
    retriever=retriever,
    response_synthesizer=synth,
    node_postprocessors=[SimilarityPostprocessor(similarity_cutoff=0.7)],
)
response = query_engine.query("What did the author do growing up?")

similarity_cutoff 过严会变成「经常答不上来」——这是特性:宁可空,也不要用毫不相关的块胡编。调参时用 no_text 或打印分数。


Chat Engine:面向数据的多轮

QueryEngine 默认不带对话历史。多轮、需要指代消解时:

chat_engine = index.as_chat_engine()
print(chat_engine.chat("作者大学时做什么?"))
print(chat_engine.chat("接着讲,再具体一点。"))

chat_mode 常见取值(以当前文档为准):例如把历史压缩成独立检索问句、或把检索结果塞进 system prompt。流式:

streaming = chat_engine.stream_chat("用一句话概括。")
for token in streaming.response_gen:
    print(token, end="", flush=True)

带工具、要模型决定何时检索时,优先 快速上手FunctionAgent + Context,而不是强迫 Chat Engine 模拟 Agent。


查询引擎当 Agent 工具

from llama_index.core.tools import QueryEngineTool, ToolMetadata
from llama_index.core.agent.workflow import FunctionAgent
from llama_index.llms.openai import OpenAI

tool = QueryEngineTool.from_defaults(
    query_engine=index.as_query_engine(similarity_top_k=4),
    name="handbook",
    description="Search the employee handbook. Use for policy questions.",
)
agent = FunctionAgent(
    tools=[tool],
    llm=OpenAI(model="gpt-4o-mini"),
    system_prompt="Prefer the handbook tool for factual policy answers.",
)

也可像官方 starter 那样自己写 async def search_documents(query: str) 去调 aquery。多个 Index(API 文档 vs 教程)就注册多个 QueryEngineTool,让模型选库。


下一步

评论