高级RAG技术、以及算法实现

知识库地址:Advanced RAG techniques

检索增强生成(Retrieval Augmented Generation, RAG)为大语言模型(Large Language Model, LLM)提供了一种机制,通过从数据源检索到的信息为其生成的答案提供依据。简而言之,RAG 结合了搜索技术和大语言模型的提示功能,即你请求模型在有了搜索算法提供的信息作为背景的基础上回答问题。这个查询请求和检索到的背景信息都会被整合到发给大语言模型的提示语中。

到了 2023 年,RAG 成为了基于大语言模型系统中最流行的架构。从结合了网络搜索引擎和大语言模型的问答服务,到数百种“与数据对话”的应用程序,许多产品几乎都是在 RAG 的基础上构建的。

即便在向量搜索领域,2019年利用 faiss 开发的基于嵌入技术的搜索引擎也受到了市场炒作的影响。诸如 chroma、weaviate.io 以及 pinecone 这些向量数据库的初创企业,是在现有的开源搜索索引基础上构建的 — 主要是 faiss 和 nmslib — 最近它们还增加了对输入文本的存储和一些新的工具功能。

在大语言模型(LLM)基础架构和应用领域,两个最为人所瞩目的开源库 — LangChain 与 LlamaIndex,它们分别在2022年10月和11月问世,仅间隔一个月。这两个库的创立受到了 ChatGPT 发布的鼓舞,并在2023年迅速流行起来。

这篇文章旨在整理和总结关键的高级 RAG(Retrieval-Augmented Generation)技术,并提供这些技术在 LlamaIndex 中实现的参考资料,以帮助其他开发者更深入地掌握这些技术。

现存的问题是,大多数教程只会选择性地介绍一两项技术,并详尽讲解其实现方式,却很少全面展示所有可用的工具和方法。

另外,LlamaIndex 和 LangChain 这两个令人瞩目的开源项目发展迅速,其文档的内容已经丰富到可以和2016年的机器学习教材相媲美。

初级 RAG

在本文中,RAG 处理流程的起始点是一批文本文档 —— 我们省略了在此之前的所有步骤,将它们交给了那些强大的开源数据加载工具,这些工具能够连接到各种数据源,从 Youtube 到 Notion 都不在话下。

图片

作者提出的方案,以及文中后续提到的所有方案

基础 RAG 案例 简述如下:首先,将文本切分成小段,然后利用某种 Transformer Encoder 模型将这些文本段转换为向量,并将这些向量存入一个索引库中。接着,为大语言模型(LLM)创建一个提示,指导模型根据我们在搜索步骤中找到的上下文来回答用户的问题。在实际运行过程中,我们使用同样的 Encoder 模型将用户的问题转换为向量,然后在索引库中进行搜索,寻找与这个查询向量最匹配的前几个(top-k)结果,从数据库中取回相应的文本段,并将这些文本作为上下文输入到大语言模型的提示中。

提示的Prompt是这样的:

图片

这是一个 RAG 提示的示例。

Prompt 工程 是提升你的 RAG 流程性能的一个成本效益高的方法。不妨先研究一下 OpenAI 提供的详尽的 prompt 工程指南。

虽然 OpenAI 作为大语言模型(LLM)的供应商处于市场领先地位,但你还有其他多种选择,例如 Anthropic 的 Claude,Mistral 的小型但功能强大的 Mixtral,Microsoft 的 Phi-2,以及众多开源选项,比如 Llama2,OpenLLaMA,Falcon 等,供你为 RAG 流程选用。

高级 RAG

接下来,我们将详细介绍高级 RAG 技术。这里展示了一个涵盖核心步骤和相关算法的示意图。为了使示意图更加清晰易懂,我们省略了一些逻辑循环和复杂的多步骤智能体行为。

图片

高级 RAG 架构的关键部分更像是一系列可选的技术手段,而非固定的设计蓝图。

示意图中的绿色部分代表了我们接下来要深入讨论的核心 RAG 技术,蓝色部分则代表文本。并不是所有高级 RAG 的理念都能在一张简单的图示中直观地展现出来,比如,一些用于扩展上下文的技术就被省略了 — 我们会在接下来的内容中逐步深入这些话题。

1. 分块与向量化

首先,我们需要创建一个向量索引库,用以表示我们文档内容的向量。然后,在程序运行过程中,我们会寻找所有这些向量与查询向量之间的最小余弦距离,以此来找到最匹配的语义含义。

1.1 选择合适的块大小

选择合适的块大小是一个关键问题

 这个决定基于你所采用的嵌入模型以及它能够处理的 Token 数量。例如,传统的 Transformer Encoder 模型,比如基于 BERT 的 Sentence Transformers,最多能处理 512 个 Token。而 OpenAI 的 ada-002 模型则能处理更长的序列,达到 8191 个 Token。但是,我们需要在确保大语言模型 (LLM) 有充分的上下文进行推理生成足够具体的文本嵌入以高效进行搜索之间找到一个平衡点。此处 有一篇研究详细讨论了如何选择块大小。在 LlamaIndex 中,这一问题可以通过 NodeParser 类 来解决,该类提供了一些高级功能,比如自定义文本分割器、元数据以及节点/块之间的关系等。

1.2 数据向量化 

接下来,我们需要选择一个模型来处理并嵌入数据段 — 有许多可供选择的模型,我倾向于使用如 bge-large 或 E5 这样的为搜索而优化的嵌入模型 — 想要了解最新的模型表现,可以查阅 MTEB 排行榜。

想要了解从数据分段到向量化完整流程的一体化实施,请参考 LlamaIndex 中的一个完整数据处理流程示例。

2. 构建搜索索引

2.1 构建向量索引库

图片

在本文中,为了简化说明,我没有包括编码器(Encoder)环节,而是直接将查询内容送入索引。当然,在这个过程中,查询内容首先会被转换成向量形式。关于最匹配的前 k 个结果(top k chunks)也是同理 — 索引返回的是最匹配的前 k 个向量,并非实际的数据段。不过,我在这里用“数据段”来代指这些向量,因为从向量中恢复出数据段是一个非常简单的操作。

RAG处理流程的核心是搜索索引,这个索引负责存储我们之前步骤中生成的向量化数据。最基本的实现方法是采用平面索引 —— 这种方法会直接计算查询向量与所有数据块向量之间的距离。

为了在拥有超过 10000+ 数据点的大规模集合中实现高效的信息检索,我们需要一个经过优化的搜索索引,也就是向量索引,比如 faiss、nmslib 或 annoy 这样的工具,它们采用了近似最近邻技术,比如聚类、树结构或 HNSW 算法来实现。

除了 OpenSearch 或 ElasticSearch 这类托管解决方案,还有如 Pinecone、Weaviate 或 Chroma 这样的向量数据库,它们能够自动处理数据摄取流程。

在你的索引选择、数据和搜索需求的基础上,你可以将元数据与向量一同存储,并利用元数据过滤器来精确搜索,比如根据特定的日期或数据来源进行筛选。

LlamaIndex 不仅支持多种向量存储索引,还支持其他一些更为简单的索引方式,包括列表式索引、树状索引和关键字表格索引。关于这些索引方式的更多细节,我们会在后续的融合检索部分进行详细介绍。

2. 2 层级索引

图片

当您需要从大量文档中检索信息时,高效的搜索、定位相关内容并整合成一个提及来源的完整答案就显得尤为重要。对于庞大的数据库,一个高效处理的策略是建立两种索引 —— 一种是基于文档摘要的索引,另一种是基于文档片段的索引。这样可以通过两阶段的搜索来操作:首先利用摘要索引过滤出相关的文档,然后在这些筛选出的文档中进行深入搜索。

2.3 假设性问题与 HyDE 方法

另一种策略是指导大语言模型(LLM)为每段文本生成一个问题,并将这些问题转化为向量形式。在实际操作中,通过与这些问题向量构成的索引进行查询搜索(即在索引中将文本块的向量替换为问题的向量),检索到相关问题后,再追溯到原始的文本段落,并把这些段落作为上下文提供给大语言模型,以此来得到答案。这种方法能够提升搜索的准确性,因为与实际文本块相比,查询内容与生成的假设性问题之间存在着更高的语义相似性

有一种被称为 HyDE 的逆向逻辑方法 —— 你可以指导一个大语言模型(LLM)根据查询生成一个理论上的文档,然后将此文档的向量与查询的向量结合使用,以此来增强搜索的准确性和效率。

2.4 丰富检索上下文

核心思想是检索更小的信息片段以提升搜索的准确性同时附加相关上下文以便大语言模型 (LLM) 进行逻辑推理。有两种策略 —— 一是在已检索的小片段周围增加句子来扩展上下文,二是将文档递归划分为多个更大的父级片段,这些父级片段中包含了更小的子片段。

图片

2.4.1 句子窗口检索技术 在这种方法中,文档的每个句子都分别进行嵌入处理,这样做能够极大提高根据查询与上下文之间的余弦距离进行搜索的准确度。为了在找到最相关的那一句话后更好地分析整个上下文,我们会在提取出的句子的前后扩展出一个包含 k 个句子的窗口,然后将这个更广的上下文送至大语言模型 (Large Language Model) 进行处理。

图片

搜索索引时,标记为绿色的部分代表找到的句子嵌入,这是进行精确搜索的关键信息。而将这个绿色部分与周围的黑色文本一起组成的段落,会一同输入到大语言模型(LLM)中,目的是在处理查询时能够考虑到更加广泛的上下文信息。

2.4.2 自动合并检索技术 (也称作 父级文档检索技术)

这一技术的核心思想与“句子级窗口检索”类似 —— 它首先寻找更具体的信息片段,然后在将这些片段提供给大语言模型(LLM)进行逻辑推理前,扩大其上下文范围。具体做法是将文档分割成更小的子片段,并将这些子片段与它们所属的更大的父片段关联起来。

图片

文档被拆分成多层次的块结构,最小的叶子块随后会被加入索引。在检索阶段,我们会获取 k 个叶子块,如果这些块中有 n 个以上属于同一个父块,那么我们会用这个父块来代替它们,并把父块提交给大语言模型(LLM)来生成答案。

先检索较小的块,如果在最初检索到的 k 个块中,超过 n 个块与同一个父节点相关联,我们就用这个父节点来替换给 LLM 的上下文。这种方法相当于自动把多个检索到的小块合并成一个大的父块。值得一提的是,搜索仅限于子节点的索引范围内。想要更深入的了解,可以查阅 LlamaIndex 提供的递归检索器 + 节点引用教程。

2.5 融合检索或混合搜索

在信息检索领域,有一个经典的概念:结合传统的基于关键词的搜索技术 —— 例如稀疏检索算法 tf-idf 和被广泛认可的搜索行业标准 BM25 —— 以及现代的语义或向量搜索技术,把它们融合到同一个检索结果中。 关键在于如何有效地融合这些具有不同相似度分数的检索结果。这一挑战通常可以通过 Reciprocal Rank Fusion 算法来克服,该算法通过重新排列检索结果来优化最终输出。

图片

在 LangChain 平台,Ensemble Retriever 类的设计允许结合多个检索器,比如 faiss 向量索引和 BM25 检索器,并利用 RRF(Reciprocal Rank Fusion)算法对结果进行重排序。

而在 LlamaIndex 平台,采取了类似的方法来实现这一功能。

通常,融合搜索或混合搜索能够带来更优的检索效果。这种方法通过结合两种互补的算法——语义相似性搜索和关键词匹配搜索,充分利用了它们各自的优势,以更准确地匹配查询和文档库中的内容。

3. 重排序与过滤

我们已经使用了上面描述的算法获得了检索结果,现在需要通过过滤、重排序或者进行一些转换来对这些结果进行优化。LlamaIndex 提供了一系列的后处理器,可以根据相似度得分、关键词、元数据来过滤结果,或者利用大语言模型(LLM)、句子转换器交叉编码器和 Cohere 的重排序端点来进行重排序,甚至可以根据元数据的日期新旧来调整——几乎可以满足你所有的想象。

这是在提交检索内容给大语言模型(LLM)以获取答案之前的关键一步。

接下来,我们将采用更为高级的 RAG 技术,包括查询转换和路由。这两种技术都需要用到大语言模型,它们体现了AI 智能体的行为 —— 在我们的 RAG 流程中融入了涉及大语言模型推理的复杂逻辑。

4. 查询转换

查询转换指的是一组技术,通过利用大语言模型(LLM)作为推理引擎,对用户的输入进行修改,旨在提升检索的准确性。 为此,我们有多种方法可供选择。

图片

展示的查询转换原理

当遇到复杂的查询时,大语言模型(LLM)能够将其拆分成多个子查询。例如,如果你提出这样的问题:—— “在Github上,Langchain和LlamaIndex哪个项目的星标更多?”, 我们的语料库中不太可能直接包含这两个项目的比较。因此,将这个问题拆分为两个假设更为简单且具体的信息检索子查询是合理的:—— “Langchain在Github上有多少星标?” —— “LlamaIndex在Github上有多少星标?” 这两个查询将同时进行,随后将得到的上下文信息合并成一个提示,以便大语言模型综合出对原始问题的最终答案。Langchain和LlamaIndex都实现了这样的功能 —— 分别是作为Langchain中的多查询检索器(Multi Query Retriever)和LlamaIndex中的子问题查询引擎(Sub Question Query Engine)。

  1. 步退提示法 利用大语言模型 (LLM) 来生成更抽象的查询问题,通过这种方式,我们能够获得一个更宏观或高级的背景知识,这有助于我们将原始问题的答案建立在这个背景之上。原始问题也会进行信息检索,这两部分的背景知识将在最终生成答案的步骤中输入到大语言模型。这是LangChain的一个实践案例。

  2. 查询改写通过大语言模型 (LLM) 对初始查询进行重新表述,目的是提升信息检索的效果。LangChain和LlamaIndex都提供了相应的实现方案,虽然它们各有特点,但我认为LlamaIndex的方案在这方面更具优势。这是LangChain的一个实践案例,这是LlamaIndex的一个实践案例。

参考文献引用

此项没有编号,因为它更类似于一个工具,而不是一种检索优化技术,但它的重要性不言而喻。 当我们为了生成答案而参考了多个资料源,不管是因为初始查询的复杂性(需要执行多个子查询并整合得到的上下文信息以形成一个完整的答案),还是因为我们在多个文档中发现了对单个查询有关的上下文,就会产生一个问题:我们是否能够精确地引用我们所参考的资料源

  1. 在我们的查询中加入引用来源的任务,并指示大语言模型(LLM)标明其引用资料的 id。

  2. 将生成的回答内容与我们数据库中的原始文本进行对比 — llamaindex 提供了一种有效的模糊匹配方案,适用于这类需求。如果你对模糊匹配还不太了解,它实际上是一种极为有效的文本匹配技巧。

5. 聊天引擎

在构建能够对同一查询多次响应的高效 RAG 系统方面,下一个关键点是 聊天逻辑,这一逻辑需充分考虑对话的上下文,正如在大语言模型(LLM)出现之前的传统聊天机器人所做的那样。为了能够处理跟进问题、代词指代或与先前对话上下文有关的用户指令,需要这样的逻辑。这个问题可以通过 查询压缩技术,同时考虑到聊天上下文 和用户的查询来得到解决。

在聊天引擎的上下文压缩领域,我们有多种可选的方法。其中,一种广受欢迎且操作简便的方法是 ContextChatEngine,它的工作原理是先找到与用户问题相关的上下文信息,再把这些信息和之前的聊天记录一起,从记忆缓冲区发送给大语言模型(LLM,Large Language Model),确保 LLM 在回答下一个问题时,能够融入之前的对话上下文。

另一个更为高级的例子是 CondensePlusContextMode —— 在这种模式下,每次交互时,都会将聊天记录和最新的消息整合压缩成一个新的查询请求。这个请求随后被发送到索引系统中,系统会找到相关的上下文信息,并将这些信息连同用户的原始消息一起传递给 LLM,以此来生成回答。

另外,LlamaIndex 还提供了一个基于 OpenAI 智能体的聊天引擎(OpenAI agents based Chat Engine),这个引擎能够让用户享受到更加自由的聊天体验。同时,Langchain 也兼容 OpenAI 的多功能 API(supports),增强了聊天智能体的实用性。

图片

不同聊天引擎类型及其工作原理简述

除了 ReAct Agent 这样的聊天引擎外,我们还可以在第 7 节中详细了解各种智能体的具体情况。

6. 查询路由

查询路由是指在接收到用户的查询请求后,由大语言模型(LLM)决定下一步该如何处理 —— 常见的处理方式包括提炼信息摘要、在数据索引中进行搜索,或者尝试多条处理路径并将结果综合起来形成一个完整的答案。

查询路由器的另一个作用是选择一个索引,或者更广泛来说,选择一个数据存储来处理用户的查询 —— 这可能涉及到多个数据来源,比如传统的向量存储、图形数据库或关系型数据库,或者是层次化的索引系统 —— 在处理多文档存储时,常见的做法是使用一个摘要索引和另一个文档片段向量索引。

设置查询路由器,就是定义它可以做出哪些选择。 选择一个路由方案是通过大语言模型(LLM)的调用来完成的,它按照预先定义的格式返回结果,这些结果用来指导查询到特定的索引。如果我们考虑到更加复杂的情况,这也可能包括将查询发送到子链或者如多文档智能体架构所示的其他智能体。

LlamaIndex 和 LangChain 都提供了查询路由功能的支持。

7. RAG 中的 AI 智能体

AI 智能体(同时得到了 Langchain 和 LlamaIndex 的支持)自大语言模型(LLM)的 API 首次发布不久后便出现了 —— 其核心理念是赋予一个具有推理能力的大语言模型(LLM)一系列工具和一个需要解决的任务。这些工具可能涵盖从固定的代码函数到外部 API,乃至其他 AI 智能体的各种功能 —— 正是这种将多个 LLM 连接起来的创意,成为了 LangChain 这一名称的灵感来源。

AI 智能体本身就是一个庞大的主题,要在 RAG 的概述中深入探讨显然不现实。因此,我将直接转向基于智能体的多文档检索案例,并简要介绍一下 OpenAI 助手,这是一个较新的概念,在最近的 OpenAI 开发者大会上作为 GPT 系列模型的一部分被展示,它在我们即将介绍的 RAG 系统中扮演着重要的角色。

OpenAI 助手 集成了许多之前在开源社区中常见的大语言模型(LLM)相关工具 —— 包括聊天历史的管理、知识库的构建、文档上传的接口,以及可能是最关键的一项,函数调用 API。这项 API 的功能是将用户的自然语言指令转换为可以操作外部工具或进行数据库查询的 API 调用。

在 LlamaIndex 中,OpenAIAgent 类融合了先进的逻辑处理能力,并与 ChatEngine 及 QueryEngine 类协同工作。它不仅能进行具有知识背景和对话情境感知的聊天,还能在单轮对话中实现多个 OpenAI 功能的调用,极大地增强了 AI 智能体的智能行为。

让我们来了解一下多文档智能体架构 —— 这是一个复杂的配置,它包括为每个文档初始化一个能够执行文档摘要和传统问答任务的智能体(OpenAIAgent),以及一个主智能体,负责向文档智能体分配查询任务并整合最终的答案。

每个文档智能体配备了两种机制:一个是向量存储索引,另一个是摘要索引。它会根据接收到的查询内容决定使用哪一种机制。至于主智能体,它将所有的文档智能体视为各自独立的组件。

这一架构体现了一个复杂的 RAG(检索增强生成)体系,其中每个参与的智能体都要进行复杂的决策。这种做法的优势在于,它能够对比在不同文档及其摘要中描述的不同解决方案或实体,并且还包括了传统的单文档摘要和问答机制 —— 这基本上覆盖了最常见的文档集合互动场景。

图片

这个方案展现了多文档智能体的工作原理,包括查询的路由分配和智能体的行为模式。

这一复杂架构的劣势可以从理论上推断出来 —— 由于需要与智能体内部的大语言模型 (LLMs) 多次进行交互,处理速度相对较慢。需要注意的是,在 RAG(检索增强生成)流程中,调用大语言模型通常是耗时最长的步骤 —— 相比之下,搜索操作是为了速度而专门优化的。因此,对于庞大的多文档数据库,建议对这种架构进行简化,以提高其可扩展性。

8. 答案合成步骤

这是任何 RAG 流程的最终环节 —— 结合我们精心检索的所有上下文信息和用户的初始查询来构建答案。最直接的做法是把所有相关性较高的上下文信息与查询问题一并输入到一个大语言模型(LLM)中。然而,还有更多高级的方法,这些方法通过多次调用大语言模型来精炼上下文信息,以此来得出更加准确的答案。

答案合成的主要方法包括:

  1. 逐步优化答案,将检索到的上下文信息分批次输入大语言模型

  2. 压缩上下文信息,使其简洁到足以适配提示

  3. 根据不同的上下文信息生成多个答案,再将这些答案整合或概括。更多详细信息,请参阅答案合成模块文档。

编码器与大语言模型微调

这个方法包括对 RAG 流程中的两个深度学习模型进行微调 —— 一个是 Transformer 编码器,它负责生成高质量的嵌入表示,从而确保上下文的准确检索;另一个则是 大语言模型(LLM),它的任务是充分利用提供的上下文来回答用户的问题 —— 值得庆幸的是,后者非常擅长少样本学习。

现在的一个显著优势是我们可以使用像 GPT-4 这样的先进大语言模型来创建高品质的合成数据集。但是,你应该始终记住,直接使用由专业研究团队在大型、经过精心筛选、清洗和验证的数据集上训练的开源模型,并且仅用小型合成数据集进行快速微调,可能会限制模型的整体性能。

编码器(向量嵌入模型)微调

我一直对对 Encoder 的微调持有保留态度,毕竟针对搜索优化的最新 Transformer Encoder 已经相当高效。但在 LlamaIndex 示例中对 bge-large-en-v1.5 进行微调的测试(该模型在本文撰写之时在 MTEB 排行榜上位列前四)显示,微调确实能使检索的质量提升 2%。虽然这一提升并不惊人,但了解这一选项还是很有价值的,尤其是当你在为特定领域的数据集构建 RAG 时。

重排序模型微调

另一个常用的选择是采用 cross-encoder 来对检索结果进行重排,特别是当你对基础 Encoder 的准确性存疑时。其工作原理是这样的:你需要将查询语句和每一个 top k 的检索文本块传递给 cross-encoder,文本块之间插入一个 SEP Token(分隔 Token)作为分隔,并对其进行微调,使其对相关的文本块输出 1,对不相关的输出 0。一个关于这种微调过程的优秀示例可以在这里找到,结果表明通过 cross-encoder 的微调,成对比较的得分提高了 4%。

大语言模型微调

OpenAI 最近推出了大语言模型(LLM)的微调 API,LlamaIndex 也发布了一个教程,介绍如何在 RAG(检索式问答)环境下对 GPT-3.5-turbo 进行微调,以便“吸收”GPT-4 的知识。这个过程包括:使用 GPT-3.5-turbo 从文档中生成问题,再利用 GPT-4 根据文档生成答案,以此建立一个基于 GPT-4 的 RAG 流程,并用这些问题和答案对 GPT-3.5-turbo 进行微调。通过 ragas 框架进行的 RAG 流程评估表明,微调后的 GPT-3.5-turbo 在“真实性度量”上提升了 5%,这意味着微调后的模型在生成答案时,能够更有效地利用给定的上下文信息。

在 Meta AI 研究的最新论文 RA-DIT: Retrieval Augmented Dual Instruction Tuning 中,提出了一种同时对大语言模型(LLM)和检索器(原文中称为 Dual Encoder)进行调优的技术,这种技术针对的是查询、上下文和答案组成的数据三元组。具体的实施细节可以参考这份指南。运用这一技术,不仅可以通过微调 API 提升 OpenAI 的大语言模型性能,还可以优化 Llama2 开源模型(如原论文所述),结果显示,在知识密集型任务的性能指标上平均提高了约 5%(相较于使用 RAG 的 Llama2 65B 模型),并且在常识推理任务上也有数个百分点的性能提升。

如果你有关于 RAG 微调大语言模型(LLM)的更佳方法,请在下方讨论区分享你的见解,尤其是那些已经应用于小型开源 LLM 的技术。

评估

针对 RAG 系统性能评估,我们有多种框架可供选择。这些框架通常包括几个独立的评估指标,比如答案的相关性、准确性、一致性和检索内容的相关性

目前存在多种针对 RAG 系统性能评估的框架,它们通常包含几个独立的评估指标,如答案的相关性、准确性、可靠性以及检索内容的相关性

在之前的讨论中,我们提到了Ragas框架,它采用了知识忠实度(faithfulness)和答案相关性(answer relevance)作为衡量生成答案质量的核心指标。同时,对于 RAG 模式中的信息检索部分,Ragas 使用了标准的精确度(precision)和召回率(recall)作为评估指标。

在由 Andrew NG 推出的最新短课程构建与评估高级 RAG (Building and Evaluating Advanced RAG)中,课程内容涉及 LlamaIndex 和评估框架Truelens,它们强调了 RAG 三要素 —— 检索上下文的查询相关性根据性(LLM 回答与所提供上下文的吻合程度)以及答案对查询的相关性

最关键且可控的评价指标是检索上下文的相关性 — 这实际上包括了先前描述的高级 RAG 流程的前七个环节,以及对 Encoder 和 Ranker 的细致微调,目的都是为了提高这一指标。而流程的第八部分和对 LLM 的微调则专注于答案的相关性和可靠性。

一个简洁明了的检索器评估流程的实例可以在这里找到,并且它已经在 Encoder 微调环节中得到应用。更进一步的评估方法不仅仅考虑命中率,还包括了平均倒数排名(Mean Reciprocal Rank)这一搜索引擎常用的评价指标,以及对生成答案的准确性和相关性的评估,可以在 OpenAI 的食谱中找到相应的演示。

LangChain 推出了一套高级的评估框架 LangSmith,不仅可以自定义评估器,还能实时监控您的 RAG 管道运行情况,确保系统运作的可视化和透明化。

对于使用 LlamaIndex 进行开发的用户,可以利用 rag_evaluator llama pack 这一工具包,它能够帮助您快速地使用公开数据集对管道进行评估。

总结

在这篇文章中,我尽力阐释了 RAG 技术的核心算法原理,并展示了其中的一些实例。我的目的是希望这些内容能够为你的 RAG 管道带来灵感,或者帮助你理解今年涌现出的众多创新技术 — 对我个人而言,2023 年无疑是机器学习领域迄今最令人兴奋的一年。

除此之外,还有更多值得关注的领域,例如由 LlamaIndex 开发的基于网络搜索的 RAG(可重复使用的答案生成器,RAGs),webLangChain 等项目。这些项目深入挖掘了 AI 智能体 架构的潜力,正如最近 OpenAI 对这一领域的重大投资 所示。同时,关于 大语言模型(LLMs)的长期记忆能力 的探索也提出了一些新思路。

除了要确保答案的相关性和可信度,RAG(可重复使用的答案生成器)系统面临的一个主要挑战是提高响应速度,这一点尤其重要,如果你倾向于采用更为灵活的 AI 智能体架构。但具体细节,我们留待另一篇文章讨论。ChatGPT 以及其他多数助手采用的实时响应功能,并不是为了追求某种赛博朋克风格,而是为了缩短用户感知到的答案生成时间。正因为此,我相信小型的大语言模型(LLMs)有着光明的未来。最近,Mixtral 和 Phi-2 的推出正是引领我们走向这个方向的先锋。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/326276.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C语言--质数算法和最大公约数算法

文章目录 1.在C语言中,判断质数的常见算法有以下几种:1.1.试除法(暴力算法):1.2.优化试除法:1.3.埃拉托色尼筛法:1.4.米勒-拉宾素性检验:1.5.线性筛法:1.6.费马小定理&am…

【前端发版】vue前端发版 步骤

1、 提交代码 代码合并通过之后到deb分支 2、git checkout 切换到dev分支上 运行起来看看自己刚刚提交的代码有没有错误 3、拉取最新代码 git pull 3、yarn run build 4、打包好的文件叫dist 重新命名为服务器里替换包名 5、登录文件传输 开始替换 替换的过程中 首先删除备…

如何一台电脑操作两个adb 设备

1.首先使用 adb devies 命令 2.然后使用 adb -s 上面的返回的id号 shell 进入对应的开发板

优化您的服务请求,增强用户体验和服务交付

您的服务请求模板是否像一个复杂的迷宫,给您的团队带来延误和困惑?您的技术人员是否厌倦了为了解最终用户的需求而与他们来回奔波?强大且可定制的请求模板可能正是您所需要的! 服务交付团队(尤其是 IT)的…

ubuntu服务器安装Slurm

相关内容,网上不少,这里记录一下自己出现的问题和解决方法,采用的是Ubuntu22.04,方法可以参考知乎上面这篇文章Ubuntu服务器安装配置slurm,整个安装过程没有什么问题,主要步骤贴在这里但在使用过程中&#…

Vue3响应式系统(一)

一、副作用函数。 副作用函数指的是会产生副作用的函数。例如:effect函数会直接或间接影响其他函数的执行,这时我们便说effect函数产生了副作用。 function effect(){document.body.innerText hello vue3 } 再例如: //全局变量let val 2f…

【MATLAB】Linux版本 高分辨率屏 调整显示缩放

0 引言 安装了linux版本的MATLAB R2023b之后,发现工具栏字体很小不方便使用,所以上网找到了MATLAB论坛上某位大佬的教程:参考链接,放在这里供各位参考 。 1 环境 这里注明我的matlab安装环境仅供参考,未在其他环境下…

Java基础 - 黑马

我是南城余!阿里云开发者平台专家博士证书获得者! 欢迎关注我的博客!一同成长! 一名从事运维开发的worker,记录分享学习。 专注于AI,运维开发,windows Linux 系统领域的分享! 知…

msvcp140.dll丢失都有什么办法可以解决呢?分享几种解决办法

msvcp140.dll是Windows操作系统中的一个重要动态链接库文件,它与许多软件的正常运行密切相关。当系统或软件无法找到或访问到该dll文件时,就会出现msvcp140.dll丢失的问题。这可能导致某些软件无法启动或崩溃,给用户带来不便。为了解决这个问…

Proxy的使用方法和13种拦截操作

前言 proxy是ES6新推出的方法,功能很强大。属于元编程,也就是修改js本身的一些东西。可以对数组,对象,函数等引用类型的对象进行一些复杂的操作。 其中,大部分人应该最熟悉的莫过于vue3中使用proxy替换了defineProperty,而且还实现了本身defineProperty不能实现的一些东西。 …

GO——gin中间件和路由

中间件 参考:https://learnku.com/articles/66234 结构 中间件是函数中间件函数被放在调用链上调用链的末尾是路由path对应的函数 执行过程 net/http包调用到gin的serverHTTP 参考:go/pkg/mod/github.com/gin-gonic/ginv1.7.7/gin.go:506 通过path找到…

FlinkSQL【分组聚合-多维分析-性能调优】应用实例分析

FlinkSQL处理如下实时数据需求: 实时聚合不同 类型/账号/发布时间 的各个指标数据,比如:初始化/初始化后删除/初始化后取消/推送/成功/失败 的指标数据。要求实时产出指标数据,数据源是mysql cdc binlog数据。 代码实例 --SET t…

【.net core】yisha框架,bootstrap-table组件增加固定列功能

需要引入 bootstrap-table-fixed-columns.css和bootstrap-table-fixed-columns.js文件 文件代码: bootstrap-table-fixed-columns.css样式文件代码 .fixed-table-header-columns, .fixed-table-body-columns {position: absolute;background-color: #fff;displa…

【Vue3】3-2 : 组件的概念及组件的基本使用方式

本书目录:点击进入 一、组件的概念 1.1、【案例】评分组件与按钮组件的抽离过程 二、组件的使用 - 抽离结构 2.1、【案例】简易首页 > 效果 > 代码 - 原始 > ​​​​​​​代码 - 组件抽离结构 > ​​​​…

【汇编】实验11 编写子程序

综合一下学过的指令就行了,比较简单。 assume cs:code data segmentdb "Beginners All-purpose Symbolic Instruction Code.",0 data ends code segment begin:mov ax,datamov ds,axmov si,0call lettercmov ax,4c00hint 21h letterc:mov cl,[si]mov ch,…

【线路图】世微AP5160宽电压降压型恒流芯片 LED电源 带调光SOT23-6

这是一款14-18V 3A 电流的PCB设计方案. 运用的是世微AP5160 电源驱动IC,这是一款效率高,稳定可靠的 LED 灯恒流驱动控制芯片,内置高精度比较器,固定 关断时间控制电路,恒流驱动电路等,特别适合大功率 LED 恒流驱动。 …

Wpf 使用 Prism 实战开发Day12

待办事项接口增删(CURD)改查实现 一.添加待办事项控制器(ToDoController) 控制器类需要继承 ControllerBase 基类需要添加 [ApiController] 特性以及 [Route] 特性Route(路由) 特性参数规则,一般…

pycharm debug显示的变量过多

问题: https://blog.csdn.net/Hodors/article/details/117535731 解决方法: 把"Show console variables by default"前面的勾取消掉就行 参考: https://stackoverflow.com/questions/48969556/hide-console-variables-in-pychar…

【Leetcode 程序员面试金典 02.08】 —— 环路检测 |双指针

面试题02.08. 环路检测 给定一个链表,如果它是有环链表,实现一个算法返回环路的开头节点。若环不存在,请返回null。 如果链表中有某个节点,可以通过连续跟踪next指针再次到达,则链表中存在环。 为了表示给定链表中的…