第一章:Dify 整体架构总览

5 阅读7分钟

第一章:Dify 整体架构总览

本章目标

通过本章的阅读,你将能够:

  • 理解 Dify 项目的整体架构设计,从前端到后端的完整技术栈
  • 了解 Dify 前端采用的 React + Next.js + Zustand + TailwindCSS 技术组合
  • 建立 Vue2 开发者到 React/Next.js 技术栈的核心概念映射
  • 对 Dify 的目录结构、模块划分、请求流程有全局认识
  • 为后续各章节的深入源码分析打下基础

必须阅读的源码文件或目录

优先级文件/目录说明
★★★dify-main/项目根目录,了解 Monorepo 整体布局
★★★dify-main/web/前端主工程
★★★dify-main/api/后端 Flask 工程
★★☆dify-main/pnpm-workspace.yamlMonorepo 工作空间配置
★★☆dify-main/web/package.json前端依赖与脚本定义
★★☆dify-main/web/next.config.tsNext.js 配置
★☆☆dify-main/docker/Docker 部署配置
★☆☆dify-main/packages/共享包(UI 组件库、合同定义等)

1. Dify 是什么

Dify 是一个开源的 LLM 应用开发平台,提供了可视化的 Prompt 编排、RAG(检索增强生成)管道、Agent 智能体、工作流引擎等能力。它融合了后端即服务(BaaS)和 LLMOps 的理念,让开发者能够快速构建和部署 AI 原生应用。

从技术角度看,Dify 是一个典型的前后端分离的 Web 应用,前端使用 React + Next.js,后端使用 Python Flask,通过 RESTful API 和 SSE(Server-Sent Events)进行通信。

Vue2 开发者视角的对照

概念Vue2 生态Dify 前端(React 生态)
UI 框架Vue 2.xReact 19
脚手架Vue CLI / ViteNext.js (App Router)
路由vue-routerNext.js 文件系统路由
状态管理Vuex / PiniaZustand + Jotai + React Query
样式方案scoped CSS / Less/SassTailwindCSS (原子化 CSS)
HTTP 请求axiosky + @orpc/client
实时通信socket.io-clientsocket.io-client (相同)
类型系统— (可选)TypeScript (强类型)
国际化vue-i18ni18next + react-i18next
组件库Element UI / Ant Design Vue@langgenius/dify-ui (自研)
构建工具Webpack / ViteTurbopack (Next.js 内置)
包管理npm / yarnpnpm (workspace monorepo)

2. 整体架构图

graph TB
    subgraph "用户层"
        A[浏览器 / Web 应用]
    end

    subgraph "前端 (Dify Web)"
        B[Next.js App Router]
        B1[React 组件树]
        B2[Zustand 状态管理]
        B3[React Query 服务端状态]
        B4[TailwindCSS 样式]
    end

    subgraph "网关层"
        C[Nginx 反向代理]
    end

    subgraph "后端 (Dify API)"
        D[Flask 应用]
        D1[Controllers 路由层]
        D2[Services 业务层]
        D3[Models 数据层]
        D4[Celery 任务队列]
    end

    subgraph "数据 & 基础设施"
        E1[(PostgreSQL / MySQL)]
        E2[(Redis)]
        E3[(向量数据库)]
        E4[对象存储]
    end

    A -->|HTTP/SSE| C
    C --> B
    B --> B1
    B --> B2
    B --> B3
    B1 --> B4
    C --> D
    D --> D1
    D1 --> D2
    D2 --> D3
    D --> D4
    D3 --> E1
    D --> E2
    D2 --> E3
    D --> E4

3. Monorepo 仓库结构

Dify 采用 pnpm workspace 进行 Monorepo 管理。整个仓库源码位于 dify-main/ 目录下:

dify-main/
├── web/                    # ★ 前端应用:Next.js + React + TypeScript
│   ├── app/                #    Next.js App Router 页面与路由
│   ├── components/         #    业务组件
│   ├── service/            #    API 请求封装层
│   ├── models/             #    数据模型定义
│   ├── context/            #    React Context 状态提供者
│   ├── hooks/              #    自定义 React Hooks
│   ├── config/             #    前端配置
│   ├── i18n/               #    国际化翻译文件
│   ├── types/              #    TypeScript 类型声明
│   ├── themes/             #    主题配置
│   ├── constants/          #    常量定义
│   ├── utils/              #    工具函数
│   ├── features/           #    功能模块
│   └── public/             #    静态资源
│
├── api/                    # ★ 后端应用:Python Flask
│   ├── controllers/        #    路由控制器
│   │   ├── console/        #      管理后台 API
│   │   ├── web/            #      Web 应用 API
│   │   ├── service_api/    #      对外服务 API
│   │   └── files/          #      文件上传 API
│   ├── services/           #    业务逻辑层
│   ├── models/             #    数据模型 (SQLAlchemy)
│   ├── core/               #    核心框架工具
│   ├── extensions/         #    Flask 扩展
│   ├── migrations/         #    数据库迁移脚本
│   └── tasks/              #    Celery 异步任务
│
├── packages/               # 共享包
│   ├── dify-ui/            #    UI 组件库 (@langgenius/dify-ui)
│   ├── contracts/          #    前后端接口合同定义
│   ├── tsconfig/           #    共享 TypeScript 配置
│   └── iconify-collections/ #  图标集合
│
├── docker/                 # Docker 部署配置
│   ├── nginx/              #    Nginx 反向代理
│   ├── pgvector/           #    PostgreSQL + pgvector
│   └── ...                 #    其他服务
│
├── sdks/                   # SDK
│   └── nodejs-client/      #    Node.js SDK
│
├── e2e/                    # 端到端测试
├── docs/                   # 文档站
└── scripts/                # 构建和工具脚本

关键配置文件

文件作用
pnpm-workspace.yaml定义 Monorepo 包含哪些子包(web, e2e, sdks/, packages/
web/package.json前端项目依赖与 npm scripts
web/next.config.tsNext.js 核心配置(basePath, 页面扩展名, 跨域等)
web/vite.config.tsVite 配置(用于测试和 Storybook)
Makefile项目级构建脚本(构建、测试、lint 等)

4. 前端技术栈深度解析

4.1 React 19 + Next.js (App Router)

Dify 使用 Next.js 的 App Router 模式(而非旧的 Pages Router),这是 Next.js 13+ 引入的新路由系统。

与 Vue2 + vue-router 的核心差异:

特性Vue2 + vue-routerNext.js App Router
路由定义手动配置 routes.js文件系统即路由app/xxx/page.tsx 自动成为路由
布局通过 <router-view> 嵌套layout.tsx 文件自动包裹子页面
数据获取mounted 钩子中调用 API支持 Server Component 直接在服务端获取数据
渲染模式纯客户端渲染 (CSR)SSR / SSG / ISR / CSR 混合
路由分组命名视图括号文件夹 (groupName) 不影响 URL

示例:Dify 的路由分组

app/
├── (commonLayout)/        ← URL 不变,共享管理后台布局
│   ├── apps/              → /apps
│   ├── datasets/          → /datasets
│   ├── explore/           → /explore
│   ├── plugins/           → /plugins
│   └── tools/             → /tools
├── (shareLayout)/         ← URL 不变,共享分享页布局
├── signin/                → /signin
└── signup/                → /signup

4.2 状态管理:Zustand + Jotai + React Query

Dify 的前端采用了三层状态管理策略,而非单一状态树:

graph LR
    subgraph "服务端状态"
        A[React Query<br/>@tanstack/react-query]
        A1[缓存 API 响应]
        A2[自动重新请求]
        A3[乐观更新]
    end

    subgraph "全局客户端状态"
        B[Zustand]
        B1[应用列表状态]
        B2[数据集详情]
        B3[调试配置]
    end

    subgraph "局部/原子状态"
        C[Jotai]
        C1[UI 临时状态]
        C2[跨组件共享变量]
    end

    A -->|API 数据| B
    B -->|派生状态| C

Vue2 对照:Vuex 把所有状态(服务端数据 + 客户端 UI 状态)都放在一个 Store 里,而 Dify 将"服务端缓存"(React Query)和"客户端状态"(Zustand)分离,各司其职。

4.3 请求层:ky + @orpc/client

Dify 不使用 axios,而是:

  • ky:基于 Fetch API 的轻量 HTTP 客户端,用于普通 REST 请求
  • @orpc/client:类型安全的 RPC 客户端,与后端共享接口合同

HTTP 请求的封装集中在 web/service/ 目录下,每个业务域有独立的 service 文件:

service/
├── apps.ts          # 应用相关 API
├── datasets.ts      # 数据集相关 API
├── workflow.ts      # 工作流相关 API
├── plugins.ts       # 插件相关 API
├── share.ts         # 分享相关 API
├── base.ts          # 基础请求封装
├── fetch.ts         # Fetch 底层封装
└── ...

4.4 TailwindCSS:原子化 CSS

Dify 使用 TailwindCSS 4(通过 @tailwindcss/vite 插件)进行样式管理。与 Vue2 中常见的 scoped CSS 或组件库样式覆盖不同,TailwindCSS 通过原子类直接在 JSX 中书写样式:

// TailwindCSS(Dify 实际方式)
<div className="flex items-center gap-2 px-4 py-2 bg-blue-500 rounded-lg">
  <span className="text-white text-sm font-medium">提交</span>
</div>

// Vue2 等价写法
// <div class="submit-btn">
//   <span>提交</span>
// </div>
// <style scoped>
// .submit-btn { display: flex; align-items: center; gap: 8px;
//               padding: 8px 16px; background: #3B82F6; border-radius: 8px; }
// .submit-btn span { color: white; font-size: 14px; font-weight: 500; }
// </style>

后面的第六章将详细讲解 TailwindCSS 的实战用法。

5. 后端技术栈概览

层级技术说明
Web 框架Flask轻量 Python Web 框架
ORMSQLAlchemy数据库 ORM
数据库PostgreSQL + pgvector关系数据 + 向量存储
缓存Redis会话、缓存、消息队列
任务队列Celery异步任务处理
迁移Alembic (Flask-Migrate)数据库版本管理
实时通信SSE流式返回 LLM 生成结果
向量数据库支持多种(Weaviate/Qdrant/Milvus 等)向量检索

API 路由分组

api/controllers/
├── console/       # 管理后台 API(/console/api/*)
│   ├── app/       #   应用管理
│   ├── datasets/  #   数据集管理
│   ├── explore/   #   探索页
│   └── ...        #
├── web/           # Web 应用 API(/api/*)
│   ├── app.py     #   用户端应用调用
│   └── ...        #
├── service_api/   # 对外 Service API(/v1/*)
├── files/         # 文件上传
├── inner_api/     # 内部 API(Worker 调用)
└── mcp/           # MCP 协议接口

6. 请求全链路示例

以"用户创建一个应用"为例,完整调用链路如下:

sequenceDiagram
    participant B as 浏览器
    participant N as Next.js
    participant F as Flask API
    participant D as PostgreSQL
    participant R as Redis

    B->>N: 访问 /apps 页面
    N->>N: Server Component 预渲染
    N->>B: HTML 响应
    B->>F: GET /console/api/apps
    F->>D: SELECT * FROM apps
    D->>F: 应用列表
    F->>B: JSON 响应
    B->>B: React Query 缓存
    B->>B: Zustand 更新 store
    B->>B: 渲染应用卡片列表

    Note over B,R: 用户点击"创建应用"

    B->>F: POST /console/api/apps
    F->>D: INSERT INTO apps
    D->>F: 新应用记录
    F->>B: JSON 响应(应用详情)
    B->>B: React Query invalidate
    B->>B: 自动重新请求列表
    B->>B: 渲染更新后的列表

7. 二次开发切入点总览

作为前端二次开发者,你的主要关注区域集中在 dify-main/web/ 目录。以下是一个快速索引:

想要做什么从哪里下手
新增一个页面web/app/(commonLayout)/ 下新建目录 + page.tsx
修改 API 请求web/service/ 下对应的 service 文件
修改/新增组件web/app/components/ 下的业务组件
调整全局状态web/context/ 或新建 Zustand store
修改样式/主题web/themes/ 和 TailwindCSS 类名
添加翻译web/i18n/ 下的语言文件
添加常量/配置web/constants/web/config/
使用新的 UI 组件@langgenius/dify-ui 包(位于 packages/dify-ui/

8. 注意事项与坑点提示

  1. Monorepo 依赖管理:Dify 强制使用 pnpm,npm installyarn 会报错(preinstall 脚本有检查)。安装依赖请用 pnpm install

  2. TypeScript 强类型:整个前端项目使用 TypeScript,没有 .js 文件。Vue2 开发者需要适应类型注解、泛型、接口等概念。建议从第三章开始逐步适应。

  3. Server Component vs Client Component:Next.js App Router 区分服务端组件(默认)和客户端组件('use client' 指令)。服务端组件不能使用 useStateuseEffect、浏览器 API。这是 Vue2 中完全没有的概念,需要在开发中时刻注意。

  4. 文件系统路由:路由由文件夹和文件决定,不是由配置文件决定。新增页面只需创建 page.tsx,无需修改 router 配置。

  5. CSS 方案不同:TailwindCSS 是原子化 CSS,类名很长但很灵活。不要试图用传统的 BEM 或 CSS Module 方式覆盖,应遵循项目现有模式。

  6. pnpm-workspace 的包引用packages/dify-ui/ 作为内部包,通过 workspace:* 协议引用。修改 UI 组件库后需要在根目录重新 pnpm install

  7. 环境变量:前端环境变量以 NEXT_PUBLIC_ 为前缀的会被暴露到浏览器端。.env.local 用于本地开发。


下一章预告:第二章将带你深入了解 Dify 前端的运行流程——从 pnpm dev 到页面渲染,完整追踪启动过程、中间件、请求拦截、登录态管理等核心机制。