workflow-vs-dify-comparison.md 37 KB

工作流特性对比:agent-management vs Dify

对比目的:以 Dify 1.16.0 开源参考实现(详见 docs/dify-readme.md)为坐标系,定位本仓库(agent-management)工作流引擎的能力边界、创新点与可借鉴的演进方向。

对比维度:节点类型与编排、调度与执行、信封化与校验、变量与输入解析、智能体集成、画布编辑器、HITL、可观测、外部 API、生态扩展。

信息来源:

  • 本仓库需求与设计:prompt.mddocs/workflow-*.mddocs/context-passing-architecture.mddocs/external-workflow-api-spec.mddocs/hermes-*.md
  • 本仓库实现:backend/src/main/java/com/agent/management/engine/**
  • Dify 实现:dify/api/core/workflow/**dify/dify-agent/src/**dify/dify-agent-runtime/**

0. 结论速览

维度 量化对比
本仓库独有特性 21 项(详见 §2)
Dify 独有特性 21 项(详见 §3)
实现方法差异 15 项(详见 §4)
设计哲学 本仓库:单体 + 强一致 envelope + 引擎层统一治理(适合企业内部可控场景)
Dify:微服务 + 插件化生态 + 多形态应用(适合多租户 SaaS / 开源社区)

1. 总体定位差异

维度 agent-management Dify
项目类型 企业内部 AI 编码助手平台 开源 LLMOSS(LLM Operating System / Stack)
后端实现 Java 17 + Spring Boot 单体 Python + Flask + Celery + 多服务编排
节点类型 硬编码 8 种 内置 + 插件扩展(plugin_daemon)
应用形态 Workflow 一种 Workflow / Chat / AdvancedChat / Completion / AgentChat 五种
部署形态 单 JAR + MySQL + Redis 11 个 docker-compose 服务(含 Plugin Daemon / Agent Backend / Local Sandbox 等)
Agent 引擎 Hermes Bridge(Python 子进程)+ Spring AI ChatClient CotAgentRunner / FunctionCallAgentRunner / dify-agent(pydantic-ai)
沙箱实现 Python 三层 monkey-patch(路径白名单) Go Landlock LSM + tmux + sanitize-pty

核心差异:本仓库追求轻量、强一致、企业内部可控;Dify 追求生态、可扩展、多形态覆盖


2. 本仓库具备而 Dify 没有的功能

2.1 工作流引擎层

# 特性 关键行为 实现位置
1 统一 envelope 全节点强制 所有节点(LLM / Agent / SmartAction / Hermes* / Knowledge / Condition / UserInput / Output)严格产出 {status, message, data} 三段式结构,多余字段丢弃;Dify 仅 Agent v2 节点强制 declared outputs,其他节点"尽力推断" engine/NodeOutputEnvelope.javadocs/workflow-node-output-envelope.md 2.6
2 统一 failStrategy(abort/skip) 引擎层 WorkflowLevelExecutor 提供节点级 failStrategy 配置;Dify 没有此配置,失败处理散落各节点内部(Agent v2 有 OutputFailureOrchestrator,但仅限该节点) engine/WorkflowLevelExecutor.javadocs/workflow-node-output-envelope.md 2.10
3 Dataflow 调度 + SKIPPED 状态 从 BSP(层同步)改造为 Dataflow:节点完成即触发后继(基于 pendingInputs: Map<nodeId, AtomicInteger> 入度计数),不被同层慢节点阻塞;条件分支未选路径自动标记 SKIPPED;Dify 的 NodeOutputStatus 枚举无 SKIPPED 状态(只有 PENDING/RUNNING/READY/TYPE_CHECK_FAILED/OUTPUT_CHECK_FAILED/NOT_PRODUCED/FAILED) docs/workflow-dataflow-execution-plan.mddify/api/services/workflow/node_output_inspector_service.py:84-103
4 节点级 abort 取消在飞节点 abortFlag(AtomicBoolean)+ inFlightFutures Map,失败时 CAS 设置并 cancel(true) 所有在飞节点;Dify 节点失败后是否取消兄弟节点由 GraphEngine 图级策略决定,Dify 侧不可见也无显式 API engine/WorkflowLevelExecutor.java 阶段 3
5 envelope 失败自动升级 result.status == SUCCESS && envelope.isFailure() 时引擎自动升级为 NodeExecutionResult.failed,按 failStrategy 处理;失败 envelope 仍写入上下文供下游感知 docs/hermes-error-detection-plan.md 方案 D

2.2 节点输入与变量系统

# 特性 关键行为 实现位置
6 四级模糊匹配 fallback 节点输入解析按拓扑逆序遍历可达前驱,依次尝试:①精确同名 → ②模糊同名(忽略 - _ 和大小写)→ ③JSON 嵌套精确同名 → ④JSON 嵌套模糊同名;Dify 通过 variable_pool 直接寻址,无模糊匹配 docs/workflow-variable-scope-design.md 4.3、dify/api/core/workflow/variable_pool_initializer.py
7 envelope.data 穿透取值 四级匹配全部穿透 envelope.data 内部取值,不再读扁平 Map 顶层;Dify 没有这种 envelope-aware 的输入解析 docs/workflow-node-output-envelope.md 2.9
8 NodeWorkspace 仅含可达前驱 节点开始执行前构建工作区,仅包含可达前驱(反向 BFS 计算)的输出,避免无关变量污染;Dify 通过共享 variable_pool,无显式工作区隔离 docs/workflow-variable-scope-design.md 2.1
9 前驱变量删除后自动回退关联 边变化导致前驱不再是可达前驱时,节点 inputs/output fields 的显式 mapping 自动回退为「自动推断」(autoMapped=true);Dify 通过手动 variable selector 重新选择,无自动回退 docs/workflow-variable-scope-design.md 3.2
10 运行工作目录 + .agentignore 每次运行分配 <data-dir>/workflow-runs/{workflowId}/{runId}/,所有节点共享;.agentignore 排除 .hermes/*.log*.tmp 等;可打包下载 zip;Dify 有 Local Sandbox 沙箱但没有 .agentignore 机制 docs/external-workflow-api-spec.md 3.5

2.3 LLM 结构化输出与重试

# 特性 关键行为 实现位置
11 错误回注 prompt 的自我修正重试 StructuredOutputHelper.extractWithRetry 校验失败时把 lastError(如"缺少 required 字段 xxx")注入 prompt 让 LLM 自我修正;Dify 没有这种"错误回注"的统一机制 engine/StructuredOutputHelper.javadocs/workflow-node-output-envelope.md 2.2
12 三级 JSON 提取容错 ①直接 JSON 解析 → ②`json 代码块提取 → ③首尾 {} 子串提取;适配 LLM 不稳定输出;Dify 通过 litellm + json-repair 0.60 在底层处理 engine/StructuredOutputHelper.java
13 类型静默自动转换 声明 number + 字符串数字 → 静默转换;boolean + "true"/"1"/"yes" → true;array/object + JSON 文本 → 解析;Dify 类型校验在 OutputTypeChecker 但更严格,无静默转换 engine/OutputValidator.javadify/api/core/workflow/nodes/agent_v2/output_type_checker.py
14 双循环重试(计划中) 外层 runtime retry(重新完整推理,默认 2 次)+ 内层 format retry(仅重组 JSON,不重跑业务,默认 2 次);内层耗尽升级为外层;Dify 无此分层 docs/workflow-envelope-strict-validation-plan.md 阶段 3
15 节点级 retry 配置覆盖全局 RetryPolicy.fromNodeData 解析节点 data.maxRetries / retryOn*,覆盖 application.yml 默认值;Dify Agent v2 的重试在节点内部硬编码(OutputFailureOrchestrator) engine/RetryPolicy.java

2.4 智能体与 Hermes 集成

# 特性 关键行为 实现位置
16 Hermes Bridge(Python 子进程) HermesProcessManager 启动 Python bridge 子进程,注入 HERMES_BRIDGE_BASE_URL/API_KEY/MODEL 等环境变量,通过 SSE 通信(思考流 / 工具调用 / 最终结果);Dify Agent v2 通过独立 FastAPI 服务(pydantic-ai),架构不同 engine/hermes/HermesProcessManager.javabackend/hermes-bridge/hermes_bridge.py
17 Hermes Error Pattern 错误检测 内置错误模式数据模型(HermesErrorPattern)+ Java Client 嗅探(parseSseResponse 在 done 分支后 substring 匹配)+ 前端管理页(/hermes-errors);内置"访问量过大"、"无效的 api"等中文模式;Dify 没有 LLM 错误响应的模式化识别 service/impl/HermesErrorPatternServiceImpl.javadocs/hermes-error-detection-plan.md
18 三层 monkey-patch 沙箱 sandbox_patch.py 对 hermes-agent 的 _resolve_path_for_task(路径白名单)、_resolve_base_dir(相对路径锚定)、_git_root(阻断外层项目根注入)打补丁;通过 _SESSION_CWD contextvar 线程隔离;Dify 沙箱是 Go Landlock LSM + tmux(更底层但与 Hermes 无关) backend/hermes-bridge/sandbox_patch.pydocs/hermes-sandbox.md
19 默认模型实时路由 AiModelService.getDefaultModel 实时查询,application.yml 切换默认模型后立即生效,不再回退到旧默认;模型管理可设置调用顺序 fallback;Dify 模型在节点级硬绑定,无统一默认路由 service/AiModelService.java
20 Skill 文件预同步(方案 A) SkillFileSyncer.syncTo 在每次工作流执行前将 uploads/skills 下所有 skill 复制到工作目录 .hermes/skills,不复制历史版本文件;Dify 插件化体系不同,无此同步需求 engine/SkillFileSyncer.java
21 技能生成(Skill 生成 Skill) 技能编辑页可选「该技能具备生成其他技能的能力」;技能生成菜单选择生成器技能 → 调 hermes-bridge → 在工作目录生成 → 复制到全局技能目录 → 跳转编辑页;Dify 无"工具生成工具"的概念 service/impl/SkillGenerationServiceImpl.javaprompt.md 855-952 行

2.5 画布编辑器与运行时交互

# 特性 关键行为 实现位置
22 字段「引入」双向关联 节点 inputs 从前驱 outputs 引入、节点 outputs 从后继 inputs 引入;输入节点输入变量从后继输入引入(业务输入语义);输出节点输出变量从前驱输出引入(业务输出语义);引入后自动填入变量名/中文名/类型/描述;Dify 通过 variable selector 单向引用,无"输出字段反向关联后继" frontend/src/utils/ioInference.jsprompt.md 1188-1192 行
23 LLM 语义「自动关联」 点击「自动关联」按钮用 LLM 语义识别(非字符串匹配)哪些 Skill 的 SKILL.md 或智能操作工作流程中隐式调用了其他 Skill;识别结果以虚线框 + 虚线箭头画在画布上,技能节点位于虚线框中可拖动;Dify 无此"自动发现隐式依赖"能力 prompt.md 357、776 行
24 模板变量动态识别(无碎片) {{}} 中按顺序输入变量名时实时识别,区分「自动字段」(从 {{}} 识别)和「手动字段」(用户显式添加),避免中间变量碎片(a、ab、abc 三个变量);Dify 使用变量选择器 UI,无模板动态识别 prompt.md 1195、1200 行
25 画布级变量/字段/节点名唯一性校验 节点内变量名不能重复、画布节点名不能重复,保存时拦截并列出具体节点与变量;Dify 通过 variable selector 引用,名称冲突由用户自行管理 prompt.md 1265、1270 行
26 节点动态斥力 拖动节点后过近节点动态推开达到平衡(非生成时距离);Dify 用 ReactFlow + ELK.js 自动布局,无交互式斥力 prompt.md 806-818 行
27 运行对话框变量导出/导入 导出已填入变量为 JSON 文件(命名 工作流名称-节点名-输入变量.json),强制选择保存位置;导入时填入对应表单;Dify 表单提交,无导入导出 prompt.md 1276-1285 行
28 输入/输出节点变量标签颜色语义 输入节点变量蓝色(业务输入)、输出节点变量绿色(业务输出)、其他节点前置数据蓝/输出变量绿;Dify 节点端口样式统一 prompt.md 1264 行
29 思考过程折叠 + 流式继续 运行记录中思考过程支持折叠,折叠后仍接收流式响应只是不显示,展开后可继续输出;Dify Trace 工具(Langfuse 等)有类似能力但非画布原生 prompt.md 626 行
30 节点名称与类型双行显示 画布节点显示「节点名称 节点类型」,名称字体与类型字体区分;空时只显示节点类型;节点名称画布内唯一;Dify 节点显示样式不同 prompt.md 66、156 行

2.6 工作流标识与外部 API

# 特性 关键行为 实现位置
31 kebab-case 唯一标识 + 中文 displayName 分离 name 为 kebab-case(^[a-z0-9]+(-[a-z0-9]+)*$),URL 按 name 寻址;displayName 可任意字符(含中文);翻译只翻译 displayName 与正文,不破坏 name;Dify 工作流标识为 UUID service/WorkflowNameNormalizer.javadocs/workflow-crud-api.md
32 外部 API 三段式调用 创建运行(POST /runs)→ 启动(POST /runs/{runId}/start)→ 订阅(GET /runs/{runId}/stream);同步阻塞模式 async=false 直接 SSE;Dify 通过 Service API 单次调用,无"创建-启动-订阅"三段式 docs/external-workflow-api-spec.md 3.1-3.2
33 断线重连 SSE(Last-Event-ID) 通过 Last-Event-ID 头部续传,事件缓存窗口默认 1000 条或运行结束保留 1 小时;Dify 通过 socket.io 自动重连,但 SSE 模式无 Last-Event-ID 续传 docs/external-workflow-api-spec.md 5
34 工作目录 ZIP 打包下载 GET /runs/{runId}/workspace 返回 zip(应用 .agentignore);Dify Agent 沙箱内文件通过 drive API 单文件上传/下载,无打包下载 docs/external-workflow-api-spec.md 3.5
35 目录结构保留上传 通过 X-Relative-Path part header 保留目录结构,含 ZIP slip 防护;Dify 文件上传扁平化 docs/external-workflow-api-spec.md

3. 本仓库没有而 Dify 具备的能力

3.1 节点类型与编排

# 特性 Dify 实现 本仓库状态
1 迭代节点(iteration) core/workflow/nodes/iteration/ 支持数组迭代执行子图 ❌ 不支持
2 显式并行节点 / 并行分支 通过 GraphEngine 线程池 + 并行边 ⚠️ 仅同层并行(Dataflow 模式),无显式并行节点
3 问题分类器节点 question-classifier 节点用 LLM 把输入分类到不同分支 ❌ 可用条件分支节点近似但不能 LLM 自动分类
4 模板转换节点 template-transform 节点专门做 Jinja2 渲染 ❌ 无独立节点,模板渲染内嵌于各节点
5 参数提取器节点 parameter-extractor 节点用 LLM 从自然语言提取结构化参数 ❌ 无
6 变量聚合器节点 variable-aggregator 节点把多个分支的变量合并 ❌ 由 envelope 自动聚合,无显式节点
7 HTTP Request 节点 独立节点支持任意 HTTP 调用 ❌ 由 SmartAction 节点近似但非通用 HTTP
8 Code 节点(沙箱化代码执行) 独立 dify-sandbox 容器执行 Python / JS 代码 ❌ 不支持任意代码执行
9 Knowledge Index 节点(索引而非检索) core/workflow/nodes/knowledge_index/ 在工作流中增量索引文档 ❌ 知识库索引在管理后台,非工作流节点
10 三种触发器节点(plugin / schedule / webhook) trigger_plugin/trigger_schedule/trigger_webhook/ 支持事件驱动工作流 ❌ 仅同步 API 触发

3.2 HITL 与执行控制

# 特性 Dify 实现 本仓库状态
11 运行中 HITL 暂停-恢复 PauseStatePersistenceLayer 全量序列化(generate_entity + graph_runtime_state + response_stream_filter_state + pause_reasons)+ 恢复重建;两条路径:独立 Human Input 节点 / Agent v2 内部 ask_human 延迟工具调用 ❌ 仅支持运行前一次性收集 userInput
12 Agent 内部 ask_human 延迟工具调用 pydantic-ai external deferred tool,让 Agent 在执行中请求人工输入后继续原上下文 ❌ 不支持
13 子工作流嵌套 _WorkflowChildEngineBuilder 创建隔离的 child GraphEngine,复用父图 variable_pool ❌ 工作流作为工具是外部 API 模式(通过 skill 调用),无内嵌子工作流

3.3 Agent 与 LLM 接入

# 特性 Dify 实现 本仓库状态
14 ReAct(CoT)推理循环 CotAgentRunner 实现 Thought/Action/Observation 文本协议 ⚠️ 通过 Hermes Bridge 间接支持(hermes-agent 内部),但本仓库引擎不直接实现
15 Function Calling 推理循环 FunctionCallAgentRunner 使用 LLM 原生 tool_calls ⚠️ 同上
16 Agent v2 推理循环外包给 pydantic-ai 完全外包给独立 dify-agent-backend 服务 ❌ Agent 在引擎内部执行
17 litellm 统一 LLM 接入 通过 litellm 1.83 收敛 100+ provider ⚠️ 通过 Spring AI + 自定义 AiModelService,覆盖面窄
18 Plugin Daemon 插件化(模型 / 工具 / 节点) 所有 provider 外置为插件,第三方可贡献;28 种向量库 + 8 种 trace 后端 + 10 种对象存储 ❌ 节点/模型/工具硬编码

3.4 多端协同与可观测

# 特性 Dify 实现 本仓库状态
19 画布多人协同编辑 loro-crdt 1.13 + python-socketio 实现工作流画布多人实时协同 ❌ 单人编辑
20 OpenTelemetry 全链路追踪 OTel distro + 五种 instrumentation(celery/flask/httpx/redis/sqlalchemy)+ B3 传播 ❌ 仅节点级 logs,无 OTel
21 8 种 Trace 后端插件化 Langfuse / LangSmith / Phoenix / MLflow / Arize / Opik / Weave / 阿里云 / 腾讯云 ❌ 无 trace 后端集成
22 MCP 客户端/服务端 core/mcp/ 内置 MCP 协议支持(auth / client / server / session) ❌ 未涉及
23 Agent 沙箱化 Shell 工作区(tmux + Landlock) Go 实现的 dify-agent-runtime,通过 tmux 控制持久化 Shell,Landlock LSM 文件系统隔离,sanitize-pty ANSI 清洗 ⚠️ Python monkey-patch 实现路径白名单,无 Landlock 级隔离
24 多语言 i18next(11 种语言) i18next 26 + react-i18next 17 + 11 种语言包 ⚠️ 中文为主,仅 displayName 翻译

3.5 其他生态能力

# 特性 Dify 实现 本仓库状态
25 五种应用形态 Workflow / Chat / AdvancedChat / Completion / AgentChat ⚠️ 仅 Workflow 一种
26 OpenAPI 自动生成(fastopenapi) fastopenapi[flask] 0.7.0 自动生成 OpenAPI 规范 ⚠️ 通过 springdoc 生成(功能等价)
27 结构化 output_type 契约(pydantic-ai) Agent v2 通过 pydantic-ai output_type 强制 JSON Schema 输出契约 ⚠️ envelope 校验类似但基于 declared outputs 字段列表,非完整 JSON Schema
28 多租户与 RBAC core/rbac/ + tenant 隔离 + 套餐优先级(QueueDispatcherManager) ⚠️ 单租户,无套餐优先级
29 Sentry / Amplitude 前端可观测 Sentry 10.66 + Amplitude(含 session-replay) ❌ 未涉及
30 流式工具调用(streaming tool call) FunctionCallAgentRunner.stream_tool_call 支持流式工具调用 ⚠️ 通过 Hermes Bridge SSE 间接支持

4. 实现方法不同的能力

4.1 工作流引擎实现

维度 agent-management Dify
语言 Java 17 + Spring Boot Python 3.12 + Flask + 外部 graphon 包
调度模型 Dataflow(入度计数 pendingInputs: Map<nodeId, AtomicInteger> GraphEngine 线程池(min/max workers + scale up/down threshold)
并发 CompletableFuture + nodeExecutor 线程池 graphon 内部线程池
失败取消 abortFlag(AtomicBoolean)+ inFlightFutures Map,显式 cancel(true) graphon 图级策略(Dify 侧不可见)
文件位置 engine/WorkflowLevelExecutor.java dify/api/core/workflow/workflow_entry.py:213-225

4.2 节点输出信封

维度 agent-management Dify
强制范围 所有节点强制 {status, message, data} 仅 Agent v2 节点 declared outputs 校验,其他节点"尽力推断"
校验器 OutputValidator 统一校验(required / typeMismatch + 静默自动转换) OutputTypeChecker(Agent v2 专用)+ NodeOutputInspectorService(声明输出视图)
失败处理 envelope.isFailure() 自动升级为 NodeExecutionResult.failed Agent v2 通过 OutputFailureOrchestrator 决策 RETRY/USE_DEFAULT/TAKE_FAIL_BRANCH/FAIL
文件位置 engine/NodeOutputEnvelope.javaengine/OutputValidator.java dify/api/core/workflow/nodes/agent_v2/output_failure_orchestrator.py

4.3 失败与重试策略

维度 agent-management Dify
配置层级 引擎层 failStrategy: abort/skip(节点级) + 全局 application.yml retry 配置 + 节点级 retry 覆盖 无统一 failStrategy;Agent v2 节点内部 OutputFailureOrchestrator
重试触发 retryOnParseError / retryOnMissingRequired / retryOnTypeMismatch / retryOnKeyNameMismatch(计划中) 由 OutputFailureOrchestrator 内部决策
重试方式 错误回注 prompt 自我修正;双循环(runtime retry + format retry,计划中) 节点内部 RETRY 决策(重新调用 agent backend)
文件位置 engine/RetryPolicy.javaengine/StructuredOutputHelper.java dify/api/core/workflow/nodes/agent_v2/output_failure_orchestrator.py

4.4 Agent 推理循环

维度 agent-management Dify
老版 Agent AgentExecutor 直接 Spring AI ChatClient(无 ReAct 循环,单次调用) CotAgentRunner(ReAct 文本协议)+ FunctionCallAgentRunner(FC)
新版 Agent HermesAgentExecutor 通过 Hermes Bridge Python 子进程(hermes-agent 内部实现推理循环) Agent v2 通过 dify-agent-backend(pydantic-ai)服务
最大迭代 由 hermes-agent 控制(不在本仓库引擎层) min(max_iteration, 99) + 1
文件位置 engine/executor/HermesAgentExecutor.java dify/api/core/agent/cot_agent_runner.py:80

4.5 结构化输出

维度 agent-management Dify
触发条件 节点 data.outputs 非空即触发(不再要求 size > 1) Agent v2 通过 pydantic-ai output_type 原生支持;其他节点 litellm + json-repair
指令构造 StructuredOutputHelper.buildInstruction(字段名+类型+描述追加 userPrompt) pydantic-ai 内部根据 output_type 自动构造
容错 三级 JSON 提取(直接 / json / 首尾 {} json-repair 0.60 底层修复
文件位置 engine/StructuredOutputHelper.java dify/api/core/workflow/nodes/agent_v2/agent_node.py:393-411

4.6 变量系统与输入解析

维度 agent-management Dify
寻址方式 四级模糊匹配 fallback(精确 / 模糊 / JSON Path 精确 / JSON Path 模糊)+ 显式 mapping variable_pool 直接寻址 + variable_prefixes 前缀解析
工作区 NodeWorkspace(仅含可达前驱输出,反向 BFS) 共享 variable_pool(无显式工作区隔离)
envelope 穿透 五级匹配全部穿透 envelope.data 节点通过 variable selector 显式声明
模板渲染 {{varName}}{{nodeId.varName}}{{nodeId.var.path}};变量不存在保留占位符 Jinja2 + variable_prefixes
文件位置 engine/NodeInputResolver.javaengine/TemplateRenderer.java dify/api/core/workflow/variable_pool_initializer.pydify/api/core/workflow/variable_prefixes.py

4.7 HITL(人工介入)

维度 agent-management Dify
入口 userInput 节点(运行前一次性收集) 独立 Human Input 节点 + Agent v2 ask_human 延迟工具
暂停机制 ❌ 无运行中暂停 PauseRequestedEvent + PauseStatePersistenceLayer 全量序列化
恢复机制 ❌ 无 从 DB 加载 WorkflowResumptionContext,重建 GraphRuntimeState
持久化 ❌ 无 generate_entity + graph_runtime_state + response_stream_filter_state + pause_reasons
文件位置 engine/executor/UserInputExecutor.java dify/api/core/app/layers/pause_state_persist_layer.py:77-177

4.8 沙箱实现

维度 agent-management Dify
语言 Python(hermes-bridge 内) Go(dify-agent-runtime)
隔离机制 三层 monkey-patch(路径白名单 + 相对路径锚定 + Git 根阻断)+ contextvar 线程隔离 Linux Landlock LSM(内核级文件系统隔离)+ tmux(持久化 Shell)+ sanitize-pty(ANSI 清洗)
隔离强度 应用层(依赖 Python 进程内约束) 内核层(依赖 Linux LSM)
状态持久化 工作目录 <data-dir>/workflow-runs/{workflowId}/{runId}/ SQLite(modernc.org/sqlite 纯 Go)记录 job 状态与退出码
文件位置 backend/hermes-bridge/sandbox_patch.py dify/dify-agent-runtime/internal/landlock/dify/dify-agent-runtime/internal/sanitize/

4.9 画布编辑器

维度 agent-management Dify
框架 Vue + vue-flow 风格画布 React + ReactFlow 11.11 + ELK.js(图布局)
协同 ❌ 单人编辑 loro-crdt 1.13 + python-socketio 多人实时协同
自动布局 ❌ 手动 + 节点动态斥力(拖动后推开过近节点) ELK.js 自动布局
字段关联 「引入」双向(input 从前驱 / output 从后继)+ LLM 语义「自动关联」(虚线框发现 Skill 隐式依赖) variable selector 单向引用
文件位置 frontend/src/views/workflow/WorkflowEditor.vuefrontend/src/utils/ioInference.js dify/web/features/workflow/

4.10 模型接入与默认路由

维度 agent-management Dify
接入层 Spring AI ChatClient + 自定义 AiModelService litellm 1.83 统一收敛 100+ provider
默认模型 AiModelService.getDefaultModel 实时查询,application.yml 切换立即生效 节点级硬绑定,无统一默认路由
Provider 管理 模型管理页设置调用顺序 + fallback 通过 plugin_daemon 加载 provider 插件
文件位置 service/AiModelService.java dify/api/core/model_manager.pydify/api/core/provider_manager.py

4.11 持久化与执行历史

维度 agent-management Dify
节点执行历史 WorkflowRunNode.logs(thinking / tool_call / tool_result / info / error) 节点执行记录 + OTel 全链路 trace
上下文快照 NodeExecutionResult.contextSnapshot(计划中,按节点持久化 variables) 共享 variable_pool 状态(无显式 per-node snapshot,但 HITL 时全量序列化)
调用链追踪 节点级 logs API:GET /runs/{runId}/nodes/{nodeId}/logs OTel + 8 种 trace 后端(Langfuse / LangSmith / ...)
文件位置 model/entity/WorkflowRunNode.javadocs/context-passing-architecture.md Phase 2-3 dify/api/core/ops/ops_trace_manager.py

4.12 节点类型扩展机制

维度 agent-management Dify
扩展方式 硬编码 NodeTypeUtils 枚举 + Executor 工厂 plugin_daemon 加载第三方插件(节点 / 模型 / 工具)
节点版本 无显式版本(通过 Executor 类区分 Hermes/非 Hermes) 节点 version() 类方法显式版本(如 Agent v1 vs v2)
动态注册 ❌ 启动时静态注册 ✅ 插件运行时注册
文件位置 engine/NodeTypeUtils.javaengine/executor/*Executor.java dify/api/core/workflow/node_factory.py:279

4.13 国际化

维度 agent-management Dify
范围 中文为主 + displayName 翻译(缓存到 JSON 文件或数据库,全文匹配调出) i18next 26 + 11 种语言包
翻译策略 只翻译 displayName 与正文(含英文的段落即翻译),不翻译 name(避免 kebab-case 被破坏) 完整 i18n 资源包切换
文件位置 prompt.md 880-901 行 dify/web/i18n/dify/web/i18n-config/

4.14 部署架构

维度 agent-management Dify
后端服务数 1(Java 单体) 5(api / worker / worker_beat / plugin_daemon / agent_backend)
沙箱服务数 0(hermes-bridge 内嵌) 2(dify-sandbox 代码沙箱 + dify-agent-local-sandbox Agent Shell)
反向代理 可选(用户自决) Nginx + SSRF Proxy(Squid)必需
必需基础设施 MySQL/PostgreSQL + Redis + 向量库 PostgreSQL/MySQL + Redis + 向量库 + Plugin Daemon + Agent Backend + Local Sandbox + Sandbox + SSRF Proxy + Nginx
文件位置 backend/src/main/resources/application.yml.example dify/docker/docker-compose.yaml

4.15 工作流标识与外部 API

维度 agent-management Dify
工作流标识 kebab-case name(URL 寻址)+ 中文 displayName 分离 UUID
外部调用模式 三段式(创建 → 启动 → 订阅)+ 同步阻塞模式 单次调用(Chat / Completion / Workflow 三类 API)
输入形态 纯 JSON / JSON + 文件 / JSON + 目录(保留结构 + ZIP slip 防护) JSON + 文件(扁平化)
工作空间下载 ZIP 打包(应用 .agentignore drive API 单文件上传/下载
文件位置 docs/external-workflow-api-spec.md dify/api/controllers/service_api/

5. 综合对比表

5.1 能力覆盖矩阵

能力领域 agent-management Dify 备注
DAG 调度 ✅ Dataflow ✅ GraphEngine 实现方式不同(§4.1)
同层并行 ✅ Dataflow 模式 ✅ GraphEngine 线程池 均支持
完成即触发后继 ✅ 显式实现 ⚠️ 推测支持(graphon 内部) 本仓库可观察(§2.1 #3
SKIPPED 状态 ✅ 条件分支未选路径 ❌ 无此状态枚举 本仓库独有(§2.1 #3
统一 envelope ✅ 全节点强制 ⚠️ 仅 Agent v2 本仓库更一致(§2.1 #1
统一 failStrategy ✅ abort/skip ❌ 无统一配置 本仓库独有(§2.1 #2
条件分支 ✅ condition 节点 ✅ if-else 节点 均支持
迭代 ✅ iteration 节点 Dify 独有(§3.1 #1
子工作流 ❌ 内嵌 ✅ child_engine_builder Dify 独有(§3.2 #13
HITL 运行中暂停 ✅ PauseStatePersistenceLayer Dify 独有(§3.2 #11
HTTP / Code 节点 ✅ 独立节点 Dify 独有(§3.1 #7、#8)
触发器(Webhook/Schedule) ✅ 三种触发器 Dify 独有(§3.1 #10
变量模糊匹配 ✅ 四级 fallback ❌ 直接寻址 本仓库独有(§2.2 #6
LLM 结构化输出 ✅ extractWithRetry + 错误回注 ✅ pydantic-ai output_type 实现方式不同(§4.5)
类型静默转换 ⚠️ 严格校验 本仓库更宽容(§2.3 #13
双循环重试 ⚠️ 计划中 本仓库规划中(§2.3 #14
ReAct / FC Agent ⚠️ Hermes Bridge 间接 ✅ 原生实现 Dify 更直接(§3.3 #14、#15)
沙箱 ✅ Python monkey-patch ✅ Go Landlock + tmux 实现方式不同(§4.8)
多人协同画布 ✅ loro-crdt Dify 独有(§3.4 #19
OTel 全链路追踪 ✅ + 8 种后端 Dify 独有(§3.4 #20、#21)
MCP 协议 ✅ 客户端 + 服务端 Dify 独有(§3.4 #22
插件化扩展 ✅ plugin_daemon Dify 独有(§3.3 #18
LLM 错误模式检测 ✅ HermesErrorPattern 本仓库独有(§2.4 #17
LLM 自动关联 ✅ 语义识别 Skill 依赖 本仓库独有(§2.5 #23
模板变量动态识别 ✅ 无碎片 本仓库独有(§2.5 #24
变量导出/导入 ✅ JSON 文件 本仓库独有(§2.5 #27
默认模型实时路由 本仓库独有(§2.4 #19
工作目录 + .agentignore 本仓库独有(§2.2 #10
外部 API 三段式 ⚠️ 单次调用 本仓库更灵活(§4.15)

5.2 设计哲学对比

维度 agent-management Dify
核心目标 企业内部 AI 编码助手(Skill 驱动) 开源 LLMOSS(多形态应用平台)
一致性优先级 高(统一 envelope、统一 failStrategy) 中(各节点分散处理)
扩展性优先级 低(硬编码 8 种节点) 高(插件化,第三方可贡献)
学习曲线 低(节点少,强约束) 高(节点多,配置灵活)
部署复杂度 低(单体 JAR) 高(11 个 docker 服务)
生态丰富度 低(自有生态:Skill / Hermes) 高(28 向量库 / 8 trace / 10 对象存储 / MCP)
多租户
企业可控性 高(私有部署,全链路可见) 中(开源 + 企业版分层)

6. 演进建议

6.1 短期可借鉴(低成本高收益)

借鉴项 来源 价值
HITL 暂停-恢复机制 dify/api/core/app/layers/pause_state_persist_layer.py 让 userInput 节点支持运行中暂停,扩展交互场景
OTel 节点级追踪 dify/api/core/ops/ops_trace_manager.py 提升可观测性,便于性能调优
Langfuse 集成 dify/api/providers/trace/langfuse/ 提供 LLM 调用全链路可视化
断线重连 SSE Dify socket.io 自动重连机制 已有 Last-Event-ID 续传,可进一步参考 socket.io 思路
节点版本机制 Dify Agent v1 vs v2 的 version() 类方法 未来 Hermes/非 Hermes 节点演进时可显式版本化

6.2 中期可考虑(中等成本)

借鉴项 来源 价值
迭代节点 dify/api/core/workflow/nodes/iteration/ 支持数组迭代处理(批量任务场景)
子工作流嵌套 _WorkflowChildEngineBuilder 复用已有工作流作为子流程
HTTP Request 节点 Dify http-request 节点 通用 HTTP 调用,替代 SmartAction 的部分场景
Code 节点(沙箱化) dify-sandbox 容器 支持任意代码执行,扩展工作流能力
触发器节点(Webhook) trigger_webhook 节点 事件驱动工作流,对接外部系统
多租户与 RBAC dify/api/core/rbac/ 企业级权限隔离
MCP 客户端集成 dify/api/core/mcp/ 接入 MCP 生态,复用 MCP 工具

6.3 长期慎选(高成本,需重新定位)

借鉴项 来源 评估
Plugin Daemon 插件化 dify-plugin-daemon(Go) 显著增加架构复杂度,仅当需要第三方扩展生态时考虑
Landlock 沙箱 dify-agent-runtime/internal/landlock/ 需 Linux 内核 5.13+,企业内部场景 monkey-patch 已够用
多人协同画布(loro-crdt) dify/web/features/workflow/ 需引入 CRDT 与 WebSocket,仅当多人协作是核心需求时考虑
多形态应用(Chat / Completion / AgentChat) dify/api/core/app/apps/ 与本仓库 Workflow 单形态定位冲突,需重新评估产品方向
litellm 统一 LLM 接入 dify/api/pyproject.toml Python 库,Java 生态可用 Spring AI 替代
Plugin 化向量库(28 种) dify/api/providers/vdb/ 仅当业务需要多向量库切换时考虑

6.4 应坚持的本仓库特色(不盲目学习 Dify)

特色 价值
统一 envelope 全节点强制 比 Dify"仅 Agent v2 强制"更一致,便于下游消费
统一 failStrategy(abort/skip) 比 Dify"散落各节点"更清晰,运维更可控
Dataflow + SKIPPED 状态机 完成即触发 + 条件分支可视化,比 Dify 的状态枚举更精细
四级模糊匹配 + envelope 穿透 容错性远超 Dify 的"直接寻址",降低用户心智负担
LLM 错误回注 prompt 自我修正 Dify 没有此机制,是结构化输出的关键创新
Hermes Bridge + monkey-patch 沙箱 轻量级、无需多服务,适合企业内部场景
LLM 语义「自动关联」 Dify 完全没有,是 Skill 工作流的独特创新
模板变量动态识别(无碎片) Dify 通过 variable selector 规避,体验不如本仓库
运行对话框变量导出/导入 实测对调试与复现非常有用,Dify 应该学
默认模型实时路由 Dify 节点级硬绑定,本仓库更灵活
外部 API 三段式 + 工作目录下载 比 Dify 单次调用更适合长时间任务场景
kebab-case name + 中文 displayName 分离 比 Dify UUID 更友好,URL 可读性强

附录 A:本仓库工作流特性清单(按维度索引)

详见各设计文档:

  • 节点类型与字段:docs/workflow-node-fields.md
  • 调度引擎计划:docs/workflow-scheduling-engine-plan.md
  • Dataflow 执行计划:docs/workflow-dataflow-execution-plan.md
  • 节点输出信封:docs/workflow-node-output-envelope.md
  • 信封严格校验:docs/workflow-envelope-strict-validation-plan.md
  • 变量作用域:docs/workflow-variable-scope-design.md
  • 上下文传递:docs/context-passing-architecture.md
  • CRUD API:docs/workflow-crud-api.md
  • 外部 API:docs/external-workflow-api-spec.md
  • Hermes 沙箱:docs/hermes-sandbox.md
  • Hermes 错误检测:docs/hermes-error-detection-plan.md

附录 B:Dify 参考索引

详见 docs/dify-readme.md

  • 技术栈:§2
  • 必需依赖:§3
  • 工作流编排调度:§4
  • 多智能体协同探索(澄清:Dify 实际无此探索):§5
  • 目录树说明:§6