Advertisement

『大模型笔记』检索增强生成(RAG):从理论到LangChain实践

阅读量:

检索增强生成(RAG)是一种结合检索技术与大语言模型(LLM)的方法,旨在通过从外部知识库中检索相关信息来增强LLM的生成能力。该方法通过将LLM与检索器模块结合使用,在向量数据库中存储外部知识源,并利用提示模板进行信息整合,从而提高模型的回答准确性和相关性。与传统的微调方法相比,RAG更灵活高效地补充外部知识以应对特定领域或专有信息的介绍了RAG的基本理论、解决方案及其在实际应用中的实现方式,并通过Python代码展示了如何利用LangChain框架结合OpenAI和Weaviate工具构建一个完整的检索增强生成流程。

检索增强生成(RAG):从理论到LangChain实践

文章目录

一. 检索增强生成(Retrieval-Augmented Generation, RAG)
* 1.1 问题背景
* 1.2 解决方案
* 检索增强生成(RAG)是一种结合了信息检索与生成式模型协同作用的知识表示方法。
* 该技术通过利用外部知识库来辅助生成更准确的文本输出。
* 其核心在于通过检索相关知识来进行上下文理解,并在此基础上进行语言模型的辅助生成。
* 这种方法特别适用于需要依赖外部信息完成复杂任务的场景。
* 它不仅提升了知识表达的能力,还能够显著提高输出的质量与相关性。
* 实现过程通常包括多个步骤:首先进行数据采集与预处理;其次构建有效的知识图谱或向量索引;最后通过训练学习器来实现跨模态或多模态的知识交互。
* 这种方法的优势主要体现在其灵活性与可扩展性上,在多个领域都有广泛的应用前景。

  • 二 基于LangChain实现的检索增强生成方法

  • 2 第一部分基于LangChain实现的检索增强生成方法

  • 21 第一阶段的工作内容

  • 22 第一阶段的主要工作内容

  • 23 第一步的主要工作内容是检索相关数据

  • 24 第二步的主要工作内容是对数据进行增强处理

  • 25 第三步的主要工作内容是对数据进行生成处理

    • 三. 总结
    • 四. 参考文献
  • 检索增强生成(RAG)的工作过程始于用户查询(Query)输入,并借助向量数据库(Vector database)进行搜索以获取相关信息内容;随后通过填充提示(Prompt)完成信息整合与表达;最后完成从Query输入到Prompt填充再到回答输出的过程。
在这里插入图片描述

自发现可借助 _专有数据提升大语言模型(LLM)性能以来,
如何有效整合 LLM 的通用知识库与专用数据集成为焦点话题。
本文深入探讨了 RAG 的理论基础及其应用潜力,
并通过案例展示了其优势。
随后介绍了如何利用 LangChain 工具、OpenAI 模型以及 Weaviate 向量数据库构建一个简单的 RAG 应用流程。

一. 什么是检索增强生成(Retrieval-Augmented Generation, RAG)

  • 检索增强生成技术(RAG)是一种创新性方法,在人工智能领域具有重要地位。该技术的主要目标是通过整合外部知识库来提升大语言模型的性能。

其核心功能体现在能够通过外部知识辅助生成更加精确且与上下文紧密相关的回答,并有效降低模型产生完全凭空想象的回答的可能性。

1.1. 问题背景

  • 当前领先的大型语言模型(LLMs)是通过大量数据进行训练而产生的,
    其目标是使它们能够掌握广泛的知识领域,
    这些知识被存储在它们神经网络中的权重(即参数内存)中。
    然而,
    如果要求LLM生成的问题涉及到其训练数据范围之外的知识——例如最新的信息、专有知识或某一特定领域的专有名词——
    就可能出现超出其已掌握知识范围的回答(我们称之为"知识缺口")
    下面是一个具体的案例:

  • 问题:总统对布雷耶大法官说了什么?从ChatGPT的回答可以看出,
    它对训练数据截止日期为2022年1月的信息不熟悉,
    因此无法提供该问题的答案。

在这里插入图片描述
在这里插入图片描述

因此,在语言模型(LLM)具备通用常识的同时能够有效结合额外语境(如实时信息)之间存在显著差距的情况下,在处理补全任务时有必要缩小这一差异范围。具体而言,在这种情况下语言模型可以通过整合外部信息来提升输出的质量与相关性从而在一定程度上避免产生脱离实际情境的"幻觉"。

1.2. 解决方案

  • 通常会进行模型微调以使其适应特定领域或特有的信息。这种方法确实有效但同时也带来了较高的计算开销且成本较高以及需要深厚的专业知识因此在快速适应信息变化方面显得不够灵活。
  • 2020 年 Lewis 等人在论文《知识密集型 NLP 任务的检索增强生成》(Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks)中 提出了更为灵活的一种技术——检索增强生成(Retrieval-Augmented Generation RAG)。该研究将 生成模型与检索器模块 结合在一起 从而能够从外部易于更新的知识库中获取更多信息。

用一个简明扼要的比喻来说明,
RAG对大型语言模型(LLM)的功能,
类似于开放资料考试对学生的作用。

在开放资料考试中,
学生可以在开放资料考试中携带参考资料入场。

开放资料考试的主要体现在考察学生的推理能力,
而不是对具体信息的记忆能力。

值得注意的是,在RAG体系中,事实性知识与LLM的推理能力被区分存储为易于访问和及时更新的外部知识源。这些信息的具体分类方式如下:

  1. 参数化知识(Parametric knowledge):模型通过训练阶段学习获得的知识信息,默认以神经网络中的权重形式嵌入。
  2. 非参数化知识(Non-parametric knowledge):这类信息则以向量数据库为例得以存储。
    此外,在Kaggle平台上的LLM科学考试竞赛中最早提出并由JJ提供过类似的阐述方法。

以下是RAG的工作流程:从用户的查询(Query)开始,在向量数据库中检索相关信息,并填充提示(Prompt),最终形成回答的过程。具体来说:

  1. 此过程利用用户的查询内容,在外部知识源中获取相关信息。
  2. 将用户的查询通过嵌入模型转化为向量,并将其与向量数据库中的其他上下文信息对比。
  3. 最后将这个经过检索增强的提示输入到大语言模型 (LLM) 中。
在这里插入图片描述

二. 基于LangChain实现的检索增强生成方法

在本节中, 我们将详细说明如何将 Python 与 OpenAI 的大语言模型、Weaviate 向量数据库以及 OpenAI 的嵌入技术整合起来构建一个检索增强生成 (RAG) 系统. 这一系统旨在通过高效的数据检索与自然语言处理技术, 实现从大规模文档库中提取关键信息并生成高质量的回答. 在这个过程中, 我们将主要依赖于 LangChain 工具来进行整体系统的架构设计与流程编排.

如果你尚未全面掌握 LangChain 和 Weaviate 的基本概念与应用方法,
两篇简明指南或许能为你提供帮助。
具体来说:

  1. LangChain 入门:这篇指南将指导你如何利用大语言模型(LLM)开发智能化的应用程序;
  2. Weaviate 入门:这篇指南则将介绍如何高效管理与检索高维向量数据集。

2.1. 准备工作

在开始之前,请确保你的系统中已安装以下 Python 包:

  1. langchain —— 用于整体编排
  2. openai —— 提供嵌入模型和大语言模型 (LLM)
  3. weaviate-client —— 用于操作向量数据库
复制代码
    #!pip install langchain openai weaviate-client

请在项目根目录中的.env文件中设定必要的环境变量。
首先,请访问此处页面。
然后按照该页面指引注册OpenAI账户并选择"创建新的密钥"选项。

复制代码
    OPENAI_API_KEY="<YOUR_OPENAI_API_KEY>"
  • 完成这些设置后,运行下面的命令来加载你所设置的环境变量。
复制代码
    import dotenv
    dotenv.load_dotenv()

2.2. 准备步骤

首先,你需要 建立一个向量数据库,并将该数据库作为外部知识源使用,以便包含所有必要的额外信息。具体操作步骤如下:

1. 第一步是收集相关数据并导入系统
2. 第二步是对你的 **文档内容进行分块处理。
3. 第三步是对每个分块的内容进行嵌入处理,并将结果存储起来。

第一步是获取所需数据源 — 在本示例中, 我们将采用 文章 《2022 年拜登总统的国情咨文》 作为背景资料. 这篇文档可以从 LangChain 的 GitHub 仓库 中找到具体实例. 为了有效地获取这些数据, 我们可以灵活运用 LangChain 提供的各种 DocumentLoader 工具. 其中, Document 类型是一种包含文本内容及附加元数据的字典结构. 在实际操作中, 我们可以通过调用 LangChain 的 TextLoader 来完成文件的加载任务.

复制代码
    import requests
    from langchain.document_loaders import TextLoader
    
    url = "https://raw.githubusercontent.com/langchain-ai/langchain/master/docs/docs/modules/state_of_the_union.txt"
    res = requests.get(url)
    with open("state_of_the_union.txt", "w") as f:
    f.write(res.text)
    
    loader = TextLoader('./state_of_the_union.txt')
    documents = loader.load()

在处理过程中需要将文档划分为多个部分 — 因为 Document 的原始大小超过了LLM处理窗口的能力范围, 因此必须将其分割成较小的片段. LangChain提供了多种用于文本分割的工具, 对于这个简单的案例, 我们可以选择 CharacterTextSplitter 工具, 建议将 chunk_size 设置为约500, 并将 chunk_overlap 设定为50, 这样能够有效保证各段之间的连贯性.

复制代码
    from langchain.text_splitter import CharacterTextSplitter
    text_splitter = CharacterTextSplitter(chunk_size=500, chunk_overlap=50)
    chunks = text_splitter.split_documents(documents)

最后一步是将这些文本块进行嵌入并存储 — 为了支持对文本块进行语义检索的需求,在生成向量嵌入的过程中,你可以选择使用 OpenAI 提供的嵌入模型;随后将这些向量进行存储操作,则可以通过调用 Weaviate 向量数据库来完成。具体而言,在调用该数据库时,请确保调用 .from_documents() 方法即可自动完成这些文本块的填充操作。

复制代码
    from langchain.embeddings import OpenAIEmbeddings
    from langchain.vectorstores import Weaviate
    import weaviate
    from weaviate.embedded import EmbeddedOptions
    
    client = weaviate.Client(
      embedded_options = EmbeddedOptions()
    )
    
    vectorstore = Weaviate.from_documents(
    client = client,
    documents = chunks,
    embedding = OpenAIEmbeddings(),
    by_text = False
    )

2.3. 第一步:检索

  • 当向量数据库准备好时即可将其配置为 检索组件 ,该组件通过与已嵌入文本块的语义关联性进行匹配来获取相关上下文信息。
复制代码
    retriever = vectorstore.as_retriever()

2.4. 第二步:增强

  • 接下来,你需要准备一个 提示模板 ,以便用额外的上下文信息来增强原始的提示。你可以根据下面显示的示例,轻松地定制这样一个提示模板。
复制代码
    from langchain.prompts import ChatPromptTemplate
    
    template = """You are an assistant for question-answering tasks.
    Use the following pieces of retrieved context to answer the question.
    If you don't know the answer, just say that you don't know.
    Use three sentences maximum and keep the answer concise.
    Question: {question}
    Context: {context}
    Answer:
    """
    prompt = ChatPromptTemplate.from_template(template)
    
    print(prompt)

2.5. 第三步:生成

  • 在 RAG (检索增强生成) 管道的构建过程中* ,可以通过整合检索器、提示模板以及大语言模型(LLM)来建立一个序列模型。明确设定好该 RAG 序列后,则能够实现其功能。
复制代码
    from langchain.chat_models import ChatOpenAI
    from langchain.schema.runnable import RunnablePassthrough
    from langchain.schema.output_parser import StrOutputParser
    
    llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0)
    
    rag_chain = (
    {"context": retriever,  "question": RunnablePassthrough()}
    | prompt
    | llm
    | StrOutputParser()
    )
    
    query = "What did the president say about Justice Breyer"
    rag_chain.invoke(query)
复制代码
    "总统对布雷耶法官 (Justice Breyer) 的服务表示感谢,并赞扬了他对国家的贡献。"
    "总统还提到,他提名了法官 Ketanji Brown Jackson 来接替布雷耶法官,以延续后者的卓越遗产。"
  • 下面展示了这一特定例子的 RAG 管道如何工作的图解:
在这里插入图片描述

当用户提问“总统对布雷耶法官说了什么”的时候,在系统中执行以下操作:首先通过检索向量数据库获取并返回三段相关文本内容;随后进行提示填充处理;最终生成回答的检索增强生成 (RAG) 工作流程图。(‘总统感谢布雷耶法官的服务精神’)

三. 总结

四. 参考文献

全部评论 (0)

还没有任何评论哟~