DeerFlow 架构解剖:它不是一个聊天壳,而是一套可拼装的 Agent Runtime
DeerFlow Architecture Analysis: A Composable Agent Runtime
DeerFlow 最值得看的,不是它又接了多少模型,而是它把一个智能体系统拆成了 Web 入口、可复用 harness、sandbox、subagent、skills、MCP 与 guardrails 这些清晰边界。它不像许多 demo 那样把一切堆进主循环,而是试图把 Agent 做成一套可以治理、可以扩展、也可以嵌入别的应用的运行时。
项目概览
DeerFlow 的核心特征,不在于提供一个“能聊天、能调工具”的前端壳,而在于构建了一套 既可被 Web 应用调用、也可被其他 Python 系统嵌入的 Agent Runtime。
这一点在其系统拆分方式中体现得非常明显。许多智能体项目随着功能叠加,往往会把前端、网关、模型工厂、工具系统、权限控制和记忆机制混在同一个主循环中。DeerFlow 则将这些能力显式拆开:最上层是 Nginx 统一入口;中间层由 LangGraph Server、Gateway API 与 Next.js Frontend 组成;底层则是可复用的 deerflow harness。

如果用一句公式化的方式概括其结构,可写成:
这意味着 DeerFlow 并未把“Agent”收缩为一个函数调用,而是将其实现为一个同时包含入口层、控制面、执行面与治理面的运行时系统。
核心设计:真正重要的是边界,而不是功能清单
1. Harness / App 分层,是系统可复用性的基础
在源码结构中,app/ 负责 FastAPI Gateway 与通道应用层,packages/harness/deerflow/ 才是核心 runtime。文档对两者的依赖方向约束写得非常明确:app 可以 import deerflow,deerflow 不能 import app。
这一边界直接决定了系统能否被复用、嵌入和测试。deerflow harness 因此能够作为独立 runtime 核心存在,而 Web 层、上传接口、线程清理、建议生成等能力则被约束在外围控制面。对 Agent 项目而言,这种边界管理往往比功能堆叠更重要,因为后期能否 SDK 化、模块化,通常取决于 runtime 是否从一开始就与产品层解耦。
2. DeerFlow 的 middleware 不是洋葱,而是管道
DeerFlow 主 agent 默认带有 14 个 middleware,但其执行方式并非 Koa 式的对称洋葱模型,而更接近一条在关键阶段挂接能力的流水线:
before_agent正序执行:ThreadData → Uploads → Sandboxbefore_model正序执行:ViewImageafter_model反序执行:Clarification → LoopDetection → SubagentLimit → Title → Summarization → DanglingToolCallafter_agent反序执行:Sandbox release → Memory enqueue
也就是说:
因此 ClarificationMiddleware 虽然位于列表末尾,却会最先拦截模型输出。这一执行细节表明,DeerFlow 将 middleware 视为“在若干关键节点挂接能力”的机制,而不是追求形式上对称的嵌套结构。对 Agent runtime 来说,这种设计更加贴近现实,因为很多能力原本就只需要单向钩子,而不需要完整包裹整个调用链。
3. Subagent 的本质是受限并发,而不是无限分叉
在 subagent 执行上,DeerFlow 采取了非常克制的策略。SubagentExecutor 使用 _scheduler_pool 与 _execution_pool 两层线程池,每层 max_workers=3;同时系统还设置了 MAX_CONCURRENT_SUBAGENTS = 3 的全局硬限制。
这一设计意味着 subagent 并不是开放式扩散,而是被严格约束在配额、超时和 middleware 规则之内的执行单元。多智能体系统常见的问题包括并发失控、上下文污染、权限外溢和任务调度混乱;DeerFlow 的做法,是先把 subagent 收敛为可治理的运行时对象,再讨论其能力边界。
此外,subagent 并未完整继承主 agent 的中间件链,而只保留 ThreadData、Sandbox、Guardrail、ToolErrorHandling 这条精简链。这说明子代理在系统中的角色被明确定义为执行单元,而不是主产品表面的复制品。
真正把系统拉开差距的,是执行基座
Sandbox:从“能跑命令”到“怎么跑命令”
DeerFlow 的 sandbox 抽象更接近一个正式的 runtime substrate。接口层仅暴露 acquire / get / release,但底层实现分成两类:
LocalSandboxProvider:单例、本地直接执行,适合开发环境AioSandboxProvider:容器化、可热复用,适合生产环境
后者包含多个关键机制:Warm Pool、idle timeout、replicas 软上限、LRU 驱逐以及线程目录虚拟路径映射。由此可见,DeerFlow 关注的不只是“是否存在沙箱”,而是如何摊平沙箱生命周期带来的性能与调度成本。
尤其是在 release 之后,容器不会立刻销毁,而是被放入 warm pool 等待下一次线程复用。这种设计说明,sandbox 在 DeerFlow 中并非简单的安全外壳,而是被纳入了长期运行系统的资源调度逻辑之中。
Skills、MCP 与 RuntimeFeatures:扩展不再依赖 if/else 堆叠
DeerFlow 的扩展面设计也相当清晰:
- skills 递归扫描
skills/{public,custom}下的SKILL.md - enabled 状态来自
extensions_config.json - MCP 通过
MultiServerMCPClient管理,支持 stdio / SSE / HTTP 与 OAuth RuntimeFeatures用于开启、关闭或替换默认 middleware@Next/@Prev允许外置 middleware 以声明式方式插入链中
这组设计共同指向一个目标:扩展能力不应被写死在主循环中,而应当通过可插拔机制进行组合。
其中,@Next/@Prev 的价值在于,它不依赖全局 priority 数字竞争插入位置,而是通过“位于谁之前/之后”的局部关系声明链路顺序。对 runtime 维护而言,这种局部约束通常比全局排序表更稳定,也更容易演化。
Memory 与 Guardrails:一个负责沉淀,一个负责制动
MemoryMiddleware 在 after_agent 阶段异步入队;在总结时只保留 user 与 final assistant 消息,并过滤 tool calls 与 ToolMessage;同时还会检测 correction / reinforcement 信号。这说明其记忆机制不是简单保存聊天全文,而是在进行面向长期偏好的压缩式提炼。
Guardrails 则承担另一类职责。它将工具授权放在 wrap_tool_call 阶段,使每次调用在执行前都先经过策略评估。Allowlist、OAP Passport 与 Custom Provider 三种模式并存,体现出非常明确的运行时治理逻辑:模型可以提出动作建议,但真正的执行权限仍由 runtime 决定。
从这一点看,DeerFlow 的安全设计重点并不在于“让模型更懂事”,而在于“让运行时保有最终裁决权”。
综合判断
从整体结构看,DeerFlow 更接近一个正在成形的 Agent Runtime 平台内核层,而不只是单独的 agent app。虽然距离“操作系统”层级仍有距离,但其中间件 pipeline、sandbox provider、subagent 配额、skills/MCP 插件面以及 memory/guardrails 治理层,已经表现出明显的平台化倾向。
其优势主要集中在三点:
- 边界清楚:harness 与 app 分层明确,Web 面与 runtime 面没有完全混合。
- 执行现实主义:subagent、sandbox、guardrail 都围绕配额、生命周期和授权展开,而不是仅讨论能力堆叠。
- 扩展方式成熟:skills、MCP、RuntimeFeatures 与
@Next/@Prev使系统更接近平台,而非单体应用。
其成本同样明显:结构复杂度更高;新读者需要同时理解 LangGraph、FastAPI、sandbox、extensions config、skills 注入和 middleware 时序;一旦观测性和文档不足,维护门槛就会迅速上升。
但这类复杂度并非偶然噪音,而是平台化 runtime 在进入治理、扩展与安全层之后必然付出的代价。DeerFlow 的价值,正在于它没有回避这些问题,而是尝试把这些问题显式纳入架构设计。
启示与下一步
如果将 DeerFlow 视为一个样本,它对 Agent 系统设计至少给出四条明确提醒:
- 先划清 harness 与 app 的边界,再谈 SDK 化。
- 把 middleware 当作运行时治理面,而不是迷信对称洋葱。
- subagent 的本质是受控并发,而不是自动组织。
- 系统可信度更多来自 sandbox、guardrails、memory 与扩展控制面,而不是模型本身。
从这一样本可以看到,Agent 不必只是一段提示词外包着一组工具调用;它同样可以被实现为一套具备边界、调度与治理能力的正式运行时。