如何使用 RAG 构建 AI 知识库

308 阅读7分钟

大型语言模型非常强大,可以快速生成智能且听起来自然的响应。然而,他们的主要问题是训练数据的局限性——例如,GPT-4 的知识截止日期为 2021 年 9 月。这意味着模型不知道此日期之后的任何事件或发展。LLM在信息的准确性和“幻觉”方面也存在持续的问题 - 连贯和合乎逻辑,但事实上不正确的回答。最后,LLM 不知道具体的利基信息,只能在一定的通用性水平上生成响应。

为了解决这些问题并使 LLM 可用于特定和信息密集型任务,LLM 可以连接到 AI 知识库——由有组织的数据组成的信息存储库——产品文档、文章、消息和其他材料。在本文中,我将解释如何创建一个知识库,该知识库稍后将连接到 LLM 模型,并使其能够生成事实正确和具体的响应。

什么是 RAG?

RAG或检索增强生成是一种技术,它使LLM能够访问知识库中的相关文档。它允许 LLM 根据访问的文档生成准确的响应。RAG 技术的工作原理如下:

  1. 首先,搜索知识库以查找响应用户查询的信息。
  2. 然后,将最合适的搜索结果作为上下文添加到提示中,并添加一条指令,例如:“仅使用以下段落中的信息来回答以下问题”。
  3. 如果您使用的 LLM 模型未针对指令进行调整,则需要添加示例来演示预期输入和预期输出的外观。
  4. 包含指令、搜索结果和输出格式的提示文本将发送到 LLM 模型。
  5. LLM 使用来自上下文的信息来生成准确的响应。

RAG 的组件

RAG 由两个组件组成——信息检索组件和文本生成器 LLM。

  • 猎犬: 检索器是一个特定的查询编码器和基于矢量的文档搜索索引。今天,向量数据库经常被用作有效的检索器。向量数据库存储数据的向量嵌入,它是反映其语义含义的数据的数值表示。例如,HELLO -> [0.23, 0.001, 0.707]。知识库可以是向量数据存储,检索器会将查询转换为向量,并使用相似性搜索来查找相关信息。流行的矢量数据库包括 Chroma、FAISS 和 Pinecone。
  • 文本生成器 LLM: 使用的 LLM 模型将取决于您的目的。例如,如果最终解决方案要求数据隐私,则不建议使用 OpenAI 的 GPT 模型。出于我的目的,我使用了 Mistral 7B,这是 Mistral AI 发布的第一个模型。

在此示例中,我还将使用 LangChain,这是一个经常用于创建基于 RAG 的应用程序的框架。

创建 AI 知识数据库的步骤

您需要创建一个 AI 知识数据库,以便稍后使用 RAG 技术。您需要采取四个步骤。

  1. 收集并准备知识库: 您需要收集文档 – pdf、txt 或其他格式。此步骤是手动执行的,不需要编码。
  2. 块: 有些文档很大,包含大量文本:大多数 LLM 的上下文大小有限——例如,Mistral 7B 在预测序列中的下一个标记时可以考虑多达 8192 个文本标记。因此,您需要将文档拆分为具有固定符号数量的扇区。最常用的尺寸是 1024。
  3. 创建矢量嵌入: 矢量嵌入是通过将文本块转换为文本嵌入来创建的。为此,使用了专门的模型,例如 bge-large-en-1.5 或 all-Mini-I6。
  4. 存储嵌入: 您需要将嵌入存储在矢量数据存储中。矢量数据库支持快速检索和相似性搜索。

这些步骤将创建 AI 知识数据库,稍后将连接到 LLM 以创建 AI 解决方案。

让我们更详细地讨论这些步骤。

分块

在 RAG 管道中,文本分块是必不可少的预处理步骤。它需要将冗长的文本文档划分为更易于理解的片段或“块”,以便语言学习模型 (LLM) 可以有效地处理它们。文本分块旨在提高检索准确性并优化模型对上下文窗口的使用。

对文本进行分块的典型方法:

  • 固定长度分块: 将文本划分为由预定数量的标记或单词组成的部分。
  • 语义分块: 沿着语义线划分文本,例如段落或句子之间的语义线。
  • 推拉窗: 使用重叠块来保证围绕块边框的上下文得到维护。

使用 LangChain 和 Llamaindex 等流行工具的代码示例:

from langchain.document_loaders import 
TextLoader
from langchain.text_splitter import 
RecursiveCharacterTextSplitter

# Load your document
loader = 
TextLoader("path_to_your_document.txt")
documents = loader.load()

# Define a text splitter
splitter = RecursiveCharacterTextSplitter(
    chunk_size=512,  # Number of characters per chunk
    chunk_overlap=24  # Overlap between chunks
)

# Split the documents
chunks = splitter.split_documents(documents)
from llama_index.core import 
SimpleDirectoryReader
from llama_index.core import Settings

documents = 
SimpleDirectoryReader("./documents_directory")
.load_data()

Settings.chunk_size = 512
Settings.chunk_overlap = 24

创建和存储嵌入

现在我们有了块,是时候使用嵌入模型(在我们的例子中是 OpenAI)、色度向量存储(在 Langchain 的情况下)和内存中向量存储(在 Llamaindex 的情况下)创建和存储嵌入了。

LangChain 和 LlamaIndex 代码示例:

from langchain.document_loaders import 
TextLoader
from langchain.text_splitter import 
RecursiveCharacterTextSplitter
from langchain.embeddings import 
OpenAIEmbeddings
from langchain.vectorstores import 
Chroma

# Load your document
loader = 
TextLoader("path_to_your_document.txt")
documents = loader.load()

# Define a text splitter
splitter = RecursiveCharacterTextSplitter(
    chunk_size=512,  # Number of characters per chunk
    chunk_overlap=24  # Overlap between chunks
)

# Split the documents
chunks = splitter.split_documents(documents)

# Use embeddings and vectorstore for retrieval
embeddings = OpenAIEmbeddings()
vectorstore = Chroma.from_documents(chunks, embeddings)

retriever = vectorstore.as_retriever()
from llama_index.core import 
SimpleDirectoryReader, VectorStoreIndex
from llama_index.core import Settings

documents = 
SimpleDirectoryReader("./data").load_data()

Settings.chunk_size = 512
Settings.chunk_overlap = 24

index = VectorStoreIndex.from_documents(
    documents,
)

query_engine = index.as_query_engine()

这些步骤允许您创建一个可用于各种解决方案的 AI 数据库,以提高 LLM 响应的准确性。

如何选择嵌入模型和向量数据库?

每周都会发布新的嵌入模型。要选择合适的,请从 MTEB 排行榜或拥抱面孔开始。在那里,您可以找到每个型号的最新列表和性能统计信息。最重要的参数是:

  • 检索平均值: 衡量检索系统性能的常用指标称为 NDCG – 归一化贴现累积增益。较高的检索平均值表明,该模型在结果列表中将正确项目排名靠前更成功。
  • 模型尺寸: 模型的大小(以 GB 为单位)显示运行模型所需的计算资源量。选择一种能够在资源使用和性能之间提供适当平衡的模型非常重要。这将取决于您的项目。
  • 嵌入延迟: 嵌入延迟是为完整数据集创建嵌入所需的时间。要测量嵌入延迟,您可以比较不同模型为本地向量存储生成嵌入的速度。然而,需要注意的是,就计算资源而言,较短的时间通常与更大的费用和更大的要求有关。
  • 检索质量: 若要评估检索质量,请使用与数据集中的主题相对应的问题。对于实际应用程序,您还可以使用您希望应用程序用户提出的问题。

对于向量数据库,其他参数是关键:

  • 开源或私有: 开源数据库通常有推动其发展的社区。它们可能适用于预算有限的组织。另一方面,专有的矢量数据库提供了额外的功能和有效的客户支持,如果您的项目有特定的技术或合规性要求,可能更合适。
  • 性能: 最重要的参数是每秒查询数和平均查询延迟。大量查询表明数据库可以同时处理多个查询。如果您希望您的应用同时为多个用户提供服务,这一点至关重要。查询延迟显示数据库处理查询所需的时间。如果您的应用需要实时响应,例如在对话式 AI 聊天机器人中,则快速处理至关重要。
  • 成本效益: 每个数据库都有特定的定价模型。通常,数据库对向量数量或存储容量收费。定价也可能因查询类型和操作的复杂性而异。此外,某些数据库会收取数据传输费用,如果您的应用需要频繁检索或上传数据,则应考虑这一点。

结论

总而言之,人工智能知识库是以快速且经济高效的方式扩大 LLM 能力的有效方法。知识库充当可靠数据的存储库,用于增强提示并使 LLM 能够生成准确的响应。RAG 技术对于 LLM 和知识库的整合是必不可少的,它为实现发展目标提供了清晰且无问题的途径。