19 LlamaIndex中的查询引擎

LlamaIndex中的查询引擎

概念

查询引擎是一个通用接口,允许你对数据提出问题。

查询引擎接收自然语言查询,并返回丰富的响应。它通常(但不总是)通过检索器构建在一个或多个索引之上。你可以组合多个查询引擎以实现更高级的功能。

提示

如果你想与数据进行对话(多次往返而不是单个问答),请查看聊天引擎。

使用模式

入门

从索引构建查询引擎:

query_engine = index.as_query_engine()

提示

要了解如何构建索引,请参见索引。

对数据提出问题:

response = query_engine.query("Who is Paul Graham?")

配置查询引擎

高级API

你可以直接从索引中构建和配置查询引擎,只需一行代码:

query_engine = index.as_query_engine(
    response_mode="tree_summarize",
    verbose=True,
)

注意:虽然高级API优化了易用性,但它并未暴露完整的可配置性。

查看响应模式以获取完整的响应模式列表及其功能。

低级组合API

如果你需要更细粒度的控制,可以使用低级组合API。具体来说,你可以显式构造一个QueryEngine对象,而不是调用index.as_query_engine(...)

注意:你可能需要查看API参考或示例笔记本。

from llama_index.core import VectorStoreIndex, get_response_synthesizer
from llama_index.core.retrievers import VectorIndexRetriever
from llama_index.core.query_engine import RetrieverQueryEngine

# 构建索引
index = VectorStoreIndex.from_documents(documents)

# 配置检索器
retriever = VectorIndexRetriever(
    index=index,
    similarity_top_k=2,
)

# 配置响应合成器
response_synthesizer = get_response_synthesizer(
    response_mode="tree_summarize",
)

# 组装查询引擎
query_engine = RetrieverQueryEngine(
    retriever=retriever,
    response_synthesizer=response_synthesizer,
)

# 查询
response = query_engine.query("What did the author do growing up?")
print(response)

流式处理

要启用流式处理,只需传递streaming=True标志:

query_engine = index.as_query_engine(
    streaming=True,
)
streaming_response = query_engine.query(
    "What did the author do growing up?",
)
streaming_response.print_response_stream()

阅读完整的流式指南
查看端到端示例

定义自定义查询引擎

你还可以定义自定义查询引擎。只需子类化CustomQueryEngine类,定义你想要的任何属性(类似于定义一个Pydantic类),并实现一个返回Response对象或字符串的custom_query函数。

from llama_index.core.query_engine import CustomQueryEngine
from llama_index.core.retrievers import BaseRetriever
from llama_index.core import get_response_synthesizer
from llama_index.core.response_synthesizers import BaseSynthesizer

class RAGQueryEngine(CustomQueryEngine):
    """RAG Query Engine."""

    retriever: BaseRetriever
    response_synthesizer: BaseSynthesizer

    def custom_query(self, query_str: str):
        nodes = self.retriever.retrieve(query_str)
        response_obj = self.response_synthesizer.synthesize(query_str, nodes)
        return response_obj

查看自定义查询引擎指南以获取更多详细信息。

响应模式

目前,我们支持以下选项:

  • refine:通过依次遍历每个检索到的文本块来创建和提炼答案。这会对每个节点/检索到的块进行单独的LLM调用。
    详细信息:第一个块使用text_qa_template提示进行查询。然后,答案和下一个块(以及原始问题)在另一个查询中使用refine_template提示。依此类推,直到所有块都被解析。
    如果一个块太大而无法适应窗口(考虑提示大小),则使用TokenTextSplitter进行拆分(允许块之间有一些文本重叠),并且(新)附加块被视为原始块集合的块(因此也使用refine_template进行查询)。
    适用于更详细的答案。

  • compact(默认):类似于refine,但事先压缩(连接)块,从而减少LLM调用。
    详细信息:尽可能多地填充文本(从检索到的块中连接/打包),使其适应上下文窗口(考虑text_qa_templaterefine_template之间的最大提示大小)。如果文本太长而无法适应一个提示,则根据需要拆分为多个部分(使用TokenTextSplitter,因此允许块之间有一些重叠)。
    每个文本部分被视为一个“块”,并发送给refine合成器。
    简而言之,它类似于refine,但LLM调用更少。

  • tree_summarize:使用summary_template提示查询LLM,次数根据需要多次,以便所有连接的块都被查询,从而得到多个答案,这些答案本身递归地用作tree_summarize LLM调用的块,依此类推,直到只剩下一个块,因此只有一个最终答案。
    详细信息:尽可能多地连接块,以适应上下文窗口使用summary_template提示,并在需要时拆分它们(再次使用TokenTextSplitter和一些文本重叠)。然后,对每个结果块/拆分使用summary_template进行查询(没有refine查询!)并获取多个答案。
    如果只有一个答案(因为只有一个块),那么它就是最终答案。
    如果有多个答案,这些本身被视为块,并递归地发送给tree_summarize过程(连接/拆分-适应/查询)。
    适用于总结目的。

  • simple_summarize:将所有文本块截断以适应单个LLM提示。适用于快速总结目的,但由于截断可能会丢失细节。

  • no_text:仅运行检索器以获取本应发送给LLM的节点,而不实际发送它们。然后可以通过检查response.source_nodes进行检查。

  • accumulate:给定一组文本块和查询,将查询应用于每个文本块,同时将响应累积到一个数组中。返回所有响应的连接字符串。适用于需要对每个文本块单独运行相同查询的情况。

  • compact_accumulate:与accumulate相同,但会对每个LLM提示进行“压缩”,类似于compact,并对每个文本块运行相同的查询。

通过这些响应模式,你可以根据具体需求选择最适合的方式来处理查询和生成响应。

LlamaIndex中的流式响应

LlamaIndex支持在响应生成时进行流式传输。这允许你在完整响应完成之前开始打印或处理响应的开头部分。这可以显著减少查询的感知延迟。

设置

要启用流式传输,你需要使用支持流式传输的LLM。目前,流式传输由OpenAI、HuggingFaceLLM和大多数LangChain LLMs(通过LangChainLLM)支持。

注意:如果你选择的LLM不支持流式传输,将引发NotImplementedError

要使用高级API配置查询引擎以使用流式传输,请在构建查询引擎时设置streaming=True

query_engine = index.as_query_engine(streaming=True, similarity_top_k=1)

如果你使用低级API来组合查询引擎,请在构造响应合成器时传递streaming=True

from llama_index.core import get_response_synthesizer

synth = get_response_synthesizer(streaming=True, ...)
query_engine = RetrieverQueryEngine(response_synthesizer=synth, ...)

流式响应

在正确配置LLM和查询引擎后,调用query现在返回一个StreamingResponse对象。

streaming_response = query_engine.query(
    "What did the author do growing up?",
)

响应在LLM调用开始时立即返回,而无需等待完整完成。

注意:在查询引擎进行多次LLM调用的情况下,只有最后一次LLM调用会被流式传输,响应在最后一次LLM调用开始时返回。

你可以从流式响应中获取生成器,并在令牌到达时进行迭代:

for text in streaming_response.response_gen:
    # 在令牌到达时进行处理。
    pass

或者,如果你只想在令牌到达时打印文本:

streaming_response.print_response_stream()

通过这些步骤,你可以利用LlamaIndex的流式传输功能,实时处理和显示LLM生成的响应,从而提升用户体验。

  • 15
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

需要重新演唱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值