实现检索增强生成(RAG):实战指南!

2024/9/20 21:03:29

本文主要是介绍实现检索增强生成(RAG):实战指南!,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

图片来源: https://arxiv.org/abs/2402.19473

大型语言模型(LLMs)如今已成为大多数组织的基石,因为整个世界正在向人工智能转型。虽然大型语言模型因为各种积极的原因而广受欢迎,但如果使用不当,它们也会带来一些缺点。是的,大型语言模型有时会产生意想不到的响应,这些响应可能是虚假的、编造的信息,甚至是有偏见的。这种情况的发生可能有各种原因。我们将大型语言模型生成错误信息的过程称为幻觉。

有一些值得注意的方法可以减轻大型语言模型(LLM)的幻觉问题,例如微调、提示工程、检索增强生成(RAG)等。其中,检索增强生成(RAG)是最常被讨论的方法,用于减轻大型语言模型遇到的幻觉问题。

让我们通过使用 SingleStore 作为向量数据库来存储向量数据的动手实现,更深入地了解 RAG 的工作原理。

什么是检索增强生成(RAG)?

大型语言模型(LLMs)有时会产生虚构的答案,而缓解这些虚构答案的一种技术是通过RAG。对于用户的查询,RAG倾向于从存储在向量数据库中的提供的源/信息/数据中检索信息。向量数据库是一种专门用于存储向量数据的数据库,不同于传统的数据库。

向量数据以嵌入的形式存在,捕捉了对象的上下文和含义。例如,想象一下你希望从你的AI应用程序中获得自定义响应的场景。

首先,组织的文档通过嵌入模型转换为嵌入,并存储在向量数据库中。当查询发送到AI应用程序时,查询会被转换为向量查询嵌入,并通过向量数据库进行向量相似性搜索以找到最相似的对象。这样,您的LLM驱动的应用程序就不会出现幻觉,因为它已经被指示提供自定义响应,并且已经输入了自定义数据。

一个简单的用例是客户支持应用程序,其中自定义数据被输入到存储在向量数据库中的应用程序中。当用户提问时,它会生成与您的产品或服务最相关的响应,而不是一些通用的答案。这样,RAG 正在改变世界上的许多其他领域。

RAG 管道

RAG 管道基本上包括三个关键组件:检索组件、增强组件和生成组件。

  • 检索:此组件帮助你从外部知识库(如向量数据库)中获取与给定用户查询相关的相关信息。此组件非常重要,因为这是生成有意义且上下文正确的响应的第一步。
  • 增强:这一部分涉及增强和添加更多与检索到的响应相关的上下文,以满足用户查询的需求。
  • 生成:最后,通过大型语言模型(LLM)向用户提供最终输出。LLM 使用其自身的知识和提供的上下文,为用户的查询生成恰当的响应。

这三个组件是构建RAG管道的基础,帮助用户获得他们所需的内容丰富且准确的回复。这就是为什么RAG在构建聊天机器人、问答系统等时如此特别的原因。

RAG 教程

让我们构建一个简单的AI应用程序,它可以为任何给定的用户查询从我们自己的数据中获取相关的信息。

注册 SingleStore 数据库 以将其用作我们的向量数据库。

一旦你注册了,就需要创建一个工作区。这很简单,而且是免费的,所以赶快去做吧。

一旦创建了工作区,就可以创建一个任意名称的数据库。

如上图所示,你可以从右侧的“创建数据库”选项卡中创建数据库。

现在,让我们去‘开发’页面使用我们的笔记本功能[就像Jupyter Notebook一样]

创建一个新的笔记本,并将其命名为你希望的名称。

在执行任何操作之前,从笔记本的下拉菜单中选择您的工作区和数据库。

现在,开始将下面显示的所有代码片段添加到你刚刚创建的笔记本中,如下所示。

安装所需的库
    !pip install openai numpy pandas singlestoredb langchain==0.1.8 langchain-community==0.0.21 langchain-core==0.1.25 langchain-openai==0.0.6
向量嵌入示例
    def word_to_vector(word):  
        # 定义向量组件的一些基本规则  
        vector = [0] * 5  # 初始化一个5维的向量  

        # 规则1:单词的长度(为了简单起见,归一化到最多10个字符)  
        vector[0] = len(word) / 10  

        # 规则2:单词中的元音数量(归一化到单词的长度)  
        vowels = 'aeiou'  
        vector[1] = sum(1 for char in word if char in vowels) / len(word)  

        # 规则3:单词是否以元音开头(是则为1,否则为0)  
        vector[2] = 1 if word[0] in vowels else 0  

        # 规则4:单词是否以元音结尾(是则为1,否则为0)  
        vector[3] = 1 if word[-1] in vowels else 0  

        # 规则5:单词中的辅音百分比  
        vector[4] = sum(1 for char in word if char not in vowels and char.isalpha()) / len(word)  

        return vector  

    # 示例用法  
    word = "example"  
    vector = word_to_vector(word)  
    print(f"Word: {word}\nVector: {vector}")
向量相似性示例
    import numpy as np  

    def cosine_similarity(vector_a, vector_b):  
        # 计算向量的点积  
        dot_product = np.dot(vector_a, vector_b)  
        # 计算每个向量的范数(大小)  
        norm_a = np.linalg.norm(vector_a)  
        norm_b = np.linalg.norm(vector_b)  
        # 计算余弦相似度  
        similarity = dot_product / (norm_a * norm_b)  
        return similarity  

    # 示例用法  
    word1 = "example"  
    word2 = "sample"  
    vector1 = word_to_vector(word1)  
    vector2 = word_to_vector(word2)  

    # 计算并打印余弦相似度  
    similarity_score = cosine_similarity(vector1, vector2)  
    print(f"'{word1}' 和 '{word2}' 之间的余弦相似度: {similarity_score}")
嵌入模型
    OPENAI_KEY = "INSERT OPENAI KEY"  
    from openai import OpenAI  
    client = OpenAI(api_key=OPENAI_KEY)  

    def openAIEmbeddings(input):  
     response = client.embeddings.create(  
         input="input",  
         model="text-embedding-3-small"  
     )  
     return response.data[0].embedding  
    print(openAIEmbeddings("Golden Retreiver"))
使用SingleStoreDB创建向量数据库

我们将使用 LangChain 框架,SingleStore 作为向量数据库来存储我们的嵌入,并使用一个关于夏洛克·福尔摩斯故事的公共 .txt 文件链接。

将 OpenAI API 密钥作为环境变量添加。

     import os  
    os.environ['OPENAI_API_KEY'] = ‘提及你的 OpenAI API 密钥’

接下来,导入所需的库,指定要使用的文件,加载文件,将其拆分并添加到SingleStore数据库中。最后,针对你使用的文档提出相关查询。

     import openai  
    from langchain.text_splitter import CharacterTextSplitter  
    from langchain_community.document_loaders import TextLoader  
    from langchain_community.embeddings import OpenAIEmbeddings  
    from langchain_community.vectorstores.singlestoredb import SingleStoreDB  
    import os  
    import pandas as pd  
    import requests  

    # 要使用的公共 .txt 文件的 URL  
    file_url = "https://sherlock-holm.es/stories/plain-text/stud.txt"  

    # 向文件 URL 发送 GET 请求  
    response = requests.get(file_url)  

    # 如果文件成功下载则继续  
    if response.status_code == 200:  
        file_content = response.text  

        # 将内容保存到文件中  
        file_path = 'downloaded_example.txt'  
        with open(file_path, 'w', encoding='utf-8') as f:  
            f.write(file_content)  

        # 现在可以使用 'downloaded_example.txt' 继续你的原始代码  
        # 加载和处理文档  
        loader = TextLoader(file_path)  # 使用下载的文档  

        documents = loader.load()  
        text_splitter = CharacterTextSplitter(chunk_size=2000, chunk_overlap=0)  
        docs = text_splitter.split_documents(documents)  

        # 生成嵌入并创建文档搜索数据库  
        OPENAI_KEY = "add your openai key"  # 用你的 OpenAI API 密钥替换  
        embeddings = OpenAIEmbeddings(api_key=OPENAI_KEY)  

        # 创建向量数据库  
        vector_database = SingleStoreDB.from_documents(docs, embeddings, table_name="scarlet")  # 用实际表名替换 "your_table_name"  

        query = "他是在哪个大学学习的?"  
        docs = vector_database.similarity_search(query)  
        print(docs[0].page_content)  

    else:  
        print("下载文件失败。请检查 URL 并重试。")

运行上述代码后,你将看到一个输入框,可以在其中输入你想要询问的关于我们引用的福尔摩斯故事的问题。

我们从提供的数据中检索了相关信息,并利用这些信息引导响应生成过程。通过将文件转换为嵌入式表示并存储在SingleStore数据库中,我们创建了一个可检索的信息库。这样,我们确保了响应不仅相关,而且内容丰富,源自提供的数据集。

这个故事发布在生成式AI出版物。

通过 Substack、LinkedIn 和 Zeniteq 与我们保持联系,了解最新的AI故事。让我们一起塑造AI的未来!



这篇关于实现检索增强生成(RAG):实战指南!的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程