加载中

既然我们已经介绍了 RAG、文本分块和嵌入的基础知识,现在让我们逐步走一遍完整的 RAG 流程。这个详细的示例将向您展示在实际实现中所有部分是如何组合在一起的。

步骤 1:对源文本进行分块

首先,我们将源文档分解成可管理的块。在这个示例中,我们将使用两个简单的文本部分:

  • 部分 1:医学研究 —— "今年我们对 XDR-47 的理解取得了重大进展,这是一种我们以前从未见过的'bug'。"
  • 部分 2:软件工程 —— "该部门投入了大量精力研究我们分布式系统中的各种感染途径"

步骤 2:生成嵌入

接下来,我们将每个文本块转换为数值嵌入。为了更容易理解,让我们假设我们有一个完美的嵌入模型,它总是返回恰好两个数字,并且我们知道每个数字代表什么:

在我们假想的模型中:

  • 第一个数字:文本谈论医学的程度
  • 第二个数字:文本谈论软件工程的程度

因此,我们的医学研究部分得到 [0.97, 0.34] —— 非常医学化,由于"bug"这个词,也有一些软件相关性。软件工程部分得到 [0.30, 0.97] —— 非常偏重软件,但"感染途径"带有医学含义。

归一化

在存储这些嵌入之前,它们会经过一个归一化过程,将每个向量缩放为幅度为 1.0。这通常由您的嵌入 API 自动处理,但了解这一过程的发生是很重要的。

归一化后,我们的嵌入变为 [0.944, 0.331] 和 [0.295, 0.955]。我们可以将它们可视化在一个单位圆上,两个点恰好都位于圆的边缘。

步骤 3:存储到向量数据库

归一化后的嵌入被存储在向量数据库中 —— 这是一种专门优化用于存储、比较和搜索像我们的嵌入这样的长数字列表的数据库。

此时,我们暂停一下。到目前为止所做的所有工作都是提前进行的预处理。现在我们等待用户提交查询。

步骤 4:处理用户查询

当用户提出类似"我对这家公司很感兴趣。特别是,软件工程部门今年做了什么?"这样的问题时,我们将他们的查询通过相同的嵌入模型处理。

这个查询被嵌入为 [0.1, 0.89] —— 医学分数低,软件工程分数高。归一化后,它变为 [0.112, 0.993]。

步骤 5:查找相似的嵌入

现在我们向向量数据库询问:"找到与这个用户查询嵌入最接近的存储嵌入。"数据库返回软件工程部分,因为它最相似。

但数据库如何确定"最接近"呢?它使用余弦相似度。

余弦相似度

向量数据库计算向量之间夹角的余弦值来衡量相似度。这给我们一个介于 -1 和 1 之间的数字:

  • 1.0 = 向量指向完全相同的方向(非常相似)
  • 0.0 = 向量垂直(不相关)
  • -1.0 = 向量指向相反的方向(非常不同)

在我们的示例中:

  • 用户查询 vs 软件工程:余弦相似度 = 0.983(非常相似!)
  • 用户查询 vs 医学研究:余弦相似度 = 0.398(不太相似)

余弦距离

您会经常在向量数据库文档中看到"余弦距离"。这简单地就是 1 - 余弦相似度,它翻转了量表,使得数字越小表示越相似:

  • 0.0 = 非常相似
  • 1.0 = 垂直
  • 2.0 = 完全相反

步骤 6:构建最终提示

最后,我们将用户的问题和最相关的文本块(软件工程部分)结合起来,组成一个提示给 Claude:

Answer the user's question about the financial document.

<user_question>
How many bugs did engineers fix this year?
</user_question>

<report>
## Section 2: Software Engineering
This division dedicated significant effort to studying various infection vectors in our distributed systems
</report>

这就是完整的 RAG 流程!系统成功找到了与用户软件工程问题最相关的上下文,并将其提供给 Claude 以生成有依据的回答。

每次用户提交查询时,这个过程都会自动发生,使 Claude 能够根据您的特定文档而不仅仅是其通用训练知识来回答问题。