RAG From Scratch: Part 3 (Retrieval) by LangChain

RAG From Scratch: Part 3 (Retrieval) by LangChain

检索(Retrieval)

在这里插入图片描述

一、核心概念

在这里插入图片描述

1. RAG系统与检索环节

  • RAG(检索增强生成):通过“检索相关文档+生成答案”的组合,提升生成内容的准确性和相关性,核心流程为:索引文档 → 检索相关文档 → 基于文档生成答案
  • 检索的目标:从索引的文档中,找出与用户问题语义最相关的文档或文档片段,为后续生成环节提供依据。
    在这里插入图片描述

2. 关键术语

  • 嵌入(Embedding):将文本转换为固定长度的数值向量(如1536维),向量的数值反映文本的语义信息。
  • 向量空间:文档和问题通过嵌入模型映射到高维空间(如3D、1536D),空间中距离越近的向量,语义相似性越高。
  • 相似性搜索:在向量空间中,通过计算向量距离(如余弦相似度),查找与问题向量最接近的文档向量。
    在这里插入图片描述

二、检索流程解析

1. 文档处理全流程

  1. 文档加载与拆分
    • 输入原始文档(如PDF、文本),使用分割器(Splitter)将长文档拆分为适合嵌入模型处理的小块(如512-8000 Token)。
    • 示例:将一本书拆分为多个章节段落,每个段落作为一个独立的“文档拆分”。
  2. 嵌入与索引构建
    • 对每个文档拆分生成嵌入向量,存储到向量存储(如Chroma、FAISS)中,形成可检索的“索引”。
  3. 问题嵌入与检索
    • 将用户问题转换为嵌入向量,在向量空间中执行相似性搜索,返回与问题最相关的Top-K个文档拆分。
      在这里插入图片描述

2. 向量空间的语义映射原理

  • 低维示例(3D空间)
    • 每个文档对应3D空间中的一个点,位置由语义决定(如“猫”和“狗”的向量点靠近,“汽车”的点远离)。
    • 问题嵌入后成为空间中的另一个点,通过“本地邻域搜索”查找附近的文档点(即语义相似的文档)。
  • 高维应用
    • 实际场景中使用高维向量(如1536D),通过数学度量(如余弦相似度)计算向量间的“距离”,距离越近,语义越相关。

三、技术原理:相似性搜索的核心逻辑

1. 核心思想

  • 语义相关性 = 向量空间距离:利用嵌入模型将文本语义转化为向量数值,通过向量距离量化语义相似性。

2. 关键方法

  • k最近邻搜索(k-NN)
    • 参数 K 表示检索时返回的最相关文档数量(如K=1表示只返回最相似的1个文档)。
    • 示例:在3D空间中,以问题向量为中心,查找距离最近的K个文档向量。
  • 实现工具
    • 向量存储库:FAISS(高效处理大规模向量)、Chroma(轻量级,适合原型开发)。
    • 嵌入模型:OpenAI Embeddings、Hugging Face Embeddings(支持多语言)。

四、实践要点

1. 工具与组件集成

  • 文档加载器:支持多种格式(如PDFLoader、TextLoader),适配不同数据源。
  • 分割器:递归字符分割器(按字符数拆分)、NLTK分割器(按句子拆分),需根据文档结构选择。
  • 向量存储选择:小规模数据用Chroma(内存存储),大规模数据用FAISS(支持GPU加速)。
    在这里插入图片描述

2. 参数K的作用

  • K值影响
    • K过小(如K=1):可能遗漏相关文档,导致信息不足;
    • K过大:返回无关文档,增加生成环节的噪声。
  • 调优建议:根据问题复杂度和文档相关性,通过实验确定最优K值(如K=3-5)。

3. 监控与调试

  • 使用 LangSmith 工具跟踪检索结果:
    • 查看检索到的文档是否与问题相关;
    • 分析嵌入向量的分布和相似性计算是否正确。

五、代码演示要点:检索核心步骤

代码

  1. 环境设置与依赖
  2. 文档加载与拆分
  3. 构建索引与检索器
  4. 执行检索
    在这里插入图片描述

六、总结

  • 检索的核心价值:通过向量空间的语义匹配,将用户问题与文档建立关联,是RAG系统“准确性”的重要保障。
  • 后续环节:检索得到的文档将作为生成模型的输入,结合prompt工程生成最终答案(详见系列视频“生成”部分)。
  • 实践关键:合理选择嵌入模型、分割策略和向量存储,通过参数调优(如K值)平衡检索精度与效率。

七、视频原文

第二页:这是我们系列视频从头开始制作RAG的第三部,从最基本的组件开始构建RAG的很多动机,所以今天我们将讨论检索,在最后两个简短的视频中,我概述了索引,并概述了此流程,从索引我们的文档开始,检索与我们的问题相关的文档,然后根据检索到的文档生成答案,因此我们看到索引过程基本上使用文档易于检索,

第三页:他经过一个流程,基本上看起来像您获取我们的文档,将他们以某种方式拆分成可以轻松嵌入的较小块,这些嵌入是这些文档的数字表示,易于检索,他们存储在索引中,当给定一个嵌入的问题时,索引会执行相似性搜索并返回与问题相关的拆分,

第四页: 现在如果我们深入挖掘,我们可以这样思考,如果我们获取一个文档,并将其嵌入,让我们想象一下嵌入只有三个维度,所以你知道每个文档都会被投影到这个3D空间中的某个点,现在的重点是空间中的位置由该文档中的语义含义或内容决定,因此,空间中相似位置的文档包含相似的语义信息,这个简单的想法实际上是许多搜索和检索方法的基石,你会在现代向量存储中看到这些方法,因此,具体来说我们将文档,嵌入到这个玩具3D空间中,我们将问题做同样的事情,然后我们可以进行搜索,比如本地邻域搜索,你可以在这个3D空间中围绕我们的问题思考,看看附近有哪些文档, 然后检索这些附近的邻居,因为他们可能与我们的问题具有相似的语义

第五页:这就是这里真正发生的事情,所以我们再次拿出我们的文档,将他们拆分,嵌入他们现在他们存储于这个高维空间中,我们已经将问题嵌入到同一个空间中,我们只需要围绕问题搜索附近的文档,并抓取接近的文档,我们可以选择一些数字,假设我们想要一个、两个、三个或n个文档,它们靠近这个嵌入空间中的问题,有很多有趣的方法可以非常有效地实现这一点,我在这里链接了一个,

第六页:我们有很多非常好的集成来实现这个总体思路,有很多不同的嵌入模型,很多不同的索引,很多文档加载器,还有很多分割器,它们可以重新组会,以测试执行这种索引或检索的不同方式,所以现在我将展现一些代码演练

第七页:在这里 我们定义了我们之前已经演练过了,这是我们的笔记本,我们安装了一些安装包,通过LMsmith设置了一些环境变量,我们之前展示了这个,这只是一个概述,展示了如何以端到端的方式运行rag,在上一个简短的演讲中,我们讨论了indexing,我要做的很简单,就是加载我们的文档,现在我有了我们的文档,我要重新分割它们,我们之前看到了如何构建索引,这里我们来做同样的事情,但在幻灯片中我们实际上展示了在3D空间中搜索的概念,在构建检索器时需要考虑的一个参数时K,所以K会告诉您在执行检索过程时要获取的附近邻居的数量,我们讨论了在3D空间中我想要一个附近的邻居还是两个或三个,所以在这里我们可以指定k等于1,例如,现在我们正在构建索引,所以我们将每个分割嵌入存储,它现在我问了一个问题,什么是任务分解,这与博客文章有关,我将运行获取相关文档,所以我运行他,现在我得到了多少个文档,根据K=1,我得到了一个,所以这个检索文档,应该与我的问题相关,现在我们可以去LangSmith,我们可以打开它,我们可以看看我们的检索器retriever。我们可以看到这是我们的问题,这是我们得到的一个文档,好的,这很有意义,这个文档特别涉及任务分解,它列出了许多可用于实现这一点的不同方法,这些方法都很有意义,并且在实践中展示了如何非常轻松地实现这种NE KNN或k最近邻搜索,只需要使用几行代码,接下来我们将讨论生成。

### LangChain4j 中 RAG 的概念介绍 检索增强生成(Retrieval-Augmented Generation, RAG)是一种结合了检索和生成模型的技术,旨在通过从外部数据源中提取相关信息来提高自然语言处理任务的效果。在 LangChain4j 中,RAG 是一种用于构建智能问答系统的强大工具[^2]。 #### 1. RAG 的基本原理 RAG 技术的核心在于将传统的基于生成的语言模型与信息检索机制相结合。具体来说,在生成最终响应之前,系统会先从存储的知识库或文档集合中检索出与当前查询最相关的片段。这些片段作为上下文输入提供给大语言模型(LLM),从而帮助其生成更加精确、有依据的回答[^3]。 #### 2. LangChain4j 对 RAG 的支持 LangChain4j 提供了一套灵活的 API 和组件来简化 RAG 应用程序的开发过程。以下是几个关键部分: - **DefaultRetrievalAugmentor**: 它是一个默认实现类,负责执行整个检索流程并将其结果传递至后续阶段。该模块的设计灵感来源于一篇学术论文《Deconstructing RAG(https://arxiv.org/pdf/2312.10997)[^1]。 - **Easy RAG 功能**: 开发者可以通过引入 `langchain4j-easy-rag` Maven 依赖快速搭建基础版 RAG 流程。这种方式虽然功能有限,但对于初学者或者仅需创建原型项目而言非常实用。 ```xml <dependency> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j-easy-rag</artifactId> <version>0.34.0</version> </dependency> ``` - **加载文档**: 使用内置工具如 `FileSystemDocumentLoader` 来读取本地文件夹内的资料,并转换成适合进一步处理的形式——即一组 Document 实体对象列表。 ```java List<Document> documents = FileSystemDocumentLoader.loadDocuments("/path/to/documents"); ``` #### 3. 高级定制选项 尽管 Easy RAG 能够满足初步需求,但在实际生产环境中往往还需要针对特定场景做更多优化调整。例如修改相似度计算算法、更换底层向量数据库引擎等操作都可以显著提升性能表现。 --- ### 示例代码展示简易 RAG 构建方式 下面给出一段简单的 Java 示例代码演示如何利用上述提到的功能点完成一次完整的交互体验: ```java import dev.langchain4j.data.document.Document; import dev.langchain4j.model.chat.ChatLanguageModel; import dev.langchain4j.retriever.Retriever; public class SimpleRAGExample { public static void main(String[] args) { // 初始化必要的组成部分 Retriever retriever = ... ; // 自定义检索器实例化逻辑省略 ChatLanguageModel llm = ... ; // 大型预训练模型接入细节忽略 String userQuestion = "Spring Boot 如何配置多环境?"; // 执行检索动作获取关联材料 List<Document> retrievedDocs = retriever.retrieve(userQuestion); // 将检索所得内容拼接形成提示词前缀 StringBuilder contextBuilder = new StringBuilder(); for (Document doc : retrievedDocs){ contextBuilder.append(doc.content()).append("\n---\n"); } String promptWithContext = String.format( "%s请根据以上背景知识回答:%s", contextBuilder.toString(), userQuestion ); // 请求大型语言模型作答 String aiResponse = llm.generate(promptWithContext); System.out.println(aiResponse); } } ``` 此脚本展示了从接收用户提问到最后返回解答的整体链条运作情况。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值