AI知识库

53AI知识库

学习大模型的前沿技术与行业应用场景


探索RAG
发布日期:2024-05-13 07:15:17 浏览次数: 1747


背景


大语言模型(LLM)是生成类人文本的强大工具,但也有局限性。检索增强生成(RAG)通过整合检索机制来增强 LLM,从而应对这些挑战。这种方法可确保 LLM 生成的内容既与上下文相关,又符合事实。RAG 就像一座桥梁,将 LLM 与庞大的知识源连接起来。随着人工智能越来越多地用于各种任务,所生成信息的准确性和相关性至关重要。

LLM 可以描述为一种新型操作系统的内核进程。正如现代计算机拥有内存和文件访问权限一样,LLM 也拥有一个上下文窗口,可以加载从众多数据源检索到的信息。

这些检索到的信息被加载到上下文窗口中,并用于 LLM 输出生成,这一过程通常称为检索增强生成(RAG)。RAG 是 LLM 应用程序开发中最重要的概念之一,因为它是一种将外部信息传递给 LLM 的简便方法,在需要实际调用的问题上,它比更复杂的微调更具优势。

通常情况下,RAG 系统涉及:一个决定要检索哪些信息的问题(通常来自用户)、一个从数据源(一个或多个数据源)检索该信息的过程,以及一个将检索到的信息作为prompt的一部分直接传递给 LLM 的过程。

挑战


尽管 RAG 取得了成功,但它也存在一些挑战,主要为以下几点。

查询转换


在考虑 RAG 时,首先要考虑的问题是:如何保证问题和检索内容相关?例如,用户的问题可能措辞不当,无法完成具有挑战性的检索任务。查询转换是一套侧重于修改用户输入以改进检索的方法。

查询扩展


考虑这样一个问题:“湖人和凯尔特人哪个队获得冠军次数多?”。在回答这个问题时,可以提出两个具体的子问题:

  • 湖人获得多少次冠军?

  • 凯尔特人获得多少次冠军?

查询扩展将输入分解为子问题,每个子问题都是一个更小的检索。参考

  • https://python.langchain.com/docs/modules/data_connection/retrievers/MultiQueryRetriever

  • https://github.com/langchain-ai/langchain/blob/master/cookbook/rag_fusion.ipynb

  • https://github.com/langchain-ai/langchain/blob/master/cookbook/stepback-qa.ipynb


查询重写


为了解决框架或措辞不当的用户输入,Rewrite-Retrieve-Read是一种重写用户问题以改进检索的方法。

参考:

https://arxiv.org/pdf/2305.14283.pdf

https://github.com/langchain-ai/langchain/blob/master/cookbook/rewrite.ipynb

查询压缩


在一些 RAG 应用程序中,例如 WebLang(langchain的开源研究助手),用户问题遵循更广泛的聊天对话。为了正确回答问题,可能需要完整的对话上下文。为了解决这个问题,langchain使用如下提示将聊天记录压缩为最后一个问题以供检索。

提示:https://smith.langchain.com/hub/langchain-ai/weblangchain-search-query?organizationId=1fa8b1f4-fcb9-4072-9aa9-983e35ad61b8

路由


在考虑 RAG 时要问的第二个问题:数据在哪里?在许多 RAG 演示中,数据位于单个向量存储中,但在生产环境中通常并非如此。在一组不同的数据存储中操作时,需要路由传入查询。LLM 可用于有效地支持动态查询路由。

参考:https://python.langchain.com/docs/expression_language/how_to/routing

查询构造


在考虑 RAG 时要问的第三个问题:查询数据需要什么语法?虽然路由问题使用自然语言,但数据存储在需要特定语法才能检索的关系数据库或图形数据库等源中。甚至矢量存储也利用结构化元数据进行过滤。在所有情况下,都需要将查询中的自然语言转换为查询语法以进行检索。

  • Text-to-SQL

    相当多的努力集中在将自然语言转换为 SQL 请求上。通过向LLM提供自然语言问题以及相关的表格信息,可以轻松完成文本到 SQL;事实证明,开源LLM在这项任务上非常有效。

    关系数据库中的混合类型(结构化和非结构化)数据存储越来越普遍;可以使用 PostgreSQL 的开源 pgvector 扩展来包含嵌入式文档列。还可以使用自然语言与这种半结构化数据进行交互,将 SQL 的表达能力与语义搜索结合起来。

    参考:https://python.langchain.com/docs/expression_language/cookbook/sql_db

  • Text-to-Cypher

    虽然向量存储可以轻松处理非结构化数据,但它们并不了解向量之间的关系。虽然 SQL 数据库可以为关系建模,但schema更改可能会造成破坏,而且成本高昂。知识图谱可以通过对数据之间的关系建模来应对这些挑战,并在不进行大修的情况下扩展关系类型。知识图谱适用于具有多对多关系或难以用表格形式表示的层次结构的数据。

    与关系数据库一样,图数据库也受益于使用文本到 Cypher的结构化查询语言。

    参考:https://blog.langchain.dev/using-a-knowledge-graph-to-implement-a-devops-rag-application/

  • Text-to-metadata filters

    配备元数据过滤功能的 Vectorstore 可以通过结构化查询来过滤嵌入的非结构化文档。自查询检索器可以使用向量存储中存在的元数据字段的规范,通过元数据过滤器将自然语言转换为这些结构化查询。


索引


在考虑 RAG 时要问的第四个问题:如何设计我的索引?对于向量存储,有相当大的机会来调整参数,如块大小和/或文档嵌入策略,以支持可变数据类型。

块大小


OpenAI 对 RAG 策略的回顾中强调了他们仅仅通过在文档嵌入过程中测试调整块大小就显著提升了性能。这是有道理的,因为块大小控制着我们加载到上下文窗口(或我们的 LLM 操作系统比喻中的 "RAM")中的信息量。

由于这是索引构建的核心步骤,可以在https://langchain-text-splitter.streamlit.app/测试各种分块大小,以获得一些直观感受;尤其值得注意的是,使用各种分块大小或策略时,文档被分割的位置,以及语义相关的内容是否被不自然地分割。

文件嵌入策略


索引设计中最简单、最有用的想法之一,就是将嵌入的内容(用于检索)与传递给 LLM 的内容(用于答案合成)分离开来。例如,考虑一大段包含大量冗余细节的文本。为了提高检索效率,我们可以嵌入一些不同的表示方法,例如摘要或缩小嵌入信息范围的小块。在这两种情况下,我们都可以检索出全文,然后传递给 LLM。这些可以分别使用multi-vector和multi-vector来实现。

multi-vector检索器还能很好地处理包含文本和表格的半结构化文档。在这种情况下,我们可以提取每个表格,生成适合检索的表格摘要,但将原始表格返回给 LLM 进行答案合成。

我们可以更进一步:随着多模态 LLM 的出现,可以使用生成和嵌入图像摘要作为包含文本和图像的文档的图像检索的一种方法(见下图)。

这可能适用于多模态嵌入不希望可靠地检索图像的情况,例如复杂的图形或表格的情况。

后续处理

考虑 RAG 时要问的最后一个问题:如何合并我检索到的文档?这很重要,因为上下文窗口的大小有限,并且冗余文档(例如,来自不同来源)将利用令牌,而不向LLM提供独特的信息。已经出现了许多文档后处理方法(例如,提高多样性或过滤新近度)。

重新排名


当我们检索大量文档时,Cohere ReRank可用于文档压缩(减少冗余)。与此相关的是,RAG-fusion 使用相互融合排名对检索器返回的文档进行重新排名(类似于多查询)。参考:

https://python.langchain.com/docs/modules/chains/how_to/openai_functions

https://github.com/langchain-ai/langchain/blob/master/cookbook/rag_fusion.ipynb

分类


OpenAI 根据其内容对每个检索到的文档进行分类,然后根据该分类选择不同的提示。这将用于分类的文本标记与基于标签的逻辑路由结合起来。



53AI,企业落地应用大模型首选服务商

产品:大模型应用平台+智能体定制开发+落地咨询服务

承诺:先做场景POC验证,看到效果再签署服务协议。零风险落地应用大模型,已交付160+中大型企业

联系我们

售前咨询
186 6662 7370
预约演示
185 8882 0121

微信扫码

与创始人交个朋友

回到顶部

 
扫码咨询