首页
/ DeerFlow Backend 深入解析:LangGraph 驱动的超长任务 SuperAgent 后端架构与实践指南

DeerFlow Backend 深入解析:LangGraph 驱动的超长任务 SuperAgent 后端架构与实践指南

2026-09-06 19:09:11作者:乔或婵

本指南以仓库 backend/README.md 为主体脉络,系统讲解 DeerFlow 后端的整体架构、核心组件(Lead Agent、中间件链、沙箱、子代理、记忆系统、工具生态、Gateway API 与 IM 渠道)、安装运行、配置体系、可观测性与开发规约,并结合 config.example.yamldeerflow-harness 源码佐证底层实现。读完你将掌握:请求如何从 Nginx 路由到 Gateway 与内嵌 Agent 运行时、九层中间件如何协同支撑每轮对话、如何配置模型/沙箱/记忆/扩展,以及如何在本仓库中开发、迁移与测试。

一、整体架构与请求路由

DeerFlow 是一个基于 LangGraph 的 AI SuperAgent:支持沙箱内执行代码、浏览网页、管理文件、向子代理委派任务、在对话间保留持久记忆,并且所有执行都发生在按线程隔离的环境中。后端由内嵌运行时与 API 网关共同构成。

backend/README.md 的架构示意可以还原出如下拓扑:

                        ┌──────────────────────────────────────┐
                        │          Nginx (Port 2026)           │
                        │      Unified reverse proxy           │
                        └───────┬──────────────────┬───────────┘
                                │
            /api/langgraph/*    │    /api/* (other)
            rewritten to /api/* │
                                ▼
               ┌────────────────────────────────────────┐
               │        Gateway API (8001)              │
               │        FastAPI REST + agent runtime    │
               │                                        │
               │ Models, MCP, Skills, Memory, Uploads,  │
               │ Artifacts, Threads, Runs, Streaming    │
               │                                        │
               │ ┌────────────────────────────────────┐ │
               │ │ Lead Agent                         │ │
               │ │ Middleware Chain, Tools, Subagents │ │
               │ └────────────────────────────────────┘ │
               └────────────────────────────────────────┘

前端(Next.js)、后端网关(FastAPI)与 LangGraph 兼容 API 统一由 Nginx(端口 2026)反向代理汇聚,内部路由规则如下:

  • /api/langgraph/* → 重写为 /api/* 后进入 Gateway 的 LangGraph 兼容 API,负责 agent 交互、线程(threads)、流式输出(streaming);
  • /api/*(其余请求)→ Gateway API,负责模型、MCP、技能、记忆、产物、上传以及线程本地数据清理;
  • /(非 API 请求)→ 前端 Next.js Web 界面。

对应源码可以进一步阅读 gateway 路由模块(含 models.pymcp.pyskills.pymemory.pythreads.pyruns.pyuploads.pyartifacts.pychannels.py 等)。需要留意的是,langgraph.json(位于 backend/langgraph.json)并不是默认服务入口——脚本与 Docker 部署走的是 Gateway 内嵌运行时,该文件仅为 LangGraph 工具链、Studio 或直接使用 LangGraph Server 时保留的兼容入口。

二、核心组件逐个拆解

2.1 Lead Agent:唯一的 LangGraph 主 Agent

后端运行时只有一个 LangGraph Agent,即 lead_agent,通过 make_lead_agent(config) 工厂创建(实现位于 agents/lead_agent/agent.py,其提示词与图装配见 lead_agentagents/factory.py)。它聚合了五类能力:

  • 动态模型选择:支持 thinking(思考)与 vision(视觉)能力开关;
  • 中间件链:承载横切关注点,共 9 个中间件(见下节);
  • 工具系统:沙箱工具、MCP 工具、社区工具与内置工具;
  • 子代理委派:支持并行任务执行;
  • 系统提示词:注入技能、记忆上下文与工作目录指引。

models[*] 中以 supports_thinking / supports_vision 标记模型能力;模型工厂与 providers 集中在 models

2.2 中间件链:严格顺序的九层横切逻辑

中间件按严格顺序执行,每一层负责一个关注点。README 给出的对照表如下:

# Middleware Purpose
1 ThreadDataMiddleware 为每个线程创建隔离目录(workspace、uploads、outputs)
2 UploadsMiddleware 将新上传的文件注入会话上下文
3 SandboxMiddleware 获取用于代码执行的沙箱环境
4 SummarizationMiddleware 接近 token 上限时压缩上下文(可选)
5 TodoListMiddleware 在 plan 模式中跟踪多步任务(可选)
6 TitleMiddleware 首轮交互后根据用户原始请求自动生成会话标题;纯附件消息回退为 New Conversation
7 MemoryMiddleware 将会话排队供异步记忆抽取
8 ViewImageMiddleware 为支持视觉的模型注入图像数据(条件性)
9 ClarificationMiddleware 拦截澄清请求并中断执行(必须位于最后)

上述中间件的源码实现位于 agents/middlewares(例如 memory_middleware.pysummarization_middleware.pyclarification_middleware.py),沙箱生命周期中间件则在 sandbox/middleware.py。需要指出的是,从仓库源码结构看中间件远不止 9 个——README 所列是主链路上顺序执行的核心横切层,另有 dangling_tool_call_middleware.pyloop_detection_middleware.pyllm_error_handling_middleware.pyskill_tool_policy_middleware.pyterminal_response_middleware.py 等安全/健壮性中间件共同组成完整运行链。

2.3 沙箱系统:按线程隔离的执行环境

沙箱提供按线程隔离的执行能力,并通过虚拟路径翻译把“虚拟路径”映射到“线程专属物理目录”:

  • 抽象接口execute_commandread_filewrite_filelist_dir,定义于 sandbox/sandbox.py
  • 两个 ProviderLocalSandboxProvider(直接使用宿主机文件系统,见 sandbox/local)与 AioSandboxProvider(基于 Docker,位于 community/)。异步运行时路径使用异步沙箱生命周期钩子,使启动、就绪轮询与释放都不会阻塞事件循环;AioSandboxProvider 在 acquire/reuse 时会校验 active-cache 与 warm-pool 中的容器,丢弃确认死亡的条目,从而在容器意外退出后仍能为线程提供全新沙箱,同时保持 get() 为纯内存查找。后端健康检查失败会被当作“状态未知”而非“死亡”;发现阶段无法确认的容器不会被采纳(acquire 会回退为创建而非报错)。
  • 虚拟路径/mnt/user-data/{workspace,uploads,outputs} → 线程专属物理目录;
  • 技能路径/mnt/skillsdeer-flow/skills/ 目录;
  • 技能加载:递归发现 skills/{public,custom} 下的嵌套 SKILL.md,并保留嵌套容器路径;
  • SkillScan:在安装及 agent 管理的技能写入时,先于 LLM 技能扫描器执行原生离线确定性扫描,CRITICAL 级发现会阻断,警告级发现进入 LLM 上下文;
  • 文件写入安全str_replace(sandbox.id, path) 串行化 read-modify-write,使隔离沙箱即使虚拟路径相同也保持并发;
  • 工具集合bashlsread_filewrite_filestr_replace。其中 write_file 默认覆盖并在末尾提供 append 选项;LocalSandboxProviderbash 默认禁用(该 Provider 不是 shell 访问的安全隔离边界),如需隔离的 shell 访问应改用 AioSandboxProvider。工具实现见 sandbox/tools.py

沙箱还支持额外的宿主目录挂载(mounts)、工具输出截断上限以及单条 bash 命令的最大墙钟时间(见后文配置)。macOS 上 AIO Sandbox 优先使用 Apple Container(可用时),其他平台使用 Docker。

2.4 子代理系统:异步并发委派

子代理让 Lead Agent 通过 task() 工具把任务异步委派给后台运行的专业 Agent:

  • 内置 Agentgeneral-purpose(完整工具集)与 bash(命令专家,仅在具备 shell 访问时暴露);
  • 并发限制:每轮最多 3 个子代理(subagent_runtime.max_running 默认为 3),单个内置子代理默认超时 1800 秒(30 分钟);另有 max_queuedadmission_policy(queue/reject)与 queue_timeout_seconds 描述进程级执行容量;
  • 执行方式:后台线程池执行并带状态跟踪与 SSE 事件;
  • 调用流:Agent 调用 task() 工具 → executor 在后台运行子代理 → 轮询直至完成 → 返回结果。

实现集中于 subagents(内置定义见 subagents/builtins,执行引擎为 executor.py,注册表为 registry.py)。内置默认 max_turns:general-purpose=150bash=60config.yaml 可对单类 Agent 覆盖超时、轮数与 token 预算,也可定义 custom_agents(自定义提示词、工具白名单、技能白名单与模型),自定义 Agent 经 task 工具与内置类型并列可用。所有子代理默认继承 Lead Agent 的模型,可在 subagents.agents.<name>.model 中覆盖(须匹配 models: 中已定义的名称)。作为确定性兜底,max_total_per_run(默认 6,合法范围 1–50)限制单次 Lead Agent run 内允许委派子代理的总次数。

2.5 记忆系统:LLM 驱动的跨会话持久上下文

记忆机制由 LLM 驱动,把对话中提炼的用户画像、事实与偏好持久化,用于后续会话注入:

  • 自动抽取:分析会话,提取用户背景、事实与偏好;
  • 作用域安全写入:中间件抽取仅存储持久、描述性的用户级事实;全局摘要同样要求描述性权威;当作用域元数据缺失或属于任务/项目本地作用域时,矛盾移除与合并事实会 fail closed;
  • 原子替换:与替换绑定的矛盾移除只有在替换通过作用域/置信度门槛、去重与事实数量裁剪后才执行;
  • 结构化存储:用户上下文(工作/个人/置顶)、历史以及带置信度分数的事实;
  • 防抖更新:批量聚合更新以最小化 LLM 调用(可配置等待时间);
  • 系统提示词注入:Top 事实 + 上下文注入 Agent 提示词;
  • Run 级记忆身份GET /api/threads/{thread_id}/runs/{run_id}/events?event_types=context:memory 返回生效隐藏记忆块的 SHA-256 身份,而无需把记忆文本复制进事件存储;
  • 读取失败策略:严格后端策略(含历史 fail_closed)会停止当前轮次,包括 5 秒异步注入截止线;fail-open 读取在无新上下文时继续;超时处理不等待空闲 worker——超时读仍可能占用其 worker 直到后端返回;
  • 存储介质:JSON 文件,基于 mtime 的缓存失效。

实现位于 agents/memory。记忆后端可插拔:memory.manager_class 支持已注册后端名(如 deermem/mem0/noop)或指向 MemoryManager 子类的点分路径,后端私有参数经 memory.backend_config 透传(含 storage_pathmodeldebounce_secondsmax_factsfact_confidence_thresholdmax_injection_tokens、token 计数方式以及 staleness 定期清理参数组等)。

2.6 工具生态

Category Tools
Sandbox bashlsread_filewrite_filestr_replace
Built-in present_filesask_clarificationview_imagetask(子代理委派)
Community Tavily(网页搜索)、Jina AI(网页抓取)、Crawl4AI(网页抓取)、Firecrawl(爬取)、fastCRW(爬取)、DuckDuckGo(图片搜索)
MCP 任意 Model Context Protocol 服务器(stdio、SSE、HTTP 传输)
Skills 经系统提示词注入的领域专属工作流

内置工具源码见 tools/builtins,社区工具与第三方 Provider 位于 deerflow.community 模块树(例如 web_search 工具在 config.example.yaml 中同时提供了 DuckDuckGo、SearXNG、Serper、Serply、Brave、Tavily、InfoQuest、腾讯云、Exa、Firecrawl、GroundRoute、fastCRW 等多个可选实现,默认启用免 API key 的 DuckDuckGo 后端)。tool_groups(web、file:read、file:write、bash、browser、knowledge)用于工具组织与访问控制,tools 的每条定义都包含 namegroupuse(模块路径)。

2.7 Gateway API:前端集成的 REST 端点

Gateway 是承载 REST 端点的 FastAPI 应用(应用装配见 gateway/app.py)。README 列出的核心路由包括:

Route Purpose
GET /api/models 列出可用 LLM 模型
GET/PUT /api/mcp/config 管理 MCP 服务器配置
POST /api/mcp/cache/reset 重置 MCP 工具缓存,使其下次使用时重新加载
GET/PUT /api/skills 列出与管理技能
POST /api/skills/install .skill 归档安装技能
GET /api/memory 读取记忆数据
POST /api/memory/reload 强制重载记忆
GET /api/memory/config 记忆配置
GET /api/memory/status 组合配置 + 数据
GET /api/threads/{id}/runs/{run_id}/events 单次 run 的调试/审计事件;event_types=context:memory 过滤出有效记忆身份
POST /api/threads/{id}/uploads 上传文件(自动把 PDF/PPT/Excel/Word 转成 Markdown,拒绝目录路径,同一请求内重复文件名自动重命名)
GET /api/threads/{id}/uploads/list 列出已上传文件
DELETE /api/threads/{id} 在 LangGraph 线程删除后清理 DeerFlow 管理的本地线程数据;意外失败记录在服务端并返回通用 500 详情
GET /api/threads/{id}/artifacts/{path} 提供生成的产物文件

2.8 IM 渠道

IM 桥接支持 飞书(Feishu)、Slack 与 Telegram:Slack 与 Telegram 仍走最终 runs.wait() 响应路径;飞书改为经 runs.stream(["messages-tuple", "values"]) 流式返回,在渠道管理器内部串行化同线程的快速连续回合,并按源消息原位更新单张线程内卡片。飞书卡片更新时,DeerFlow 为每条入站消息保存运行中卡片的 message_id,持续 patch 同一卡片直至 run 结束,从而保留既有 OK/DONE 反应流;当既有飞书主题内出现后续消息而上一轮仍在运行时,后续消息会等待映射到的 DeerFlow thread_id,并在该精确源消息上收到排队/运行卡片,且保留紧凑的源消息引用块以区分快速连问。

Discord 在入站消息处理让出控制权之前注册每个“输入中”指示器循环,并在渠道停止后拒绝启动新的 typing 任务;typing 任务归属 Discord 专属事件循环,正常关闭会在关闭客户端前于该循环上调度有界取消、等待与映射清理,从而串行化主线程与 Discord 线程的注册/清理,同时避免关闭挂起与跨循环 RuntimeError

三、快速上手:安装、配置与运行

3.1 环境要求

  • Python 3.12+
  • uv 包管理器(README 与 Makefile 均以 uv 为依赖安装载体)
  • 所选 LLM Provider 的 API key

3.2 安装步骤

cd deer-flow

# 复制配置文件
cp config.example.yaml config.yaml

# 安装后端依赖
cd backend
make install

Makefilepyproject.toml 承载依赖与常用开发命令;容器化构建见 backend/Dockerfile

3.3 最小配置与 API key

编辑项目根目录的 config.yaml(以 config.example.yaml 为蓝本)。README 给出了两个 OpenAI 示例条目:

models:
  - name: gpt-4o
    display_name: GPT-4o
    use: langchain_openai:ChatOpenAI
    model: gpt-4o
    api_key: $OPENAI_API_KEY
    supports_thinking: false
    supports_vision: true

  - name: gpt-5-responses
    display_name: GPT-5 (Responses API)
    use: langchain_openai:ChatOpenAI
    model: gpt-5
    api_key: $OPENAI_API_KEY
    use_responses_api: true
    output_version: responses/v1
    supports_vision: true

然后导出对应的 API key:

export OPENAI_API_KEY="your-api-key-here"

3.4 模型配置要点(结合 config.example.yaml 深入)

config.example.yaml 中的注释还揭示了模型条目更完整的语义,部署前建议逐项核对:

  • use 的格式为 包名.子包.模块:类名/变量名,按模块路径引用 Provider 类。若 Provider 模块缺失,DeerFlow 会返回带安装指引的可操作错误(例如提示 uv add langchain-google-genai)。
  • max_tokens每次调用的输出上限;context_window 是提示词 + 补全的总上下文容量,驱动 UI 的实时“% context used”指示并供给 summarization.triggerfraction 类型触发器解析阈值。第三方 OpenAI 兼容模型没有内置 profile,不设置 context_window 时 fraction 触发器会降级(丢弃并告警)而不是使 Agent 构建崩溃。
  • 支持添加 pricing 块(单一币种,按每百万 token 计价)在控制台展示真实成本。
  • 使用需 thinking 的厂商模型时,推荐用补丁 Provider 保留 reasoning 字段跨多轮工具调用回放:例如 DeepSeek 用 deerflow.models.patched_deepseek:PatchedChatDeepSeekpatched_deepseek.py)、MiMo 用 PatchedChatMiMo、StepFun 用 PatchedChatStepFun、MiniMax 用 PatchedChatMiniMax、OpenAI 兼容网关用 PatchedChatOpenAI;Anthropic 开启 thinking 时必须同时配置 when_thinking_enabled.thinking.budget_tokens(最小 1024 且须小于 max_tokens),否则会静默回退到非 thinking 模式。
  • Ollama 请使用 langchain_ollama:ChatOllama 原生 Provider(其 /v1/chat/completions 兼容端点不会把 reasoning 作为独立字段返回);本地/容器地址在 Docker 部署时应写 host.docker.internal
  • 配置值以 $ 开头时解析为环境变量。

3.5 启动运行

完整应用(项目根目录执行):

make dev  # 启动 Gateway + Frontend + Nginx

访问地址:http://localhost:2026

仅后端(backend 目录执行):

# Gateway API + 内嵌 Agent 运行时
make dev

Gateway 直连地址:http://localhost:8001

终端工作台(TUI)——无需任何服务的内嵌运行时终端 UI:

uv pip install 'deerflow-harness[tui]'   # 可选 'textual' 依赖
deerflow                                 # 启动 TUI
deerflow --print "summarize this repo"   # 无头单次执行
deerflow --recursion-limit 250 --print "run a longer task"

TUI 中打开的会话会出现在 Web UI 侧边栏(它把共享的 threads_meta 存储写入本地默认用户之下),详见 backend/docs/TUI.md

四、工程目录结构与 langgraph.json 的角色

deerflow-harness 是打包为 Python 库的核心运行时(以 deerflow.* 导入),目录结构如下(摘自 README 并经源码核对):

backend/
├── packages/harness/           # deerflow-harness 包(import: deerflow.*)
│   └── deerflow/
│       ├── agents/             # Agent 系统
│       │   ├── lead_agent/     # 主 Agent(工厂、提示词)
│       │   ├── middlewares/    # 中间件组件
│       │   ├── memory/         # 记忆抽取与存储
│       │   └── thread_state.py # ThreadState schema
│       ├── sandbox/            # 沙箱执行
│       │   ├── local/          # 本地文件系统 Provider
│       │   ├── sandbox.py      # 抽象接口
│       │   ├── tools.py        # bash、ls、read/write/str_replace
│       │   └── middleware.py   # 沙箱生命周期
│       ├── subagents/          # 子代理委派
│       │   ├── builtins/       # general-purpose、bash agents
│       │   ├── executor.py     # 后台执行引擎
│       │   └── registry.py     # Agent 注册表
│       ├── tools/builtins/     # 内置工具
│       ├── mcp/                # MCP 协议集成
│       ├── models/             # 模型工厂
│       ├── skills/             # 技能发现与加载
│       ├── config/             # 配置系统
│       ├── runtime/            # 内嵌 run 执行(RunManager、StreamBridge)
│       ├── persistence/        # Checkpointer/store 引擎与 schema 迁移
│       ├── guardrails/         # 工具调用前授权 Provider
│       ├── tracing/            # Tracer 工厂与 trace 元数据
│       ├── uploads/            # 上传管理器
│       ├── tui/                # 终端 UI(`deerflow` console 脚本)
│       ├── community/          # 社区工具与 Provider
│       ├── reflection/         # 动态模块加载
│       └── utils/              # 工具函数
├── app/                        # FastAPI Gateway + IM 渠道(import: app.*)
│   ├── gateway/                # Gateway API
│   │   ├── app.py              # 应用装配
│   │   └── routers/            # 路由模块
│   └── channels/               # IM 渠道集成
├── docs/                       # 文档
├── tests/                      # 测试套件
├── langgraph.json              # LangGraph 图注册表(供工具链/Studio 兼容)
├── pyproject.toml              # Python 依赖
├── Makefile                    # 开发命令
└── Dockerfile                  # 容器构建

如需启动可选的独立开发服务器并打开其 Studio 地址:

cd backend
uv run langgraph dev --allow-blocking

需在 backend/ 下运行以便 CLI 发现 langgraph.json。要点:该内存态服务器仅面向开发与测试而非生产部署;--allow-blocking 允许 DeerFlow 在本地 Studio 请求期间执行同步配置与图工厂装配,并非生产设置;本地 Studio 认证与已注册图发现自动处理,无需自定义连接头。Assistant 归属/来源由服务器盖章,常规 assistant 版本选择仍然可用。在锁定本地运行时加载持久化开发存储前,DeerFlow 会修复遗留 assistant 行与版本历史,防止旧元数据重新激活仅服务端权限或被运行时启动清理丢弃。依赖变更后需执行 uv sync;该兼容路径要求声明的 LangGraph 运行时版本,并在持久化存储契约不符时告警。这一基于文件的 custom-app 加载路径已被后端回归测试套件覆盖。

五、配置体系详解

5.1 主配置 config.yaml

放在项目根目录,以 $ 开头的值解析为环境变量。核心小节如下:

  • models — 带类路径、API key、thinking/vision 标志的 LLM 配置
  • tools — 带模块路径与分组的工具定义
  • tool_groups — 逻辑工具分组
  • sandbox — 执行环境 Provider
  • skills — 技能目录路径
  • title — 自动标题生成设置
  • summarization — 上下文摘要设置
  • subagents — 子代理系统(启/停)
  • memory — 记忆系统设置(enabled、storage、debounce、facts 上限)
  • 其他顶层键(详见 config.example.yaml):config_version(schema 变更时递增,旧配置可运行 make config-upgrade 合并新字段)、log_leveltoken_usagetoken_budget(每 run 硬性 token 上限,可设置 warn/hard-stop 阈值)、max_recursion_limit(对客户端提交的 recursion_limit 硬性封顶,超出被钳制到该上限,非法/非正值回退服务端默认 100)、uploads(应用级上传限制与文档转换开关,如 auto_convert_documents: falsepdf_converter: auto)、skill_scanverification(结果回执)等。

沙箱小节默认选择本地沙箱(直接宿主执行),并明确关闭宿主 bash:

sandbox:
  use: deerflow.sandbox.local:LocalSandboxProvider
  allow_host_bash: false      # 仅对完全可信的单用户本地工作流开启
  bash_output_max_chars: 20000
  read_file_output_max_chars: 50000
  ls_output_max_chars: 20000
  bash_command_timeout: 600

容器化 AIO Sandbox 版本则切换为 deerflow.community.aio_sandbox:AioSandboxProvider,并支持容器镜像钉版、replicas(默认 3,最近最少使用驱逐)、出站网络策略(open/isolated/allowlist,受限模式要求 Docker Engine 28+,私有/回环/链路本地/组播/云元数据地址始终被拒)、thread_data_mounts、环境变量注入、跨实例容器所有权(多 Gateway 实例共享一个容器后端时须设置 ownership.type: redis)等高级项。完整的参数注释见 config.example.yaml

标题生成默认开启(max_words: 6max_chars: 60model_name: null 使用快速本地回退,设置模型名则改用 LLM 生成)。

摘要配置支持多触发条件(OR 逻辑):按 token 数(默认 32000)、消息数或模型输入上限比例(fraction),以及摘要后保留策略(默认保留最近 10 条消息)。详见 config.example.yaml

5.2 扩展配置 extensions_config.json

MCP 服务器与技能状态统一放在单个文件中(仓库根目录的 extensions_config.example.json 提供模板)。README 给出的完整示例:

{
  "mcpServers": {
    "github": {
      "enabled": true,
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {"GITHUB_TOKEN": "$GITHUB_TOKEN"}
    },
    "secure-http": {
      "enabled": true,
      "type": "http",
      "url": "https://api.example.com/mcp",
      "oauth": {
        "enabled": true,
        "token_url": "https://auth.example.com/oauth/token",
        "grant_type": "client_credentials",
        "client_id": "$MCP_OAUTH_CLIENT_ID",
        "client_secret": "$MCP_OAUTH_CLIENT_SECRET"
      }
    },
    "postgres": {
      "enabled": false,
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-postgres", "postgresql://localhost/mydb"],
      "description": "PostgreSQL database access",
      "routing": {
        "mode": "prefer",
        "priority": 50,
        "keywords": ["orders", "users", "SQL", "database", "table"]
      },
      "tools": {
        "query": {
          "routing": {
            "priority": 100,
            "keywords": ["query database", "orders table", "metrics"]
          }
        }
      }
    }
  },
  "skills": {
    "pdf-processing": {"enabled": true}
  }
}

routing 会向 Agent 提示词注入“软性”MCP 偏好:让模型在匹配请求时优先选用配置好的 MCP 工具,但并不禁止其他工具。当 tool_search.enabled=true 推迟(defer)MCP schema 时,命中的 routing 元数据可在模型调用前把最多 tool_search.auto_promote_top_k 个被推迟的 schema 自动提升。

5.3 环境变量

  • DEER_FLOW_CONFIG_PATH — 覆盖 config.yaml 位置
  • DEER_FLOW_EXTENSIONS_CONFIG_PATH — 覆盖 extensions_config.json 位置
  • 模型 API key:OPENAI_API_KEYANTHROPIC_API_KEYDEEPSEEK_API_KEY
  • 工具 API key:TAVILY_API_KEYGITHUB_TOKEN

结合 config.example.yaml 注释还常见:DEER_FLOW_PROJECT_ROOT(显式指定项目根)、DEER_FLOW_HOME(运行时数据目录,默认项目根下的 .deer-flow)、DEER_FLOW_DATE_TIMEZONE(注入 Agent 的会话日期时区)、DEER_FLOW_SKILLS_PATHDEER_FLOW_STREAM_BRIDGE_REDIS_URL 等。

六、可观测性:LangSmith / Langfuse / 双 Provider

DeerFlow 内置 LangSmith 集成。启用后,所有 LLM 调用、Agent 运行、工具执行与中间件处理都会被追踪并显示在 LangSmith 控制台。配置方式(写在项目根 .env 中):

LANGSMITH_TRACING=true
LANGSMITH_ENDPOINT=https://api.smith.langchain.com
LANGSMITH_API_KEY=lsv2_pt_xxxxxxxxxxxxxxxx
LANGSMITH_PROJECT=xxx

兼容旧变量LANGCHAIN_TRACING_V2LANGCHAIN_API_KEYLANGCHAIN_PROJECTLANGCHAIN_ENDPOINT 仍受支持;两者同时设置时 LANGSMITH_* 优先。

Langfuse 追踪面向 LangChain 兼容的运行:

LANGFUSE_TRACING=true
LANGFUSE_PUBLIC_KEY=pk-lf-xxxxxxxxxxxxxxxx
LANGFUSE_SECRET_KEY=sk-lf-xxxxxxxxxxxxxxxx
LANGFUSE_BASE_URL=https://cloud.langfuse.com

自托管 Langfuse 时,把 LANGFUSE_BASE_URL 指向你的 Langfuse 主机即可。

双 Provider 行为:若同时启用 LangSmith 与 Langfuse,DeerFlow 会初始化并挂接两个 callback,同一份运行数据同时上报两套系统。若某个 Provider 被显式启用但凭据缺失或 callback 无法初始化,DeerFlow 会在模型创建期间初始化追踪时报错,而不会静默禁用追踪。Docker 环境docker-compose.yaml 默认关闭追踪(LANGSMITH_TRACING=false),请在 .env 中设置 LANGSMITH_TRACING=true 与/或 LANGFUSE_TRACING=true 及对应凭据后启用容器化部署的追踪。相关工厂与元数据实现在 deerflow/tracing

七、开发:命令、Schema 迁移与测试

7.1 Make 目标

make install    # 安装依赖
make dev        # 运行 Gateway API + 内嵌 Agent 运行时(安全 reload,端口 8001)
make gateway    # 运行 Gateway API(不 reload,端口 8001)
make lint       # 运行 linter(ruff)
make format     # 格式化代码(ruff)
make detect-blocking-io  # 盘点可能阻塞后端事件循环的 blocking IO
make migrate-rev MSG="..."  # 针对实时 ORM 模型自动生成新 alembic revision

注意:make dev 会预创建并把 DEER_FLOW_HOME(默认 backend/.deer-flow)与 backend/sandbox 从 Uvicorn 的 reload 监视器中排除。应使用该目标而非裸 uvicorn --reload:Agent 任务会在 DEER_FLOW_HOME 下写 Python 与其他运行时文件,监视该目录会在 run 进行中重启 Gateway。

7.2 Schema 迁移

DeerFlow 的应用表(runsthreads_metafeedbackusersrun_events 以及 channel_* 表)由 alembic 管理。Gateway 启动时通过 bootstrap_schema(engine, backend=...) 自动执行 alembic upgrade head,因此生产环境操作者不需要手动运行 alembic。Bootstrap 并发安全(跨进程使用 Postgres advisory lock;单 SQLite 进程内使用每引擎 asyncio.Lock),并且对已存在 schema(空 / 遗留 / 已版本化)幂等。

修改 ORM 模型后,把变更作为新 revision 提交到 packages/harness/deerflow/persistence/migrations/versions/

make migrate-rev MSG="add foo column to runs"

该目标调用 backend/scripts/_autogen_revision.py:它会在 head 新建一个临时 SQLite 并与实时模型做 diff,因此干净的 checkout 无需预置 ./data/deerflow.db。提交前请审查生成的文件,并把裸的 op.add_column / op.drop_column 换成 migrations/_helpers.py 中的幂等辅助函数。项目刻意不提供 make migrate / make migrate-stamp——Gateway 启动是唯一执行路径,从而杜绝运维误操作。完整设计见 backend/CLAUDE.md

7.3 代码风格

  • Linter/Formatter:ruff
  • 行长上限:240 字符
  • Python:3.12+,带类型注解
  • 引号:双引号
  • 缩进:4 空格

对应配置见 backend/ruff.tomlbackend/pyproject.toml

7.4 测试

# 默认离线后端测试套件(排除实时外部 API 与 blocking-I/O 测试)
make test

# 严格 blocking-I/O 套件
make test-blocking-io

# 显式真实 API 的 DeerFlowClient 集成套件
make test-live

实时套件需要合法的根级 config.yaml 与 API 凭据,可能产生 API 费用或创建本地沙箱、产物与文件,因此不在默认测试或 CI 中运行。直接以 pytest 调用 backend/tests/test_client_live.py 还需设置 DEER_FLOW_RUN_LIVE_TESTS=1

make detect-blocking-io 对后端业务代码做静态扫描,找出可能运行在事件循环上且未被测试覆盖的 blocking IO,向人工审查输出简洁汇总,并把完整 JSON 发现写入仓库根目录 .deer-flow/blocking-io-findings.json(无论从仓库根还是 backend/ 调用)。JSON 发现同时包含宽泛 IO 分类与审查导向字段(prioritylocationblocking_callevent_loop_exposurereasoncode)。priority 是由操作类型决定的确定性审查排序,并非 bug 证明;同文件裸名调用按函数名解析,因此同一文件内重名的辅助函数可能保守地多报异步可达性。

后端测试套件位于 backend/tests,覆盖客户端合约(如 test_client.pytest_client_e2e.py)、记忆(test_memory_* 系列)、沙箱(test_aio_sandbox_*test_local_sandbox_* 系列)、运行事件流等,可作为各模块行为的活文档。

八、技术栈

README 声明的依赖基线(以 backend/pyproject.tomlbackend/uv.lock 为准):

  • LangGraph(1.0.6+)— Agent 框架与多 Agent 编排
  • LangChain(1.2.3+)— LLM 抽象与工具系统
  • FastAPI(0.115.0+)— Gateway REST API
  • langchain-mcp-adapters — Model Context Protocol 支持
  • agent-sandbox — 沙箱化代码执行
  • markitdown — 多格式文档转换
  • tavily-python / firecrawl-py — 网页搜索与爬取

九、延伸阅读

登录后查看全文
热门项目推荐
相关项目推荐