Dify 源码解析 (三):RAG 核心——索引、切片与检索链路的深度实现

在 Dify 的架构体系中,如果说 Workflow 是它的“四肢”,那么 RAG(检索增强生成)引擎就是它的“海马体”——负责记忆、组织并检索海量的私有知识。

本篇是 Dify 源码解析系列的第三章。我们将深入 api/core/rag 模块,剖析 Dify 如何将非结构化文档转化为机器可读的索引,以及在提问时如何通过混合检索(Hybrid Search)精准定位答案。

核心代码路径: api/core/rag


1. 数据处理流水线:从文档到切片 (ETL)

RAG 的第一步是 ETL(Extract, Transform, Load)。在 Dify 中,这一过程被高度抽象化,主要由 DatasetProcess 相关的类控制。

1.1 提取与清洗 (Extractor & Cleaner)

Dify 并不直接处理所有文件格式,而是依赖于通过工厂模式封装的解析器。

  • 提取 (extractor): 支持 PDF, Word, Markdown, HTML 等多种格式。Dify 内部集成了 unstructured 等库来处理复杂的非结构化数据。

  • 清洗 (cleaner):core/rag/cleaner 中,逻辑主要集中在去除无效字符、乱码修复以及格式标准化上。

代码逻辑视点:

数据流并不是线性的,而是一个 Pipeline。当用户上传文件后,DatasetService 会触发 Celery 异步任务,调用 ExtractProcessor。

1.2 切片策略 (Splitting Strategy)

这是 RAG 效果的胜负手。Dify 的切片逻辑位于 core/rag/splitter 中。

  • 字符级切分: 基于固定字符数(Fixed Size)和重叠窗口(Overlap)。这是最基础的兜底策略。

  • 语义切分(父子索引): Dify 实现了更高级的“父子切片”逻辑。

    • Parent Chunk: 较大的文本块,用于保持上下文的完整性。

    • Child Chunk: 较小的文本块,用于向量化以提高检索的精确度。

    • 实现原理: 检索时匹配 Child Chunk,但返回给 LLM 的是其对应的 Parent Chunk。这解决了“检索精准度”与“上下文连贯性”之间的矛盾。


2. 索引构建与向量化 (Indexing & Embedding)

切片完成后,数据进入索引阶段。Dify 的设计哲学是**“存储层解耦”**。

2.1 向量数据库工厂 (Vector Store Factory)

core/rag/index_processorcore/rag/datasource/vdb 中,Dify 采用了典型的工厂模式适配多种向量数据库(Milvus, Weaviate, Qdrant, pgvector, Chroma 等)。

每个具体的 VDB 实现类都必须继承自 BaseVector 抽象基类,实现以下核心方法:

  • create(): 创建集合/索引。

  • add_texts(): 写入向量数据。

  • search(): 执行相似度搜索。

  • delete(): 删除索引。

2.2 Embedding 策略

Embedding 过程并非单纯调用 OpenAI API。Dify 在 core/model_manager 中维护了 Embedding 模型的接口。

  • Cache 机制: 为了节省成本和提高速度,Dify 会对相同的文本 hash 值进行缓存,避免重复 Embedding。

  • Batch 处理: 在写入向量库时,系统会自动将切片打包(Batch),批量调用 Embedding 接口,提高吞吐量。


3. 混合检索链路 (Retrieval & Hybrid Search)

这是 core/rag 模块中最精彩的部分。单一的向量检索(Semantic Search)在面对专有名词或精确匹配时往往表现不佳,因此 Dify 引入了 混合检索(Hybrid Search)

检索的入口通常位于 RetrievalService

3.1 检索流程架构

当一个 Query 传入时,Dify 的检索链路如下:

  1. Query Rewrite (可选): 对用户问题进行改写或扩展(取决于配置)。

  2. 路由分发: 根据 Dataset 的配置,决定使用哪种检索策略。

  3. 并发执行:

    • 向量检索 (Vector Search): 将 Query 向量化,在 VDB 中查找 Top K。

    • 关键词检索 (Keyword Search): 利用倒排索引(如 Elasticsearch 或 jieba 分词后的数据库匹配)查找 Top K。

  4. 结果融合 (Fusion): 将两路结果合并。

  5. 重排序 (Rerank): 这一步是提升效果的关键。

3.2 核心实现:混合检索与 Rerank

在代码层面,混合检索不仅仅是简单的列表相加。

Weighted Score Fusion (加权融合):

如果未开启 Rerank 模型,Dify 可能会使用加权算法(或依赖 VDB 自身的 Hybrid 能力,如 Weaviate)。

Rerank 模型介入 (core/rag/rerank):

如果配置了 Rerank 模型(如 Cohere Rerank, BGE Rerank),流程会有质的飞跃:

  1. 先通过 Vector + Keyword 检索出较大范围的候选集(例如 Top 50)。

  2. (Query, Document) 对输入 Rerank 模型。

  3. 模型计算两者的相关性得分(Score)。

  4. 根据 Score 重新排序,截取最终的 Top N(例如 Top 5)。

代码洞察: 这种 Retrieve -> Rerank 的两阶段模式(Two-Stage Retrieval)是目前 RAG 系统的最佳实践。Dify 将其封装在 RerankRunner 类中,使得开发者可以无缝切换不同的 Rerank 提供商。


4. 总结与思考

Dify 的 core/rag 模块展示了一个生产级 RAG 系统应有的素质:

  1. 模块化极强: VDB、Embedding、Rerank 均可插拔。

  2. 关注全链路: 不仅关注“检索”,还深度优化了“入库”时的清洗和切片。

  3. 混合检索落地: 原生支持 Keyword + Vector + Rerank 的完整链路,解决了单一向量检索的痛点。

理解了这个模块,你就理解了 Dify 如何让 LLM 拥有“私有记忆”。


下期预告:

既然数据已经准备好,LLM 又是如何根据 Prompt 和检索到的上下文进行推理的呢?下一篇我们将深入解析 Dify 的 Workflow 引擎。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天天进步2015

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值