dify_workflow/
├── __init__.py # 包入口,版本号
├── models.py # Pydantic v2 数据模型(全模式 DSL 结构定义)
├── editor.py # 通用图编辑操作(节点/边增删改)
├── validator.py # 模式分派校验器(自动检测模式→调用专用校验)
├── node_data_validator.py # 节点数据校验(对齐 Dify graphon 节点 schema)
├── node_validators_core.py # 核心节点校验器(LLM/Code/HTTP/IF-ELSE/Tool 等)
├── node_validators_extra.py # 扩展节点校验器(Iteration/Loop/Agent 等)
├── frontend_validator.py # 前端崩溃预防校验(对齐 Dify React 前端渲染要求)
├── checklist_validator.py # Pre-publish 清单(对齐 Dify use-checklist.ts 三层校验)
├── checklist_checks.py # 清单子检查函数
├── layout.py # 自动布局引擎(5 种策略调度)
├── layout_tree.py # 树形布局算法(Dify 风格左→右分支分组)
├── mermaid.py # Mermaid 流程图输出
├── io.py # YAML/JSON 文件读写 + 模式感知序列化
├── scanner.py # [废弃] dify-test 源码扫描分析
├── cli.py # Click CLI 入口(命令注册)
├── cli_edit.py # edit 子命令组
├── cli_config.py # config 子命令组
├── cli_inspect.py # inspect 命令
├── cli_ops.py # validate / checklist / export / import / diff / layout
├── cli_shared.py # CLI 公共工具
├── workflow/ # Workflow 模式 (mode=workflow)
│ ├── editor.py # 模板创建:minimal / llm / if-else
│ └── validator.py # 图结构校验:start/end、连通性、环检测、checklist
├── chatflow/ # Chatflow 模式 (mode=advanced-chat)
│ ├── editor.py # 模板创建:chatflow / knowledge
│ └── validator.py # chatflow 校验:Answer 节点、LLM memory
├── model_config_validators/ # 共享 model_config 校验模块(对齐 Dify ConfigManager 链)
│ ├── __init__.py
│ ├── model_validator.py # model 配置校验(provider/name/mode/stop)
│ ├── variables_validator.py # user_input_form 校验(类型/label/variable 格式/唯一性)
│ ├── prompt_validator.py # prompt_type + prompt_config 校验
│ ├── dataset_validator.py # dataset_configs 校验(retrieval_model/UUID/query_variable)
│ ├── agent_mode_validator.py # agent_mode 校验(enabled/strategy/tools/tool_parameters)
│ └── features_validator.py # Features 校验(TTS/STT/开场白/敏感词等)
├── chat/ # 聊天助手模式 (mode=chat)
│ ├── editor.py # model_config 编辑操作
│ └── validator.py # 共享校验链 + chat 专属规则
├── agent/ # Agent 模式 (mode=agent-chat)
│ ├── editor.py # Agent 配置:strategy / 工具管理
│ └── validator.py # 共享校验链 + agent_mode/strategy/tools 校验
└── completion/ # 文本生成模式 (mode=completion)
├── editor.py # completion 配置
└── validator.py # 共享校验链 + dataset_query_variable/features 校验
| 组件 | 选择 | 原因 |
|---|---|---|
| CLI 框架 | Click 8.x | 成熟稳定,支持子命令、参数校验、OrderedGroup |
| 数据模型 | Pydantic v2 | 类型安全,ConfigDict,validation_alias/serialization_alias |
| YAML | PyYAML | 标准库级别,Dify 原生使用 |
| 输出美化 | Rich | 树形结构、表格、彩色输出 |
| 测试 | pytest | 行业标准,513 个测试 |
| 运行时 | Python 3.12 | 类型提示、match 语法 |
- 所有模型字段名与 Dify 导出的 YAML 完全一致
- 能加载 Dify 导出的真实 DSL 文件(经 dify-test fixture 验证)
- 导出格式可直接被 Dify 导入
Dify 的 5 种应用模式分为两种底层架构:
| 架构 | 模式 | 核心数据结构 | CLI 编辑命令 |
|---|---|---|---|
| Workflow-based | workflow, advanced-chat (chatflow) | workflow.graph (nodes + edges) |
edit 命令组 |
| ModelConfig-based | chat, agent-chat, completion | model_config (model + prompt + tools) |
config 命令组 |
- 所有命令支持
-j/--json-output输出结构化 JSON - 支持非交互模式(无需人工确认)
- 参数接受 JSON 字符串(
-d '{"key": "value"}')和--data-file文件 - 错误信息明确,包含 node_id 和字段名
guide命令提供渐进式教程list-node-types命令发现可用节点类型
- 纯文件操作,不依赖远程 API 或数据库
- 读 → 改 → 验证 → 导出 全部在本地完成
- 支持 YAML 和 JSON 双格式
- 每种应用模式独立目录(workflow / chatflow / chat / agent / completion)
- 每个目录有独立的 editor.py + validator.py
- 通过
__init__.py控制公开 API - 通过顶层
validator.py统一分派,用户无需关心内部细节
┌──────────────────────────────────────────────────────┐
│ CLI Layer │
│ cli.py — Click 命令定义 │
│ 命令组:create / edit / config / validate / ... │
│ 输入解析、输出格式化(JSON/Rich) │
├──────────────────────────────────────────────────────┤
│ Service Layer │
│ editor.py — 通用图编辑操作(add_node/edge/etc.) │
│ workflow/editor.py — workflow 模板创建 │
│ chatflow/editor.py — chatflow 模板创建 │
│ chat/editor.py — model_config 编辑 │
│ agent/editor.py — agent 配置 + 工具管理 │
│ completion/editor.py — completion 配置 │
├──────────────────────────────────────────────────────┤
│ Validator Layer │
│ validator.py — 统一分派入口 │
│ node_data_validator.py — 逐节点数据校验(25 种类型) │
│ frontend_validator.py — 前端崩溃预防校验(16 种类型) │
│ checklist_validator.py — Pre-publish 清单(三层校验) │
│ layout.py + layout_tree.py — 自动布局(5 种策略) │
│ mermaid.py — Mermaid 流程图输出 │
│ workflow/validator.py — 图结构+环检测+连通性+checklist │
│ chatflow/validator.py — Answer 节点 + memory │
│ model_config_validators/ — 6 个共享校验模块 │
│ model / variables / prompt / dataset / agent_mode / │
│ features(对齐 Dify ConfigManager 链) │
│ chat/validator.py — 共享链 + opening_statement 等 │
│ agent/validator.py — 共享链 + agent_mode.enabled/tools │
│ completion/validator.py — 共享链 + query_variable 等 │
├──────────────────────────────────────────────────────┤
│ I/O Layer │
│ io.py — YAML/JSON 文件读写、模式感知序列化 │
│ _clean_export_data() 清理空字段 │
│ by_alias=True 确保 model_config 正确序列化 │
├──────────────────────────────────────────────────────┤
│ Model Layer │
│ models.py — Pydantic v2 模型 │
│ DifyDSL — 顶层文档(统一所有模式) │
│ ModelConfigContent — chat/agent/completion 配置 │
│ Graph / Node / Edge — 工作流图结构 │
│ AppMode / NodeType — 枚举 │
└──────────────────────────────────────────────────────┘
class DifyDSL(BaseModel):
model_config = ConfigDict(extra="allow", populate_by_name=True)
version: str = "0.6.0"
kind: str = "app"
app: AppInfo = AppInfo()
workflow: WorkflowContent = WorkflowContent()
model_config_content: ModelConfigContent | None = Field(
default=None,
validation_alias="model_config", # YAML 中的 model_config 键
serialization_alias="model_config", # 导出时用 model_config 键
)
dependencies: list[dict] = []关键设计:Pydantic v2 中
model_config是保留类变量(ConfigDict),不能作为字段名。 因此使用model_config_content作为 Python 属性名,通过validation_alias和serialization_alias映射到 YAML 中的model_config。
WORKFLOW_MODES = frozenset({AppMode.WORKFLOW, AppMode.ADVANCED_CHAT})
CONFIG_MODES = frozenset({AppMode.CHAT, AppMode.AGENT_CHAT, AppMode.COMPLETION})
@property
def is_workflow_based(self) -> bool:
return self.app.mode in WORKFLOW_MODES
@property
def is_config_based(self) -> bool:
return self.app.mode in CONFIG_MODESDifyWorkflowDSL = DifyDSL # 旧代码使用的别名仍可用validator.py 是统一入口,自动检测 app.mode 并分派到模式专用校验器:
| 模式 | 校验器 | 校验内容 |
|---|---|---|
| workflow | workflow.validator.validate_workflow_mode() |
顶层字段、图结构、节点规则、边合法性、环检测、连通性、pre-publish 清单 |
| advanced-chat | chatflow.validator.validate_chatflow_mode() |
同 workflow + Answer 节点检查 + memory 建议 |
| chat | chat.validator.validate_chat_mode() |
共享校验链(model→variables→prompt→dataset→features) + opening_statement、suggested_questions、agent_mode 启用警告 |
| agent-chat | agent.validator.validate_agent_mode() |
共享校验链 + agent_mode_fields(enabled/strategy/tools/tool_parameters)、enabled 必须为 true、无 tools 警告 |
| completion | completion.validator.validate_completion_mode() |
共享校验链(含 dataset_query_variable 必填)+ opening_statement/SQA/STT 不适用警告、无 user_input_form 警告 |
| 维度 | 检查内容 |
|---|---|
| 顶层校验 | version、kind、app.name、app.mode 存在性 |
| 图结构校验 | 节点非空、ID 唯一、有 start 节点、start/trigger 不共存 |
| 节点数据校验 | 25 种节点类型的必填字段、类型约束、枚举值合法性(对齐 Dify graphon schema) |
| 前端崩溃预防 | 16 种节点类型的前端渲染必填字段(对齐 Dify React 前端 node.tsx / initialNodes()) |
| HumanInput 深度校验 | inputs[].output_variable_name 必填、delivery_methods[].id 必须为 UUID、user_actions 标识符格式、去重等 |
| 边校验 | 端点存在、无自环、ID 唯一 |
| 环检测 | DFS 3-color 算法检测 DAG 中的环(对齐 Dify 前端 getCycleEdges),环上所有边会被前端移除导致断连 |
| 连通性校验 | BFS 从 start 出发,检测孤立节点(含 Iteration/Loop 子节点遍历) |
| Pre-publish 清单 | 对齐 Dify 前端 use-checklist.ts:节点配置完整性、上游变量引用有效性、所有节点可达 |
| 命令 | 功能 |
|---|---|
guide |
渐进式教程(6 步) |
list-node-types |
列出全部 25 种节点类型 |
scan |
[废弃] 扫描 dify-test 源码分析 |
create |
创建应用(支持 5 种模式 + 多种模板) |
inspect |
查看结构(树形 / JSON / Mermaid,自动识别模式) |
validate |
校验合法性(结构 + 节点数据 + 连通性 + 环检测) |
checklist |
Pre-publish 清单(对齐 Dify 前端检查面板) |
export |
导出为 YAML / JSON |
import |
导入、校验、再导出 |
diff |
对比两个文件差异 |
layout |
自动布局节点(5 种策略:tree / hierarchical / linear / vertical / compact) |
| 子命令 | 功能 |
|---|---|
add-node |
添加节点 |
remove-node |
删除节点(自动清理连线) |
update-node |
更新节点数据字段 |
add-edge |
添加连线 |
remove-edge |
删除连线 |
set-title |
修改节点标题 |
layout |
自动排版布局(linear/hierarchical/vertical/compact) |
| 子命令 | 功能 |
|---|---|
set-model |
设置 LLM 模型和参数 |
set-prompt |
设置系统提示词 (pre_prompt) |
add-variable |
添加用户输入变量 |
set-opening |
设置开场白 |
add-question |
添加推荐问题 |
add-tool |
添加 Agent 工具 |
remove-tool |
移除 Agent 工具 |
layout.py 提供 4 种布局策略,一键重排工作流节点位置:
| 策略 | 方向 | 算法 | 适用场景 |
|---|---|---|---|
linear |
左→右 | 按拓扑序排列在同一水平线 | 简单顺序流程 |
hierarchical |
左→右 | DAG 分层 + 交叉最小化 + 居中对齐 | 默认,适合多分支工作流 |
vertical |
上→下 | 同 hierarchical,轴向旋转 90° | 纵向展示 |
compact |
左→右 | 同 hierarchical,间距压缩 40% | 大型工作流需要紧凑视图 |
┌─────────────────────────────────────────────────────────────┐
│ Step 1: 构建图 │
│ nodes[] + edges[] → adjacency list + reverse adjacency │
├─────────────────────────────────────────────────────────────┤
│ Step 2: 分层(Layer Assignment) │
│ BFS 从源节点出发,layer = max(所有父节点层) + 1 │
│ 保证分支和合并节点在正确的深度层级 │
├─────────────────────────────────────────────────────────────┤
│ Step 3: 层内排序(Cross Minimization) │
│ 重心法(Barycenter Heuristic): │
│ · 正向扫描:节点按其前驱的平均位置排序 │
│ · 反向扫描:节点按其后继的平均位置排序 │
│ · 迭代 4 轮收敛 │
│ 分支顺序遵循 if-else case / question-classifier class 顺序 │
├─────────────────────────────────────────────────────────────┤
│ Step 4: 坐标计算(Position Assignment) │
│ 层内节点垂直居中 │
│ 间距参数对齐 Dify 前端 ELK 配置: │
│ · 层间距:100px(compact: 60px) │
│ · 节点间距:80px(compact: 40px) │
│ · 节点尺寸:244×90px │
└─────────────────────────────────────────────────────────────┘
# 默认 hierarchical 布局
dify-workflow layout -f workflow.yaml
# 指定布局策略
dify-workflow layout -f workflow.yaml --strategy vertical
# 布局后输出到新文件
dify-workflow layout -f workflow.yaml -o workflow-laid-out.yaml
# 结合 JSON 输出
dify-workflow layout -f workflow.yaml -jfrom dify_workflow.layout import auto_layout
# 重排节点位置(修改 dsl 对象原地更新)
auto_layout(dsl, strategy="hierarchical")io.py 中的 _clean_export_data() 根据应用模式清理导出数据:
- Workflow-based 应用:移除空的
model_config字段 - ModelConfig-based 应用:移除空的
workflow字段(仅含默认空图) - 所有模式:
model_dump(by_alias=True)确保model_config_content序列化为model_config
tests/
├── test_models.py # 19 个测试 — 数据模型
├── test_editor.py # 32 个测试 — 图编辑操作
├── test_validator.py # 14 个测试 — 校验逻辑
├── test_node_data_validator.py # 76 个测试 — 节点数据校验
├── test_frontend_validator.py # 43 个测试 — 前端崩溃预防校验
├── test_layout.py # 32 个测试 — 自动布局引擎
├── test_io.py # 12 个测试 — 文件读写
├── test_cli.py # 43 个测试 — CLI 命令端到端
├── test_integration.py # 19 个测试 — 集成场景 + Dify fixture 真实校验
├── test_chatflow.py # 8 个测试 — Chatflow 模块
├── test_chat.py # 19 个测试 — 聊天助手模块
├── test_agent.py # 15 个测试 — Agent 模块
└── test_completion.py # 11 个测试 — 文本生成模块
──────────
361 个测试 全部通过
每个模式目录遵循相同的结构:
<mode>/
├── __init__.py # 公开 API 导出
├── editor.py # 创建和编辑操作
└── validator.py # 模式专用校验
新增模式只需:
- 创建新目录,实现 editor.py + validator.py
- 在顶层
validator.py的分派逻辑中注册 - 在
cli.py的_create_by_mode()中添加分支
DifyDSL 模型设置了 extra="allow",可兼容其他平台的额外字段。
未来可通过 PlatformAdapter 基类实现百炼 / 腾讯 ADP 等平台的转换。