Skip to content

系统整体架构

本章目标:

  1. 认识 DeerFlow 2.0 的四大运行组件 —— Nginx(2026)、Frontend(3000)、Gateway(8001)、Provisioner(8002),以及它们的端口与职责。
  2. 理解后端 harness/app 双层分工:deerflow.* 是可发布的 agent 框架,app.* 是 Gateway/channels 应用层,依赖方向单向。
  3. 跟踪一次浏览器请求如何经 Nginx 反向代理流入 Gateway,再经 RunManager + StreamBridge 驱动 LangGraph agent runtime 并以 SSE 流式返回。

TL;DR

DeerFlow 2.0 是一个基于 LangGraph 的 super agent harness,部署形态为四个容器:Nginx 做统一入口反向代理,Frontend 跑 Next.js 界面,Gateway 是 FastAPI 应用并内嵌 agent runtime,Provisioner 在 Kubernetes 沙箱模式下按需创建沙箱 Pod。后端代码按 harness(deerflow.*,框架)与 app(app.*,Gateway 与 IM channels)严格分层,app 可依赖 deerflow 但反向被 CI 禁止。所有对话请求通过 /api/langgraph/* 进入 Gateway,由 RunManager 登记运行、run_agent() 在后台 task 中驱动 make_lead_agent 构建的 LangGraph 图、StreamBridge 把事件解耦地推给 SSE 端点。这张组件—分层—请求流的地图贯穿全 wiki 后续各章。

Overview

DeerFlow 没有把 agent runtime 做成独立的 LangGraph Platform 服务,而是把它内嵌进 Gateway 进程。这样做的动机是简化部署与状态共享:make dev、Docker dev、生产三种模式都用同一套 RunManager + run_agent() + StreamBridge,无需额外维护一个 LangGraph Server 进程。Nginx 把对外的 /api/langgraph/* 路径重写成 Gateway 原生的 /api/* 路由,让前端的 useStream Hook 以为自己在和标准 LangGraph Platform 对话 docker/nginx/nginx.conf:43-44

后端的 harness/app 分层是为了让 agent 框架可独立发布(deerflow-harness 包,见 backend/packages/harness/pyproject.toml:1-3),同时让 FastAPI/IM 应用层依赖它而不污染它。langgraph.json 把图入口直接指向 harness 内的工厂函数 deerflow.agents:make_lead_agent,checkpointer 也指向 harness 模块,只有 auth 钩子落在 app 层 backend/langgraph.json:8-16

Architecture

四个组件在 docker-compose 中各为一个 service,通过 deer-flow bridge 网络互通,只有 Nginx 对宿主暴露端口。

组件端口角色Source
Nginx2026(可由 PORT 覆盖)统一反向代理,路径路由,SSE/分块透传docker/docker-compose.yaml:27-42
Frontend3000Next.js 生产服务,通过 gateway:8001 内部地址访问后端docker/docker-compose.yaml:45-61
Gateway8001FastAPI + uvicorn 多 worker,内嵌 agent runtimedocker/docker-compose.yaml:63-74
Provisioner8002K8s 沙箱模式下创建/销毁沙箱 Pod,带健康检查docker/docker-compose.yaml:117-146

后端进程内部分两层,依赖方向单向(app → deerflow,反向被 CI test_harness_boundary.py 拦截):

Components / Subsystems

Nginx —— 统一入口反向代理(:2026)

职责:单一对外端口,按路径把请求分流到 Gateway 或 Frontend,并保证 SSE/流式不被缓冲。

关键点:

Frontend —— Next.js 界面(:3000)

职责:提供 Web 聊天界面。容器内通过 DEER_FLOW_INTERNAL_GATEWAY_BASE_URL=http://gateway:8001 直连后端,默认经 Nginx 同源访问。

关键点:BETTER_AUTH_SECRET 为前端会话安全必需项,由 compose 注入 docker/docker-compose.yaml:54-56。前端技术栈细节见第 28 章。

Gateway —— FastAPI 应用 + 内嵌 runtime(:8001)

职责:对外提供 REST API(models/mcp/skills/uploads/threads/runs 等)与 LangGraph 兼容的运行生命周期,并在同一进程内驱动 agent。

关键文件 / 关键点:

  • create_app() 注册全部 router,并按顺序挂载 AuthMiddleware(失败关闭式鉴权兜底)→ CSRFMiddleware → 可选 CORSMiddleware backend/app/gateway/app.py:214-324
  • lifespan 启动时先加载 AppConfig,再用 langgraph_runtime(app) 上下文初始化全部 runtime 单例,然后做 admin 引导与 IM channel 启动 backend/app/gateway/app.py:160-211
  • langgraph_runtime()AsyncExitStack 依次构建 StreamBridge、持久化引擎、checkpointer、store、各 Repository、RunManager(store=...),挂到 app.statebackend/app/gateway/deps.py:41-97
  • AuthMiddleware 对非公开路径强制校验 cookie+JWT,成功后把 user 写入 request.state.userdeerflow.runtime.user_context contextvar,供仓储层做属主过滤 backend/app/gateway/auth_middleware.py:52-70。鉴权与 CSRF 细节见第 14 章。

Agent Runtime —— RunManager / run_agent / StreamBridge

职责:把 HTTP 创建的"运行"登记、在后台异步执行 LangGraph 图、并把流式事件解耦推给 SSE 消费者。这是"内嵌 runtime"的核心,等价于 LangGraph Platform 的 Queue + StreamManager。

关键文件 / 关键点:

LeadAgent —— LangGraph 图入口

职责:被 langgraph.json 注册为图 lead_agent,根据运行配置动态选模型、装配中间件链、加载工具与系统提示。

关键点:make_lead_agent(config)langgraph.json 指定的工厂入口 backend/langgraph.json:8-9 backend/packages/harness/deerflow/agents/lead_agent/agent.py:343-347;deerflow.agents 包导入时预热 enabled-skills 缓存以减少请求路径上的同步文件 IO backend/packages/harness/deerflow/agents/init.py:7-10。LeadAgent 与中间件链分别见第 10、12 章。

Provisioner —— 沙箱供应器(:8002,可选)

职责:仅在沙箱配置为 provisioner/Kubernetes 模式时启动;按 sandbox_id 在宿主 K8s 上创建 Pod + NodePort Service,backend 通过 {NODE_HOST}:{NodePort} 直连沙箱。

关键点:暴露 POST/DELETE/GET /api/sandboxes/health;通过挂载的 ~/.kube/config 连宿主集群 docker/provisioner/app.py:11-30。compose 健康检查每 10s 探测 :8002/health docker/docker-compose.yaml:142-146。沙箱系统架构见第 17 章。

Data Flow

下图展示一次浏览器对话请求从输入到 SSE 流式返回的完整链路。

编号步骤说明:

1-2. 浏览器请求经 Nginx,/api/langgraph/ 前缀被重写为 /api/,并应用 600s 超时与关闭缓冲 docker/nginx/nginx.conf:43-64

  1. AuthMiddleware 校验 cookie+JWT 并把 user 注入 contextvar backend/app/gateway/auth_middleware.py:52-70

4-6. 路由层经 start_runRunManager.create_or_reject() 登记运行并按多任务策略处理 inflight backend/packages/harness/deerflow/runtime/runs/manager.py:224-290;thread_runs router 是薄 HTTP 层,委托给 app.gateway.services backend/app/gateway/routers/thread_runs.py:22-28

7-12. run_agent() 标记 running、发 metadata、用 agent.astream 驱动图,每个分块 serializepublish 到 StreamBridge backend/packages/harness/deerflow/runtime/runs/worker.py:178-309

13-15. SSE 帧经 Nginx 原样透传给浏览器;无论成功失败,finally 都 publish_end 并写最终状态、延迟 cleanup backend/packages/harness/deerflow/runtime/runs/worker.py:366-403

Common Pitfalls / Tips

  • events stream_mode 在 Gateway 内不可用:它需要 astream_events(),无法与 values 快照共存,worker 会记录日志并跳过。前端应使用 values + messages-tuple backend/packages/harness/deerflow/runtime/runs/worker.py:154-159
  • CORS 默认同源:经 Nginx 2026 同源访问时无需 CORS;拆分前后端或端口转发时必须用 GATEWAY_CORS_ORIGINS 显式 opt-in,CORSMiddleware 与 CSRFMiddleware 共用同一来源清单 backend/app/gateway/app.py:313-324
  • IM channels 走 SDK 而非内部直调:channels 通过 langgraph-sdk HTTP 客户端访问 Gateway;Docker compose 内 localhost 指向 gateway 容器自身,需用 http://gateway:8001(DEER_FLOW_CHANNELS_GATEWAY_URL)docker/docker-compose.yaml:102-103
  • harness 不能 import app:deerflow.* 反向引用 app.* 会被 CI 的 test_harness_boundary.py 拦截;新代码若在 harness 内需要应用层能力,应通过依赖注入(如 RunContext)传入 backend/app/gateway/deps.py:139-152
  • Provisioner 缺席不阻塞启动:Nginx 用变量延迟解析 provisioner:8002,本地/无 K8s 部署可不启动 Provisioner docker/nginx/nginx.conf:194-205

References

页面关系
09-Harness与App分层边界深入本章提到的 harness/app 依赖方向与 CI 边界守卫
13-Gateway-API与路由体系展开 Gateway 各 router 与 create_app() 路由全貌
15-Runtime运行时与StreamBridge详解 RunManager/run_agent/StreamBridge 的 SSE 与重连机制
17-沙箱系统架构展开 Provisioner 与沙箱 Provider 的完整体系
10-LeadAgent与Agent工厂深入 make_lead_agent 工厂与图构建

公司内部参考 · 由 claude-wiki-gen 基于源码自动生成的二次分析