20 LlamaIndex中的响应合成器

LlamaIndex中的响应合成器

概念

响应合成器是使用用户查询和给定的一组文本块从LLM生成响应的组件。响应合成器的输出是一个响应对象。

这种方法可以有多种形式,从简单的迭代文本块到复杂的构建树。主要思想是通过LLM简化跨数据生成响应的过程。

在查询引擎中使用时,响应合成器在从检索器检索节点之后,以及运行任何节点后处理器之后使用。

提示

对响应合成器在RAG工作流中的位置感到困惑?阅读高级概念

使用模式

入门

使用response_mode配置查询引擎的响应合成器:

from llama_index.core.data_structs import Node
from llama_index.core.schema import NodeWithScore
from llama_index.core import get_response_synthesizer

response_synthesizer = get_response_synthesizer(response_mode="compact")

response = response_synthesizer.synthesize(
    "query text", nodes=[NodeWithScore(node=Node(text="text"), score=1.0), ...]
)

或者,更常见的是,在创建索引后在查询引擎中使用:

query_engine = index.as_query_engine(response_synthesizer=response_synthesizer)
response = query_engine.query("query_text")

提示

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

配置响应模式

响应合成器通常通过response_mode关键字参数设置指定。

LlamaIndex中已经实现了几种响应合成器:

  • 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进行检查。

  • context_only:返回所有文本块的连接字符串。

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

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

自定义响应合成器

每个响应合成器继承自llama_index.response_synthesizers.base.BaseSynthesizer。基础API非常简单,这使得创建自己的响应合成器变得容易。

也许你想自定义在tree_summarize中每一步使用的模板,或者也许一篇新的研究论文详细介绍了一种生成查询响应的新方法,你可以创建自己的响应合成器并将其插入任何查询引擎或单独使用。

下面我们展示了__init__()函数,以及每个响应合成器必须实现的两个抽象方法。基本要求是处理查询和文本块,并返回字符串(或字符串生成器)响应。

from llama_index.core import Settings

class BaseSynthesizer(ABC):
    """Response builder class."""

    def __init__(
        self,
        llm: Optional[LLM] = None,
        streaming: bool = False,
    ) -> None:
        """Init params."""
        self._llm = llm or Settings.llm
        self._callback_manager = Settings.callback_manager
        self._streaming = streaming

    @abstractmethod
    def get_response(
        self,
        query_str: str,
        text_chunks: Sequence[str],
        **response_kwargs: Any,
    ) -> RESPONSE_TEXT_TYPE:
        """Get response."""
        ...

    @abstractmethod
    async def aget_response(
        self,
        query_str: str,
        text_chunks: Sequence[str],
        **response_kwargs: Any,
    ) -> RESPONSE_TEXT_TYPE:
        """Get response."""
        ...

使用结构化答案过滤

在使用“refine”或“compact”响应合成模块时,你可能会发现使用structured_answer_filtering选项是有益的。

from llama_index.core import get_response_synthesizer

response_synthesizer = get_response_synthesizer(structured_answer_filtering=True)

structured_answer_filtering设置为True后,我们的refine模块能够过滤掉与所提问题无关的任何输入节点。这对于涉及从外部向量存储中检索文本块的RAG-based Q&A系统特别有用。

如果使用支持函数调用的OpenAI模型,此选项特别有用。其他不支持原生函数调用的LLM提供商或模型在生成此功能依赖的结构化响应时可能不太可靠。

使用自定义提示模板(带额外变量)

你可能想自定义响应合成器中使用的提示,并在查询时添加额外变量。

你可以在get_response**kwargs中指定这些额外变量。

例如:

from llama_index.core import PromptTemplate
from llama_index.core.response_synthesizers import TreeSummarize

# 注意:我们在这里添加了一个额外的tone_name变量
qa_prompt_tmpl = (
    "Context information is below.\n"
    "---------------------\n"
    "{context_str}\n"
    "---------------------\n"
    "Given the context information and not prior knowledge, "
    "answer the query.\n"
    "Please also write the answer in the tone of {tone_name}.\n"
    "Query: {query_str}\n"
    "Answer: "
)
qa_prompt = PromptTemplate(qa_prompt_tmpl)

# 初始化响应合成器
summarizer = TreeSummarize(verbose=True, summary_template=qa_prompt)

# 获取响应
response = summarizer.get_response(
    "who is Paul Graham?", [text], tone_name="a Shakespeare play"
)

通过这些步骤,你可以利用LlamaIndex的响应合成器功能,根据具体需求生成和处理LLM的响应。

LlamaIndex中的响应合成模块

以下是每个响应合成器的详细输入/输出。

API示例

以下展示了利用所有关键字的设置。

  • response_mode 指定使用哪个响应合成器
  • service_context 定义用于合成的LLM和相关设置
  • text_qa_templaterefine_template 是在各个阶段使用的提示
  • use_async 目前仅用于tree_summarize响应模式,以异步构建总结树
  • streaming 配置是否返回流式响应对象
  • structured_answer_filtering 启用主动过滤与给定问题无关的文本块

synthesize/asynthesize函数中,你可以选择提供额外的源节点,这些节点将被添加到response.source_nodes列表中。

from llama_index.core.data_structs import Node
from llama_index.core.schema import NodeWithScore
from llama_index.core import get_response_synthesizer

response_synthesizer = get_response_synthesizer(
    response_mode="refine",
    service_context=service_context,
    text_qa_template=text_qa_template,
    refine_template=refine_template,
    use_async=False,
    streaming=False,
)

# 同步
response = response_synthesizer.synthesize(
    "query string",
    nodes=[NodeWithScore(node=Node(text="text"), score=1.0), ...],
    additional_source_nodes=[
        NodeWithScore(node=Node(text="text"), score=1.0),
        ...,
    ],
)

# 异步
response = await response_synthesizer.asynthesize(
    "query string",
    nodes=[NodeWithScore(node=Node(text="text"), score=1.0), ...],
    additional_source_nodes=[
        NodeWithScore(node=Node(text="text"), score=1.0),
        ...,
    ],
)

你也可以直接返回字符串,使用较低级别的get_responseaget_response函数:

response_str = response_synthesizer.get_response(
    "query string", text_chunks=["text1", "text2", ...]
)

通过这些API,你可以灵活地配置和使用LlamaIndex中的响应合成器,以满足不同的需求和场景。无论是同步还是异步,流式还是非流式,LlamaIndex都提供了丰富的选项来生成和处理LLM的响应。

  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Llamaindex是一个开源的搜索引擎,可以用于快速搜索和索引大型数据集。为了在本地部署Llamaindex,您需要按照以下步骤进行操作。 首先,您需要从Llamaindex的官方GitHub页面上下载源代码。确保您的计算机已安装了Git系统,然后使用命令行工具输入以下命令来克隆代码库: ``` git clone https://github.com/llama-lab/llamaindex.git ``` 下载完成后,进入项目文件夹并创建一个Python虚拟环境。使用以下命令可以创建一个虚拟环境: ``` python3 -m venv llama-env ``` 然后需要激活虚拟环境。在Mac和Linux系统下,使用以下命令: ``` source llama-env/bin/activate ``` 在Windows系统下,使用以下命令: ``` llama-env\Scripts\activate ``` 接下来,安装Llamaindex的依赖项。在虚拟环境运行以下命令: ``` pip install -r requirements.txt ``` 等待依赖项安装完成后,可以开始配置Llamaindex。编辑`config.yaml`文件,根据您的需求进行相应的修改。您可以设置数据集的路径、索引文件的位置和其他相关参数。 完成配置后,运行以下命令来创建索引: ``` python3 llama.py -f path/to/dataset ``` 上述命令的`path/to/dataset`应替换为实际的数据集路径。运行该命令后,Llamaindex会开始索引数据集。 当索引完成后,您可以使用以下命令来搜索索引的数据: ``` python3 llama.py -s "your search query" ``` 您可以将`"your search query"`替换为实际的搜索关键字。Llamaindex将返回与关键字匹配的结果。 以上就是在本地部署Llamaindex的步骤。祝您在使用Llamaindex时取得成功!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

需要重新演唱

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

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

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

打赏作者

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

抵扣说明:

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

余额充值