# Dify 参考项目说明 > 项目位置:`D:/projects/agent-management/dify`(外部参考仓库,**不参与本仓库构建**) > 版本快照:`1.16.0` > 文档目的:为 agent-management 后续在工作流编排、智能体调度、节点执行信封化等方向的演进提供可借鉴的工程参考。 --- ## 0. 一句话定位 Dify 是一个 **开源 LLMOSS(LLM Operating System / Stack)**,对外提供 Chatbot / Workflow / Agent / Text-Generator / RAG 知识库五类应用形态,底层通过 **Flask API + Celery Worker + Plugin Daemon(Go)+ Agent Backend(Python/pydantic-ai)+ Local Sandbox(Go/Landlock)** 一组协同服务完成大模型应用的编排、执行与扩展。 **与 agent-management 项目的关系**:Dify 是同类问题的"重型开源参考实现"。它在工作流引擎(DAG 调度)、智能体运行时(pydantic-ai)、插件化模型/工具(plugin_daemon)、HITL 暂停-恢复(pause_state_persist_layer)等方面有成熟工程化方案,可作为本仓库工作流改造、Hermes 智能体执行、Skill 文件同步等模块的设计参照。 --- ## 1. 主要做了哪些工作 ### 1.1 应用形态抽象(core/app/apps/) 把 LLM 应用统一抽象为 4 类: - **ChatApp / AdvancedChatApp**:对话型,AdvancedChatApp 走工作流引擎 - **CompletionApp**:一次完成型 - **AgentChatApp**:独立 Agent 应用(非工作流),走 CotAgentRunner / FunctionCallAgentRunner - **WorkflowApp**:基于 DAG 画布的工作流应用 每类应用都有独立的 `AppGenerator` 与 `AppQueueManager`,通过统一的 `task_pipeline` 把事件流推送给前端(SSE / WebSocket / Blocking)。 ### 1.2 工作流引擎(core/workflow/ + services/workflow/) - **构图**:前端 ReactFlow 画布导出 `{nodes, edges}` JSON,由 `WorkflowEntry` 装配 `Graph`(来自外部 `graphon` 包) - **节点系统**:通过 `DifyNodeFactory`(`core/workflow/node_factory.py:279`)按 `type+version` 注册并构造节点实例 - **节点类型**:start、end、llm、knowledge_retrieval、if-else、code、template-transform、question-classifier、http-request、variable-aggregator、parameter-extractor、iteration、agent(v1/v2)、human_input、trigger(plugin/schedule/webhook)、datasource 等 - **调度**:`GraphEngine` 内部线程池(min_workers/max_workers + 弹性伸缩),按"完成即触发后继"方式驱动 DAG - **HITL**:原生 `PauseRequestedEvent` + `PauseStatePersistenceLayer`(`core/app/layers/pause_state_persist_layer.py:77-177`)把图运行时状态、流过滤器状态、暂停原因全量序列化到 DB,恢复时重建 ### 1.3 RAG 知识库(core/rag/) - 完整的"文档 → 切分 → 嵌入 → 入库 → 检索 → 重排 → 引用"链路 - 内置 28 种向量库适配(plugin 化,按需 `uv sync --group vdb-`) - 检索结构:splitter / extractor / index_processor / retrieval / rerank / data_post_processor ### 1.4 智能体能力(双轨实现) | 实现 | 路径 | 推理循环位置 | |---|---|---| | 老版 Agent Chat | `core/agent/cot_agent_runner.py` / `fc_agent_runner.py` | Dify 内部 while 循环 | | 工作流 Agent v1 节点 | `core/workflow/nodes/agent/` | 通过 plugin daemon 外包 | | 工作流 Agent v2 节点 | `core/workflow/nodes/agent_v2/` + `dify-agent` 子项目 | 完全外包给独立 `dify-agent-backend` 服务(基于 pydantic-ai) | ### 1.5 插件化扩展(plugin_daemon + 插件市场) - 所有模型 provider、工具 provider、向量库 provider 都外置为插件 - 由 Go 编写的 `dify-plugin-daemon` 进程加载与执行 - API 通过 HTTP/gRPC 调用插件,所有插件共享一份 daemon 维护的连接与凭据 ### 1.6 沙箱化 Agent 工作区(dify-agent-runtime,Go) - `shellctl` 服务器:通过 tmux 控制持久化 Shell 会话 - `sanitize-pty`:ANSI 控制字符清洗 - `landlock`:Linux LSM 文件系统隔离 - 让 Dify Agent 具备"在受限沙箱里执行 Shell 命令"的能力 ### 1.7 多端协同与可观测 - 前端基于 **loro-crdt** 实现工作流画布的多人协同编辑 - 后端基于 **OpenTelemetry** 全链路埋点(Flask / Celery / httpx / redis / sqlalchemy),可对接 Langfuse / LangSmith / Phoenix / MLflow / Arize / Opik / Weave / 阿里云 SLS / 腾讯云 --- ## 2. 技术栈 ### 2.1 后端 API(`api/`,Python 3.12) | 类别 | 技术 | |---|---| | **运行容器** | gunicorn + gevent + gevent-websocket | | **Web 框架** | Flask 3.1 + flask-restx + flask-login + flask-migrate + flask-orjson + flask-cors + flask-compress | | **OpenAPI** | fastopenapi[flask] 0.7.0 | | **实时** | python-socketio 5.13(工作流多人协同 WebSocket) | | **任务队列** | Celery 5.6(api / worker / worker_beat 三角色) | | **ORM** | SQLAlchemy + Flask-SQLAlchemy(psycopg2-binary / mysql-connector) | | **业务库** | PostgreSQL 15(默认) / MySQL 8(备选),通过 docker-compose profile 切换 | | **缓存/消息** | Redis 6(hiredis),全后端共用 | | **LLM 接入** | **litellm 1.83**(统一收敛) + google-cloud-aiplatform + azure-identity | | **HTTP 客户端** | httpx[socks] 0.28 + httpx-sse 0.4 + sseclient-py | | **JSON 修复** | json-repair 0.60(结构化输出补救) | | **向量库** | 28 种插件化适配(Weaviate / Qdrant / Milvus / pgvector / Chroma / ES / OpenSearch / OceanBase / Oracle / MyScale / ...) | | **对象存储** | 10 种插件化适配(S3 / OSS / COS / BOS / OBS / TOS / Azure Blob / GCS / Supabase / OpenDAL) | | **Trace** | 8 种插件化适配(Langfuse / LangSmith / Phoenix / MLflow / Arize / Opik / Weave / 阿里云 / 腾讯云) | | **可观测** | OpenTelemetry distro + 五种 instrumentation(celery/flask/httpx/redis/sqlalchemy)+ B3 传播 | | **其他** | nltk(分词)/ tiktoken(token 计数)/ gmpy2(大数)/ croniter(定时)/ bleach(HTML 消毒)/ zstandard(压缩) | ### 2.2 新一代 Agent 子项目(`dify-agent/`,Python 3.12) | 类别 | 技术 | |---|---| | **核心 Agent 框架** | **pydantic-ai-slim 1.102**(关键依赖) | | **数据建模** | pydantic 2.12 | | **HTTP** | httpx 0.28 + httpx2 2.5 | | **独立服务模式** | FastAPI 0.136 + uvicorn 0.46 | | **gRPC** | grpclib + protobuf(与 Local Sandbox 通信) | | **可观测** | logfire[fastapi,httpx,redis] | | **加密** | jwcrypto(Agent Stub Bearer Token / JWE) | | **包管理** | uv workspace(被 `api/pyproject.toml` 以 editable 形式引用) | ### 2.3 Agent Runtime 子项目(`dify-agent-runtime/`,Go 1.26) | 类别 | 技术 | |---|---| | **CLI 框架** | spf13/cobra 1.10 | | **沙箱隔离** | landlock-lsm/go-landlock v0.9(Linux LSM) | | **gRPC** | google.golang.org/grpc v1.82 + protobuf v1.36 | | **状态存储** | modernc.org/sqlite v1.37(纯 Go SQLite,无 CGO) | | **产出二进制** | shellctl / shellctl-runner / shellctl-runner-exit / shellctl-sanitize-pty | ### 2.4 前端(`web/`,TypeScript) | 类别 | 技术 | |---|---| | **框架** | Next.js 16 + React 19.2 + React DOM 19.2(App Router / RSC) | | **备选构建** | Vinext 1.0-beta(基于 vite-plus,实验性) | | **构建工具** | @voidzero-dev/vite-plus-core 0.2.5(通过 overrides 替换官方 vite)+ @vitejs/plugin-rsc | | **TypeScript** | typescript 6.0(通过 @typescript/native 走 native 编译器) | | **样式** | Tailwind CSS 4.3 + @tailwindcss/typography | | **状态管理** | Zustand 5 + Jotai 2.20(含 jotai-effect / jotai-scope / jotai-tanstack-query) | | **数据层** | TanStack Query 5.101 + TanStack Form 1.33 + Immer 11 + Zundo 2.3(时间旅行) | | **协同** | loro-crdt 1.13(工作流画布多人协同) | | **画布** | ReactFlow 11.11 + ELK.js 0.11(图布局) | | **富文本/代码** | Lexical 0.47 + Monaco Editor 4.7 | | **可视化** | ECharts 6.1 + Mermaid 11.16 + KaTeX 0.17 + Shiki 4.3 + Streamdown(流式 Markdown) | | **网络/RPC** | oRPC 1.14(类型安全 RPC)+ ky 2.0 + socket.io-client 4.8 + eventsource-parser 3.1 | | **校验** | Zod 4.4 | | **i18n** | i18next 26 + react-i18next 17 | | **可观测** | Sentry 10.66 + Amplitude(含 session-replay) | | **测试** | Vitest 4.1 + Testing Library + Playwright 1.61(+ Cucumber) + Storybook 10.5 | ### 2.5 Monorepo 工作区(`pnpm-workspace.yaml`) `web` + `e2e` + `sdks/nodejs-client` + `packages/*` + `cli`。 其中 `packages/*` 包含 7 个内部包:`@dify/contracts` / `@dify/iconify-collections` / `@dify/tsconfig` / `@langgenius/dev-proxy` / `@langgenius/dify-ui` / `jotai-tanstack-form` / `migrate-no-unchecked-indexed-access`。 --- ## 3. 必需依赖(运行时无法省略) 最小可运行集(源自 `docker/docker-compose.yaml`): | 依赖 | 角色 | 必需性 | |---|---|---| | **PostgreSQL 15** 或 **MySQL 8** | 业务库(dify)+ 插件库(dify_plugin) | 二选一 | | **Redis 6** | Celery broker + 缓存 + 协作通道 | 必需,全后端共用 | | **dify-plugin-daemon**(Go) | 插件加载与执行,所有模型/工具扩展都通过它 | 必需 | | **dify-agent-backend**(dify-agent server) | 新一代 Agent 运行时(pydantic-ai) | Agent v2 节点必需 | | **dify-agent-local-sandbox**(dify-agent-runtime Go) | Agent Shell 工作区,提供 `shellctl` 服务 | Agent shell 能力必需 | | **dify-sandbox** | 代码节点沙箱(独立于 agent-local-sandbox) | 代码节点 / 工具执行必需 | | **ssrf_proxy**(Squid) | 出网安全代理,sandbox 通过它出网 | 默认启用 | | **nginx** | 反向代理统一入口(80/443) | 默认启用 | | **dify-api / worker / worker_beat** | 业务进程,同一镜像三种启动模式 | 必需 | | **dify-web** | Next.js 前端 | 必需 | 向量库(任选其一,默认 **Weaviate**,通过 `VECTOR_STORE` 切换):Qdrant / Milvus(+ etcd + minio)/ pgvector / pgvecto-rs / Chroma / Elasticsearch / OpenSearch / OceanBase / Oracle / MyScale / 等。 可选:**Unstructured**(文档解析,`ETL_TYPE=Unstructured` 时启用)/ **Certbot**(HTTPS 证书)/ **Kibana**(ES profile 下)。 --- ## 4. 工作流编排与调度的具体方法 ### 4.1 整体架构 ``` 前端画布(ReactFlow) │ 导出 graph_config = {nodes, edges} ▼ WorkflowEntry(api/core/workflow/workflow_entry.py) │ ① Graph.init(graph_config, node_factory) 构造 DAG │ ② 装配 GraphEngine(外部 graphon 包) │ ③ 套上 ResponseStreamFilter 维持响应顺序 ▼ GraphEngine(graphon 包内) │ 内部线程池 + 弹性伸缩 │ 按边依赖"完成即触发后继" │ yield GraphEngineEvent ▼ WorkflowAppQueueManager(api/core/app/apps/workflow/app_queue_manager.py) │ q.put(message) ▼ TaskPipeline(api/core/app/task_pipeline/) │ ConvertToSSE / StreamGenerating / Pipeline ▼ 前端 SSE / WebSocket ``` ### 4.2 节点生命周期 每个节点继承 `graphon.nodes.base.node.Node`,实现: 1. `version()` 类方法 → 返回版本字符串(如 Agent v2 返回 `"2"`) 2. `_run()` 异步生成器 → yield 出 `NodeEventBase` 事件 3. `populate_start_event(event)` → 在节点启动事件中附加元数据 4. `_extract_variable_selector_to_variable_mapping()` → 声明消费哪些上游变量(用于 publish 时依赖校验) 事件类型: - `NodeRunResult`:节点执行结果,包含 `status / inputs / outputs / process_data / metadata / error / error_type` - `StreamCompletedEvent`:流结束信号,包装一个 `NodeRunResult` - `PauseRequestedEvent`:HITL 暂停信号,携带 `reason` ### 4.3 关键调度特性 - **基于 DAG**:顶层图严格有向无环,依赖边只能指向前序节点 - **并行执行**:GraphEngine 线程池(min/max workers + scale up/down threshold) - **完成即触发**:节点完成后由 GraphEngine 内部决定后继,不做"同层 barrier 等待"(从测试 `test_parallel_human_input_join_resume.py` 可印证并行 + join) - **子工作流嵌套**:`_WorkflowChildEngineBuilder`(`workflow_entry.py:72-140`)为工具节点创建隔离的 child GraphEngine,复用父图 variable_pool,但用全新的 GraphRuntimeState 与 InMemoryChannel - **顶层图不支持回环**:循环只能通过 Agent 节点内部的 ReAct/FC 迭代实现 ### 4.4 失败与重试 **关键差异**:Dify **没有统一的节点级 `failStrategy` 配置**。失败处理分散在各节点内部: - **Agent v2 节点**:通过 `OutputFailureOrchestrator`(`core/workflow/nodes/agent_v2/output_failure_orchestrator.py`)决策四种动作:`RETRY` / `USE_DEFAULT` / `TAKE_FAIL_BRANCH` / `FAIL`,配合 per-output 的 `OutputTypeChecker` 在每次成功后做类型校验 - **传输层错误**:流式错误/异常终止直接 yield 失败 envelope,不重试 - **节点失败后兄弟节点/后继节点**:完全由 GraphEngine 图级策略决定(在 graphon 包内) > 对照参考:本仓库(agent-management)的 `WorkflowEngine` 把 `failStrategy: abort | skip` 提到引擎层统一处理,对齐所有节点,是比 Dify 更一致的工程改进。 ### 4.5 HITL(人工介入) 两条独立路径: **路径 A:独立 Human Input 节点** - `HumanInputNodeData`(`core/workflow/nodes/human_input/entities.py`)→ 表单定义 - `DifyHITLCallback`(`core/workflow/nodes/human_input/callback.py`)→ 表单生命周期回调 - `HumanInputFormRepositoryImpl` → 表单状态持久化 **路径 B:Agent v2 内部的 ask_human 延迟工具调用** - Agent 在执行过程中通过 `AgentBackendDeferredToolCallInternalEvent` 请求人工输入 - Dify 转换为 `HumanInputRequired` 暂停事件,保存 `pending_form_id` 与 `pending_tool_call_id` 到 `WorkflowAgentRuntimeSessionStore` - 工作流恢复时把表单结果作为 `deferred_tool_results` 注入下一次 Agent backend 调用,让 Agent 在原上下文继续 **持久化层**:`PauseStatePersistenceLayer`(`core/app/layers/pause_state_persist_layer.py:77-177`)在收到 `GraphRunPausedEvent` 时序列化:`generate_entity` + `serialized_graph_runtime_state` + `serialized_response_stream_filter_state` + `pause_reasons`,恢复时全量重建。 ### 4.6 流式输出 `GraphEngine` 是一个生成器,产出 `GraphEngineEvent` 流。Dify 通过 `iter_dify_graph_engine_events`(`workflow_entry.py:49-69`)在原始事件流上套 `ResponseStreamFilter`,以维持"按响应顺序输出"的历史语义(兼容 graphon v0.5.0+ 的变量流分块)。最终经 `TaskPipeline` 转换为 SSE / WebSocket 推给前端。 ### 4.7 任务队列与多租户 - `WorkflowAppQueueManager`(`core/app/apps/workflow/app_queue_manager.py:24-44`):单工作流执行内的事件队列 - `QueueDispatcherManager`(`services/workflow/queue_dispatcher.py:72-111`):按租户套餐分配优先级,跨租户隔离 ### 4.8 节点类型清单 | 类别 | 节点 | |---|---| | **入口/出口** | start、end、datasource | | **控制流** | if-else、iteration、variable-aggregator、parameter-extractor | | **生成式** | llm、question-classifier、template-transform | | **执行式** | code、http-request | | **知识增强** | knowledge_retrieval、knowledge_index | | **智能体** | agent(v1 插件化)、agent_v2(dify-agent 后端) | | **人工介入** | human_input | | **触发器** | trigger_plugin、trigger_schedule、trigger_webhook | --- ## 5. 多智能体协同方面的探索 ### 5.1 重要结论(必须澄清) **经过完整探索,Dify 项目在"智能调度而非强依赖 DAG"方面没有任何探索。** 所有调度路径都基于强依赖的 DAG,不存在 LLM 决定执行顺序、动态路由、Agent 调度 Agent 的原生模式。 用户在需求描述中提到的"智能调度而非强依赖 DAG",更准确的对应物应该是本仓库(agent-management)`backend/src/main/java/com/agent/management/engine/WorkflowEngine.java` 等近期改造(参见 commit `1e166dd`"节点完成后立即触发后继节点,不再被同层慢节点阻塞"等),而不是 Dify 自身。 下面如实说明 Dify 实际的设计形态。 ### 5.2 工作流顶层:严格 DAG 由外部 `graphon` 包的 `GraphEngine` 按边依赖调度,无回环、无动态跳转。 ### 5.3 Agent 节点内部:固定循环 - **CotAgentRunner**(`api/core/agent/cot_agent_runner.py:106-266`):固定 while 循环,每次重新组织 prompt(含历史 + scratchpad + 工具描述),通过 ReAct 协议(`Thought/Action/Observation`)解析,最大迭代 `min(max_iteration, 99) + 1` - **FunctionCallAgentRunner**(`api/core/agent/fc_agent_runner.py:81-330`):固定 while 循环,使用 LLM 原生 tool_calls - **Agent v2**(`api/core/workflow/nodes/agent_v2/`):把推理循环外包给 `dify-agent-backend` 服务的 pydantic-ai `Agent.run()` 三种实现的"决策"都体现在 **tool calling**(调用哪个工具、何时输出最终答案),但工具是预先注册的函数集合,不是图节点,**工具调用 ≠ 图路由**。 ### 5.4 agenton Compositor:单 Agent 的层组合(不是多 Agent 协同) `dify-agent/src/agenton/compositor/` 是一个 **框架中立的层图(layer graph)组合器**,常被误以为是"多智能体协同",实际定位如下: | 设计点 | 实际情况 | |---|---| | 目的 | 把**单个 Agent 一次 LLM 调用**所需的 system prompt / user prompt / tools / output contract 分模块组合 | | 节点(LayerNode) | 无状态,声明 `name / provider / deps` | | 边(deps) | 严格约束为"只能指向前序节点"(`compositor/core.py:257-289`),形成 DAG | | 执行顺序 | 在 `CompositorConfig.layers` 中静态声明,**运行时不可变** | | 进入/退出 | 按 slots 顺序进入(`run.py:127-145`),反向退出 | | 聚合输出 | prompts/user_prompts/tools 通过 `CompositorRun` properties 线性聚合(`run.py:247-278`),扁平化为两个列表喂给单个 pydantic-ai Agent | | 是否支持分支/并行/路由 | **全部不支持** | | 与 pydantic-ai 关系 | 嵌套:`Compositor.enter()` 外层准备资源 → 内层 `Agent.run()` 跑标准推理循环 | **已有的 Layer 类型**(`dify-agent/src/dify_agent/layers/`): - `ask_human/`:人工输入延迟工具(pydantic-ai external deferred tool) - `dify_plugin/`:Dify 插件(LLM 与工具) - `dify_core_tools/`:Dify 核心工具 - `knowledge/`:知识库检索工具 - `output/`:结构化输出契约(提供 pydantic-ai 的 `output_type`) - `shell/`:Shell 命令执行(4 个工具:run/wait/input/interrupt) - `drive/`、`execution_context/`、`config/`:辅助层 这些 Layer **不直接协作**,各自通过 properties 暴露 prompt/tool,最终被 `dify_agent/runtime/runner.py:321-374` 聚合后**喂给同一个 pydantic-ai Agent**。 ### 5.5 Session Snapshot:单 Agent 的断点续传 `CompositorSessionSnapshot`(`compositor/schemas.py:78-115`)让**同一个 agent session 跨多次 agent run 续接**,典型场景: ``` workflow run → agent run #1(执行到一半遇到 ask_human)→ snapshot 持久化 ↓ workflow 暂停(HITL) ↓ 人提交答案 workflow 恢复 → agent run #2(从 snapshot 复用原状态继续) ``` 这是**单 Agent 的状态持久化**,不是多 Agent 间的协同。文档原话(`dify-agent/docs/dify-agent/concepts/run-lifecycle/index.md:7-11`): > "A `workflow run` is one full workflow execution. An `agent run` is one Agent execution started by an Agent node while the workflow is running. They are not a one-to-one mapping: one `workflow run` often contains multiple `agent run`s." **多 Agent 协同是 Dify 外部 workflow 引擎的职责**,dify-agent 只是被工作流调用的执行单元,自身不做编排。 ### 5.6 没有 SubAgent / Supervisor / Handoff 抽象 对整个 `dify-agent/` 仓库做了如下针对性搜索,全部零命中: - `multi.?agent|sub.?agent|subagent|spawn|handoff|delegate|orchestrat|supervisor|manager.?agent` → 命中只在 docstring 字面词或无关语义 - `LLM.*(decide|choose|route|select).*(order|layer|next)|dynamic.*(execution|graph|dag)|model.?decides` → **零匹配** `Compositor` 的默认 provider 集合(`dify-agent/src/dify_agent/runtime/compositor_factory.py:77-128`)也不包含任何 `SubAgentLayer` / `RouterLayer` / `SupervisorLayer`。 ### 5.7 对本仓库的启示 | Dify 的局限 | 本仓库可能的演进方向 | |---|---| | 工作流顶层不支持回环 | 引入 Agent 自主路由(让 LLM 决定下一个激活的后继节点)需要扩展 GraphEngine 调度策略 | | 无 multi-agent 原生模式 | 把 Agent 节点的 tool calling 扩展为"子图调用"(需扩展 child_engine_builder)或引入"agent 作为另一个 agent 的工具"的语义层 | | 无统一 failStrategy | 本仓库已做到(`failStrategy: abort | skip` 在引擎层统一处理) | | Envelope 校验仅对 Agent v2 强制 | 本仓库已做到(所有节点统一 `{status, message, data}` envelope) | | 分支未选路径状态不清晰 | 本仓库已做到(commit `1e166dd` 提到自动标记 SKIPPED) | --- ## 6. 目录树说明(顶层 + 主要子目录) ### 6.1 顶层目录 ``` dify/ ├── api/ # Python 后端(主仓库核心,Flask + Celery) ├── dify-agent/ # Python 新一代 Agent 框架(pydantic-ai + agenton) ├── dify-agent-runtime/ # Go 实现的 Agent Shell 沙箱运行时(shellctl + landlock) ├── web/ # Next.js + React 19 前端(控制台 + Web App) ├── packages/ # pnpm workspace 内部包(contracts / dify-ui / dev-proxy 等 7 个) ├── sdks/ # 官方 SDK(nodejs-client / php-client) ├── cli/ # Dify CLI(TypeScript,独立 npm 包) ├── docker/ # docker-compose 编排(含 28 种向量库的 profile 模板) ├── dev/ # 本地开发脚本(start-api / start-web / start-worker / start-beat) ├── scripts/ # 仓库治理脚本(lint / ast-grep 规则 / 压测) ├── e2e/ # E2E 测试(Playwright + Cucumber) ├── docs/ # 产品/概念文档(多语言 + design + weaviate 子目录) ├── images/ # 仓库用图 ├── README.md / SECURITY.md / LICENSE / CONTRIBUTING.md / AUTHORS ├── Makefile # 顶层构建/测试入口 ├── package.json / pnpm-workspace.yaml / pnpm-lock.yaml # 前端 monorepo 元数据 ├── vite.config.ts / eslint.config.mjs / lint.config.ts / oxlint-suppressions.json ├── codecov.yml / depot.json ├── CLAUDE.md / AGENTS.md # AI 协作指引 ``` ### 6.2 `api/`(Python 后端) ``` api/ ├── app.py / app_factory.py / dify_app.py / gunicorn.conf.py # 入口与 WSGI 配置 ├── celery_entrypoint.py / celery_healthcheck.py # Celery worker/beat 入口 ├── pyproject.toml / pytest.ini / conftest.py # 依赖与测试配置 ├── Dockerfile # 主镜像 ├── controllers/ # HTTP 控制器层(console / service_api / openapi / inner_api / web / mcp / trigger / files / common) ├── services/ # 业务服务层(account / agent / app / dataset / workflow / ...) │ └── workflow/ # 工作流编排服务(scheduler / queue_dispatcher / workflow_converter / node_output_inspector_service) ├── core/ # 核心业务逻辑(详见 6.3) ├── models/ # SQLAlchemy ORM 实体(account / agent / dataset / workflow / ...) ├── repositories/ # 仓储层(封装复杂查询) ├── migrations/ # Alembic 数据库迁移 ├── extensions/ # Flask 扩展注册(ext_database / ext_celery / ext_redis / ext_logging / ...) ├── configs/ # 分层配置(app_config / feature / enterprise / packaging / observability / middleware / deploy / remote_settings_sources) ├── events/ # 领域事件与事件处理器(app / dataset / document / message / tenant) ├── contexts/ / context/ # 请求/应用级上下文(execution_context / flask_app_context / models) ├── factories/ # 工厂类 ├── fields/ # flask-restx 字段定义 ├── enums/ # 枚举类型 ├── constants/ # 常量 ├── errors/ # 错误与异常 ├── commands/ # CLI 命令(account / data_migrate / plugin / rbac / retention / storage / system / vector) ├── schedule/ # Celery Beat 定时任务(clean_embedding / clean_messages / clean_workflow_runs / queue_monitor / workflow_schedule / ...) ├── libs/ # 公共工具库(archive_storage / datetime_utils / encryption / exception / file_utils / infinite_scroll_pagination / json_in_md_parser / ...) ├── clients/ # 外部客户端 ├── providers/ # 插件化的 provider 适配(vdb/ 向量库,trace/ 可观测) ├── enterprise/ # 企业版专有代码(telemetry/) ├── openapi/ # OpenAPI 规范文件 ├── docker/ # 容器内辅助脚本 └── dev/ # 本地开发辅助 ``` ### 6.3 `api/core/`(核心业务逻辑) ``` core/ ├── workflow/ # 工作流引擎(顶层入口) │ ├── workflow_entry.py # WorkflowEntry:装配 Graph + GraphEngine + 过滤器(核心文件) │ ├── graph_topology.py # WorkflowGraphTopology:邻接表与上游集合(仅用于校验,非运行时调度) │ ├── node_factory.py # DifyNodeFactory:节点注册与构造 │ ├── node_runtime.py # 节点运行时辅助(变量池、HITL 表单仓储) │ ├── human_input_*.py # HITL 适配器、表单、策略 │ ├── system_variables.py # 系统级变量定义 │ ├── variable_pool_initializer.py # 共享变量池初始化 │ ├── variable_prefixes.py # 变量前缀解析 │ ├── template_rendering.py # Jinja2 模板渲染 │ ├── file_reference.py # 文件引用处理 │ ├── snippet_start.py # snippet 节点辅助 │ ├── workflow_run_outputs.py # 运行输出聚合 │ ├── generator/ # LLM 辅助生成工作流(planner/builder prompts) │ └── nodes/ # 各类节点实现 │ ├── agent/ # Agent v1 节点(plugin 化策略) │ ├── agent_v2/ # Agent v2 节点(调用 dify-agent-backend) │ ├── datasource/ # 数据源节点 │ ├── human_input/ # 人工输入节点(表单 + 回调) │ ├── knowledge_index/ # 知识库索引节点 │ ├── knowledge_retrieval/ # 知识库检索节点 │ ├── trigger_plugin/ # 插件触发器节点 │ ├── trigger_schedule/ # 定时触发器节点 │ └── trigger_webhook/ # Webhook 触发器节点 ├── app/ # 应用抽象层 │ ├── apps/ # 4 类应用(advanced_chat / agent_app / agent_chat / chat / completion / workflow) │ ├── app_config/ # 应用配置(ChatAppConfig / CompletionAppConfig / WorkflowAppConfig / AgentAppConfig) │ ├── entities/ # 应用实体 │ ├── features/ # 应用功能(dialog / file_upload / moderation / suggested_questions / ...) │ ├── file_access/ # 文件访问 │ ├── layers/ # 应用层(pause_state_persist_layer / observability_layer / ...) │ ├── llm/ # LLM 调用辅助 │ ├── task_pipeline/ # 任务管道(SSE / 流生成 / Pipeline) │ ├── workflow/ # 工作流应用层(file_runtime / retry_history / layers) │ ├── base_app_generator.py / base_app_runner.py / base_app_queue_manager.py │ ├── message_generator.py / streaming_utils.py │ └── draft_variable_saver.py ├── agent/ # 独立 Agent Chat App 的 Runner(非工作流节点) │ ├── base_agent_runner.py # 基类 │ ├── cot_agent_runner.py # ReAct 推理循环 │ ├── cot_chat_agent_runner.py # Chat 模型 ReAct │ ├── cot_completion_agent_runner.py # Completion 模型 ReAct │ ├── fc_agent_runner.py # Function Calling 推理循环 │ ├── output_parser/ # ReAct 输出解析 │ ├── strategy/ # 策略(含 plugin 化的 PluginAgentStrategy) │ ├── prompt/ # Agent prompt 模板 │ └── entities.py / errors.py / plugin_entities.py ├── rag/ # RAG 知识库引擎(splitter / extractor / embedding / pipeline / retrieval / rerank / docstore / ...) ├── tools/ # 工具系统 │ ├── __base__/ # 工具基类 │ ├── builtin_tool/ # 内置工具 │ ├── custom_tool/ # 自定义工具(OpenAPI schema) │ ├── plugin_tool/ # 插件工具 │ ├── mcp_tool/ # MCP 工具 │ ├── workflow_as_tool/ # 工作流作为工具(关键:child engine builder 的对端) │ ├── tool_engine.py / tool_manager.py / tool_file_manager.py / tool_label_manager.py │ └── utils/ ├── memory/ # 会话记忆(token_buffer_memory) ├── file/ # 文件(remote_fetcher) ├── model_manager.py / provider_manager.py # 模型/Provider 管理器 ├── datasource/ # 数据源抽象 ├── db/ # 数据库辅助 ├── rbac/ # RBAC 实体 ├── mcp/ # MCP 客户端与服务端(auth / client / server / session) ├── plugin/ # 插件系统( backwards_invocation / endpoint / entities / impl / plugin_service / utils) ├── trigger/ # 触发器管理(constants / entities / provider / trigger_manager / utils / debug) ├── ops/ # 可观测(ops_trace_manager / entities / utils) ├── prompt/ # Prompt 工具 ├── moderation/ # 内容审核 ├── external_data_tool/ # 外部数据工具 ├── llm_generator/ # LLM 生成器(用于辅助生成提示词/工作流) ├── indexing_runner.py # 知识库索引执行器 ├── callback_handler/ # 回调处理 ├── helper/ # 辅助函数 ├── extension/ # 核心扩展点 ├── entities/ / schemas/ # 实体与 Schema ├── errors/ # 错误定义 ├── logging/ # 日志 ├── telemetry/ # 遥测 ├── repositories/ # 核心层仓储 ├── hosting_configuration.py # 多租户 hosting 配置 └── base/ # 基础抽象 ``` ### 6.4 `dify-agent/`(新一代 Agent 框架,Python) ``` dify-agent/ ├── pyproject.toml # uv workspace 元数据(含 grpc / server 可选依赖组) ├── README.md / Makefile / mkdocs.yml ├── Dockerfile # 独立 agent_backend 镜像 ├── docs/ # 概念文档(concepts/run-lifecycle / ...) ├── examples/ # 使用示例 ├── proto/ # gRPC proto(与 Local Sandbox 对齐) ├── tests/ # 单元测试 └── src/ ├── agenton/ # 框架中立的层图(layer graph)组合器 │ ├── compositor/ # Compositor + CompositorRun + schemas │ │ ├── core.py # Compositor / LayerNode(无状态 DAG 计划) │ │ ├── run.py # CompositorRun(一次活动运行时 + 资源作用域) │ │ ├── providers.py # LayerProvider(工厂) │ │ ├── schemas.py # 可序列化 DTO(CompositorSessionSnapshot) │ │ └── types.py # 泛型类型变量 │ ├── layers/ # Layer 抽象基类 │ │ ├── base.py # Layer / LayerDeps / LayerConfig / LifecycleState │ │ └── types.py # PlainLayer / PydanticAILayer 类型族 │ └── __init__.py # 门面(自述 state-only core) ├── agenton_collections/ # 可复用 Layer 与 Transformer 实现 │ ├── layers/ │ │ ├── plain/ # 普通字符串 prompt/tool 层 │ │ └── pydantic_ai/ # pydantic-ai 桥接(history 等) │ └── transformers/ # 类型转换器(PYDANTIC_AI_TRANSFORMERS) │ └── pydantic_ai.py ├── dify_agent/ # Dify 业务运行时(FastAPI server) │ ├── runtime/ # 运行时入口 │ │ ├── runner.py # AgentRunRunner:组合 compositor + pydantic-ai │ │ ├── agent_factory.py # create_agent(一行:Agent(model, output_type, tools)) │ │ ├── compositor_factory.py # 默认 provider 集合 │ │ ├── run_scheduler.py # 调度(无 Redis job queue,进程内) │ │ └── output_contract.py # 输出契约解析 │ ├── layers/ # Dify 业务 Layer(详见 5.4) │ │ ├── ask_human/ # 人工输入延迟工具 │ │ ├── config/ # 配置层 │ │ ├── dify_core_tools/ # Dify 核心工具层 │ │ ├── dify_plugin/ # Dify 插件层(LLM 与工具) │ │ ├── drive/ # 文件 Drive 层 │ │ ├── execution_context/ # 执行上下文层 │ │ ├── knowledge/ # 知识库检索层 │ │ ├── output/ # 结构化输出契约层(output_type) │ │ └── shell/ # Shell 命令执行层(4 个工具) │ ├── adapters/ # Shell / LLM 适配器 │ ├── agent_stub/ # gRPC Stub 协议、文件上传下载(drive) │ ├── client/ # 与 Dify API 对接的客户端 │ ├── protocol/ # 公开协议(DTO) │ ├── server/ # FastAPI server 路由与生命周期 │ ├── storage/ # 存储适配(snapshot 落盘) │ └── plugin_daemon_transport.py # 与 plugin_daemon 通信 └── shellctl/ # Python 版 shellctl 客户端(与 Go 版 dify-agent-runtime 对端) ├── client/ └── shared/ ``` ### 6.5 `dify-agent-runtime/`(Agent Shell 沙箱,Go) ``` dify-agent-runtime/ ├── go.mod / go.sum # Go 1.26 ├── Makefile / README.md ├── packaging_test.go # 打包测试 ├── cmd/ # CLI 入口(cobra) │ ├── shellctl/ # 主服务(serve --listen 0.0.0.0:5004) │ ├── dify-agent-cli/ # Agent CLI(在沙箱内调用) │ ├── runner/ # 集成 Landlock 的 job runner │ ├── runner-exit/ # 退出状态写 SQLite │ └── sanitize-pty/ # tmux pipe-pane PTY 过滤器 ├── internal/ # 内部实现 │ ├── server/ # shellctl HTTP/gRPC 服务 │ ├── agentcli/ # Agent CLI 实现 │ ├── landlock/ # Linux Landlock LSM 隔离封装 │ ├── sanitize/ # PTY ANSI 清洗 │ ├── runner_exit/ # 退出码处理 │ ├── cmdutil/ # 命令工具 │ ├── envvar/ # 环境变量 │ └── stubclient/ # 与 dify-agent gRPC Stub 通信 ├── gen/ # 由 proto 生成的 Go 代码(gen/dify/agent/stub/v1/) ├── docker/ # 容器构建辅助 └── tests/ # 测试 ``` ### 6.6 `web/`(前端,Next.js + React 19) ``` web/ ├── package.json / Dockerfile / next.config.mjs / vite.config.ts / tsconfig.json ├── app/ # Next.js App Router 路由 ├── features/ # 功能模块(按业务领域划分) ├── components/ # 共享组件(隐含,按 features 内组织) ├── hooks/ # 自定义 Hook ├── context/ # React Context ├── models/ # 前端类型定义 ├── constants/ # 常量 ├── assets/ / icons/ # 静态资源 ├── i18n/ / i18n-config/ # 国际化(i18next) ├── config/ # 前端配置 ├── bin/ # 入口脚本 ├── docs/ # 前端文档 ├── docker/ # 容器构建 ├── __mocks__ / __tests__ # Mock 与测试 ├── next/ # Next.js 特定代码 ├── global.d.ts / env.ts / instrumentation-client.ts ├── dev-proxy.config.ts # 开发代理 └── knip.config.ts # 死代码检测配置 ``` ### 6.7 `docker/`(部署编排) ``` docker/ ├── docker-compose.yaml # 自动生成的最终编排 ├── docker-compose-template.yaml # 手维护的模板(源头) ├── docker-compose.middleware.yaml # 仅中间件(DB / Redis)的精简版 ├── docker-compose.pytest.ports.yaml # 测试用端口编排 ├── generate_docker_compose # 从 template + envs 生成最终 yaml 的脚本 ├── dify-env-sync.py / dify-env-sync.sh # 环境变量同步 ├── envs/ # 按 profile 拆分的环境变量(向量库 / 业务库) ├── volumes/ # 持久化卷挂载点 ├── nginx/ # Nginx 反向代理配置 ├── ssrf_proxy/ # Squid SSRF 代理配置 ├── certbot/ # HTTPS 证书 ├── startupscripts/ # 容器启动脚本 ├── elasticsearch/ / pgvector/ / couchbase-server/ / iris/ / tidb/ # 各向量库的辅助配置 └── README.md ``` ### 6.8 `packages/`(pnpm workspace 内部包) ``` packages/ ├── contracts/ # @dify/contracts:前后端共享的类型契约 ├── dify-ui/ # @langgenius/dify-ui:可复用 UI 组件库 ├── dev-proxy/ # @langgenius/dev-proxy:本地开发代理 ├── iconify-collections/ # @dify/iconify-collections:图标集合 ├── tsconfig/ # @dify/tsconfig:共享 tsconfig ├── jotai-tanstack-form/ # jotai 与 TanStack Form 的桥接包 └── migrate-no-unchecked-indexed-access/ # 迁移工具包 ``` ### 6.9 `sdks/`(官方 SDK) ``` sdks/ ├── nodejs-client/ # Node.js 客户端 SDK(TypeScript) ├── php-client/ # PHP 客户端 SDK └── README.md ``` ### 6.10 `cli/`(Dify CLI) ``` cli/ ├── package.json / tsconfig.json / vite.config.ts ├── bin/ # CLI 入口(dify-cli) ├── src/ # CLI 命令实现 ├── scripts/ # 辅助脚本 ├── test/ # 测试 ├── AGENTS.md / ARD.md # 架构决策记录 └── README.md ``` ### 6.11 `dev/`(本地开发脚本) ``` dev/ ├── setup* # 一键拉起开发环境 ├── start-api* # 启动 Flask API ├── start-web* # 启动 Next.js 前端 ├── start-worker* # 启动 Celery Worker ├── start-beat* # 启动 Celery Beat ├── start-docker-compose* # 启动 docker-compose ├── sync-uv* # 同步 uv workspace 依赖 ├── reformat* # 代码格式化 ├── ty-check* # 类型检查(pyrefly) └── pyrefly-check-local* ``` ### 6.12 `e2e/`(端到端测试) ``` e2e/ ├── package.json / cucumber.config.ts ├── features/ # Cucumber 特性文件 ├── fixtures/ # 测试夹具 ├── support/ # 测试支持代码 ├── scripts/ # 辅助脚本 ├── tests/ # 测试实现 ├── test-env.ts # 测试环境配置 ├── AGENTS.md / README.md ``` ### 6.13 `scripts/`(仓库治理) ``` scripts/ ├── ast_grep_guard.py / ast_grep_rules/ # AST 检查规则 ├── check_no_new_controller_sqlalchemy.py # 禁止在 controller 直接用 SQLAlchemy ├── check_no_new_getattr.py # 禁止新增 getattr 调用 ├── lint_controller_sqlalchemy.py # 检查 controller 层 SQL 渗漏 └── stress-test/ # 压测脚本 ``` ### 6.14 `docs/`(产品文档) ``` docs/ ├── design/ # 设计文档(架构 / 决策) ├── zh-CN/ zh-TW/ en-US/ # 多语言文档(中文简/繁、英文) ├── ja-JP/ ko-KR/ fr-FR/ ...# 其他语言 ├── cross-env-app-migration/ # 跨环境应用迁移指南 ├── weaviate/ # Weaviate 专题 ├── eu-ai-act-compliance.md # 欧盟 AI Act 合规 └── tlh/ # 克林贡语(彩蛋) ``` --- ## 7. 对本仓库(agent-management)的关键借鉴清单 | 借鉴维度 | Dify 实现位置 | 对应本仓库模块 | |---|---|---| | 工作流信封化 | `services/workflow/node_output_inspector_service.py`(仅 Agent v2) | `engine/NodeOutputEnvelope`(已全节点统一) | | 节点级失败策略 | `core/workflow/nodes/agent_v2/output_failure_orchestrator.py`(仅 Agent v2) | `engine/RetryPolicy` + `failStrategy`(已引擎层统一) | | HITL 暂停-恢复 | `core/app/layers/pause_state_persist_layer.py` | 可参考其状态序列化设计 | | 子工作流嵌套 | `core/workflow/workflow_entry.py:72-140`(`_WorkflowChildEngineBuilder`) | 未来扩展"工作流作为工具"时可参考 | | 插件化模型/工具 | `dify-plugin-daemon`(Go)+ `core/plugin/` | Hermes Bridge 设计可对照 | | 沙箱化 Shell 执行 | `dify-agent-runtime/internal/landlock/` + `shellctl` | `docs/hermes-sandbox.md` 可对照 | | 多人协同画布 | loro-crdt + socket.io | 前端 ReactFlow 改造时可参考 | | 可观测全链路 | OpenTelemetry + 8 种 trace 后端 | 未来接入 Langfuse 可参考 `api/providers/trace/` | --- ## 附录:探索方法说明 本文档基于以下方式收集信息: 1. 直接阅读 `pyproject.toml` / `go.mod` / `package.json` / `docker-compose.yaml` 提取技术栈与依赖 2. 直接阅读核心源码文件(`workflow_entry.py`、`agent_node.py`、`cot_agent_runner.py`、`compositor/core.py`、`runtime/runner.py` 等)提取调度与执行细节 3. 对 `dify-agent/` 全仓库做针对性关键字搜索(`multi.?agent` / `dynamic.*graph` / `LLM.*(decide|route)` 等),结论为"零命中"以支撑第 5 章判断 4. 阅读官方概念文档(`dify-agent/docs/dify-agent/concepts/run-lifecycle/index.md` 等)确认设计意图 文档中所有"file_path:line_number"引用均可直接定位到对应源码位置,便于深入查阅。