11 LlamaIndex中的查询:解锁LLM应用的核心功能

LlamaIndex中的查询:解锁LLM应用的核心功能

现在你已经加载了数据,构建了索引,并为后续存储了该索引,你已经准备好进入LLM应用中最重要的一部分:查询。

在最简单的情况下,查询只是对LLM的一个提示调用:它可以是一个问题并得到答案,或者是一个总结请求,或者是一个更复杂的指令。

更复杂的查询可能涉及重复/链式的提示+LLM调用,甚至是在多个组件之间的推理循环。

入门指南

所有查询的基础是查询引擎(QueryEngine)。获取查询引擎的最简单方法是让索引为你创建一个,如下所示:

query_engine = index.as_query_engine()
response = query_engine.query(
    "Write an email to the user given their background information."
)
print(response)

查询的阶段

然而,查询不仅仅是表面上看起来的那么简单。查询由三个不同的阶段组成:

  1. 检索:从你的索引中找到并返回与查询最相关的文档。如索引部分所述,最常见的检索类型是“前k”语义检索,但还有许多其他检索策略。
  2. 后处理:对检索到的节点进行可选的重排序、变换或过滤,例如要求它们具有特定的元数据,如附加的关键词。
  3. 响应合成:将你的查询、最相关的数据和你的提示组合并发送给LLM以返回响应。

提示

你可以了解如何将元数据附加到文档和节点。

自定义查询的阶段

LlamaIndex提供了一个低级组合API,让你可以对查询进行细粒度的控制。

在这个例子中,我们自定义了检索器以使用不同的top_k数量,并添加了一个后处理步骤,要求检索到的节点达到最小相似度分数才能被包含。这会在你有相关结果时提供大量数据,但如果没有任何相关内容,则可能没有数据。

from llama_index.core import VectorStoreIndex, 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

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

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

# 配置响应合成器
response_synthesizer = get_response_synthesizer()

# 组装查询引擎
query_engine = RetrieverQueryEngine(
    retriever=retriever,
    response_synthesizer=response_synthesizer,
    node_postprocessors=[SimilarityPostprocessor(similarity_cutoff=0.7)],
)

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

你还可以通过实现相应的接口来添加自己的检索、响应合成和整体查询逻辑。

有关已实现组件和受支持配置的完整列表,请查看我们的参考文档。

让我们更详细地了解如何自定义每个步骤:

配置检索器

retriever = VectorIndexRetriever(
    index=index,
    similarity_top_k=10,
)

有各种各样的检索器,你可以在我们的检索器模块指南中了解。

配置节点后处理器

我们支持高级的节点过滤和增强,可以进一步提高检索到的节点对象的相关性。这可以帮助减少时间/LLM调用次数/成本或提高响应质量。

例如:

  • KeywordNodePostprocessor:通过required_keywords和exclude_keywords过滤节点。
  • SimilarityPostprocessor:通过设置相似度分数的阈值来过滤节点(因此仅支持基于嵌入的检索器)。
  • PrevNextNodePostprocessor:基于节点关系,通过增加额外的相关上下文来增强检索到的节点对象。

节点后处理器的完整列表记录在节点后处理器参考中。

要配置所需的节点后处理器:

node_postprocessors = [
    KeywordNodePostprocessor(
        required_keywords=["Combinator"], exclude_keywords=["Italy"]
    )
]
query_engine = RetrieverQueryEngine.from_args(
    retriever, node_postprocessors=node_postprocessors
)
response = query_engine.query("What did the author do growing up?")

配置响应合成

在检索器获取相关节点后,BaseSynthesizer通过组合信息合成最终响应。

你可以通过以下方式配置它:

query_engine = RetrieverQueryEngine.from_args(
    retriever, response_mode=response_mode
)

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

  • default:通过依次遍历每个检索到的节点“创建并提炼”答案;这会对每个节点进行单独的LLM调用。适用于更详细的答案。
  • compact:在每次LLM调用中“压缩”提示,尽可能多地塞入节点文本块。如果块太多无法塞入一个提示,则通过多个提示“创建并提炼”答案。
  • tree_summarize:给定一组节点对象和查询,递归构造一棵树并返回根节点作为响应。适用于总结目的。
  • no_text:仅运行检索器以获取本应发送给LLM的节点,而不实际发送它们。然后可以通过检查response.source_nodes来检查。响应对象在第5节中有更详细的介绍。
  • accumulate:给定一组节点对象和查询,将查询应用于每个节点文本块,同时将响应累积到一个数组中。返回所有响应的连接字符串。适用于需要对每个文本块单独运行相同查询的情况。

结构化输出

你可能希望确保你的输出是结构化的。请查看我们的查询引擎+Pydantic输出,了解如何从查询引擎类中提取Pydantic对象。

还要确保查看我们的整个结构化输出指南。

创建你自己的查询工作流

如果你想设计复杂的查询流程,可以在许多不同的模块之间组合你自己的查询工作流,从提示/LLMs/输出解析器到检索器到响应合成器到你自己的自定义组件。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

需要重新演唱

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

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

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

打赏作者

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

抵扣说明:

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

余额充值