犀牛鸟 2026 研究笔记 estelledc.github.io

Ch33: Dify 源码走读——Workflow 与 RAG 引擎

Part 9: 四平台源码走读(Phase E) 前置:Ch16 Dify 精读Ch32 大师通关 后续:Ch34 RAGFlow 源码

结论先行:Dify 的 RAG 实现在 api/core/rag/,业务编排落在 api/core/workflow/大师读 Dify 应优先追踪 Workflow DAG 如何调用 KnowledgeRetrievalNode,而不是只读 Chat 封装。Dify 的护城河是「可视化编排 + Model Runtime」,RAG 是标准 BM25+向量双路——与 WeKnora 三路+RRF 互补,常见组合是 Dify 编排 + WeKnora 外部检索 HTTP 节点


一、日常类比

Dify 像 宜家厨房样板间:预制柜体(节点)、说明书(Workflow DSL)、统一接口(Model Runtime)让你快速搭出「能用的」RAG 应用。WeKnora 像 专业后厨:刀工(解析)、三路备料(BM25/向量/图谱)、摆盘(Rerank)更细。大师要会选:展示 Demo 用宜家,竞赛改检索深度进后厨。


二、Commit / 版本 Pin 说明

建议
仓库 langgenius/dify
Docker langgenius/dify-api:0.15.x 或 clone 日 2026-06 对照 git log -1 --format=%ci
原因 api/core/workflow/nodes/core/rag/retrieval/ 在 0.14→0.15 间有目录微调
git clone https://github.com/langgenius/dify.git
cd dify && git checkout $(git tag -l '0.15.*' | tail -1)   # 无 tag 则用 main + 记录 commit
cd docker && docker compose up -d
# 浏览器打开 :80,创建 Dataset + 最小 Workflow

走读前在笔记写:pin = tag/commit + 日期,PR 或实验结论必须可复现。


三、目录地图(RAG + Workflow)

路径 职责
api/controllers/console/ Console API 路由(Dataset、App、Workflow)
api/services/dataset_service.py 知识库 CRUD、文档索引任务派发
api/core/rag/retrieval/ VectorRetriever / KeywordRetriever / HybridRetriever
api/core/rag/splitter/ Fixed / Recursive / Auto 分块
api/core/rag/extractor/ PDF / Word / Markdown 抽取
api/core/workflow/graph/graph.py DAG 拓扑与执行调度
api/core/workflow/nodes/knowledge_retrieval/ 工作流内知识检索节点
api/core/model_runtime/ 100+ Provider 统一 invoke()
api/tasks/ Celery 异步摄入、Embedding

分工记忆services/ = 业务编排与权限;core/rag/ = 算法与管线;core/workflow/ = 节点运行时。


四、一条具体调用链(Workflow 带知识库)

以 Console 触发「知识检索 → LLM」Workflow 为例(文件路径以 0.15.x 为锚):

POST /console/api/.../workflows/run
  → api/controllers/console/app/workflow.py          # 接 HTTP
  → api/services/workflow_service.py                 # 加载 DSL、鉴权
  → api/core/workflow/graph/graph.py                 # GraphEngine.run()
  → api/core/workflow/nodes/knowledge_retrieval/node.py
       # 读 query 变量 → 调 RetrievalService
  → api/core/rag/retrieval/retrieval_service.py
  → api/core/rag/retrieval/hybrid.py                   # HybridRetriever.retrieve()
       # KeywordRetriever + VectorRetriever → 权重融合
  → api/core/rag/datasource/vdb/*                      # Qdrant / Weaviate 等
  → (下一节点) api/core/workflow/nodes/llm/node.py
  → api/core/model_runtime/model_providers/*/llm.py    # 生成答案

Chat 应用走 api/services/app_generate_service.py,最终仍复用 core/rag/retrieval/,但 变量分支与 if_else 只在 Workflow 路径完整暴露——故大师优先读 Workflow。


五、grep 起手式

cd dify/api
rg -n "class HybridRetriever" core/rag/retrieval/
rg -n "KnowledgeRetrieval" core/workflow/nodes/
rg -n "class GraphEngine" core/workflow/graph/
rg -l "RetrievalService" core/rag/ services/
rg "bm25_weight|vector_weight" core/rag/retrieval/ -n

对比 WeKnora 同题:Ch22 请求生命周期 — Handler→Service→HybridSearch;Dify 多一层 GraphEngine 节点调度


六、与 WeKnora / Lab 对照

Dify 能力 WeKnora 可借鉴 Lab 验证
可视化 DAG + if_else 低分分支 文档化推荐工作流,不必先做 UI Ch37 C 组
HTTP 节点调外部检索 官方 API 作 Dify 后端 weknora-arch.md

案例:case-1774 ↔ Dify controllersservices 分层。


七、动手练习(45–60 分钟)

时段 任务
0–15 min Docker 起服务,UI 搭「知识检索 → LLM」Workflow
15–30 min DevTools 抓 run 请求,rg 定位 knowledge_retrieval/node.py
30–45 min hybrid.py,记录 BM25/向量默认权重与是否支持 Rerank
45–60 min 上传 lab/corpus/weknora-arch.md,问 A1「错误码 E1042」类 query,写 5 行:Dify 混合检索 vs WeKnora RRF 差异

章末自检


延伸阅读