AI Agent 项目赏析:DeerFlow 2.0 —— 一个真正“长跑“的 SuperAgent 是怎么设计出来的?

项目类型:Long-horizon SuperAgent Harness / Agent Runtime / 开源 Agent 平台

赏析目标:学习一个真实 Agent 项目如何组织 Harness、Agent、Sub-Agent、RunStore、Memory、Skills、Sandbox、Worker 与 Failure Recovery

核心问题:一个 Agent 真正要"跑几分钟到几小时"时,架构为什么必须围绕"失败"而不是"成功"来设计?

前面三次项目赏析,我们分别看了:

  • LangGraph ------ 学到了 Workflow / State / Graph(任务怎么编排)
  • OpenHands ------ 学到了 Coding Agent / Runtime / Sandbox / Event(Agent 怎么执行真实动作)
  • browser-use ------ 学到了 DOM 序列化 / 界面感知(Agent 怎么"看"真实界面)

但继续看这三个项目有一个共同的问题:

它们都默认"一次执行很快结束"。

LangGraph 的图跑完就停;OpenHands 的 step 循环是交互式的、人在旁边;browser-use 一次任务通常几分钟。

而真实世界里有一类需求:

"调研一下 X 领域的最新进展,读 200 篇论文,写一份带引用的综述。"

"把这个仓库从 Python 3.8 升级到 3.12,跑通所有测试。"

"监控这个系统一整夜,出问题自动分析并给出处理建议。"

这些任务的共同特点是:

复制代码
耗时:分钟级 → 小时级
步骤:几十 → 几百
工具:跨网络 / 跨沙箱 / 跨子代理
失败:中途必然发生(网络抖、模型抽风、租约过期、进程被 kill)

这时候,一个真正的长任务 Agent 和一个 Agent Demo 的区别才开始显现。

因此,这次我选择 DeerFlow 2.0

DeerFlow 是字节开源的 long-horizon SuperAgent harness,官方定位:

"An open-source long-horizon SuperAgent harness that researches, codes, and creates. With the help of sandboxes, memories, tools, skills, subagents and message gateway, it handles tasks that could take minutes to hours."

它 2026 年 2 月 28 日登上过 GitHub Trending 第 1,2.0 是一次 ground-up rewrite(注意:1.x 是 src/ 结构,2.0 是 backend/ + frontend/ 结构,本文只谈 2.0 的 main 分支)。

这也是它最值得学习的地方:

它不是在教你"怎么写一个 Agent",而是在展示"一个 Agent 系统怎么在长跑中不死"。


一、先不要看代码:DeerFlow 到底解决什么问题?

先想象一个最简单的长任务 Agent。

复制代码
用户:

"调研一下 RAG 的最新进展,写一份综述。"

最简单的实现:

复制代码
User
 ↓
LLM
 ↓
循环:调工具 / 写文件
 ↓
返回综述

但这根本不是 long-horizon Agent。

因为 Agent 必须真正面对:

复制代码
进程会死

网络会断

模型会抽风

租约会过期

子代理会卡住

任务会被用户取消

中途崩溃要能恢复

这意味着 Agent 必须拥有:

  • LLM
  • Tool
  • Sub-Agent
  • Sandbox
  • Memory
  • Run / Worker
  • RunStore(持久化)
  • Checkpoint(检查点)
  • Lease(租约)
  • Guardrail(护栏)
  • Observability(可观测)

DeerFlow 的价值就在这里。

它不是单纯让模型多转几圈,而是把模型放进一个能容忍失败的执行环境中。

官方 2.0 的设计哲学可以压缩成一句话:

长任务的本质不是"跑得快",而是"跑不死"。


二、先记住 DeerFlow 最重要的一张图

第一次看 DeerFlow,最容易迷路。

因为你会看到:

复制代码
harness
app
runtime
subagents
agents
sandbox
skills
guardrails
persistence
tracing
scheduler
gateway
channels

名字很多。

但实际上可以先压缩成两层:

复制代码
              ┌─────────────────────────────┐
              │         app(主机 / Host)     │
              │  gateway / channels /          │
              │  scheduler / mcp_tasks /       │
              │  subagent_batches             │
              └──────────────┬────────────────┘
                             │ 调用
                             ▼
              ┌─────────────────────────────┐
              │      harness(引擎 / Engine) │
              │  Agent / Sub-Agent / Run /   │
              │  Worker / RunStore / Memory / │
              │  Sandbox / Skills / Guardrail │
              └─────────────────────────────┘

也就是:

app 负责"把 Agent 接到各种入口"(HTTP、IM、定时任务、MCP),harness 负责"把 Agent 真正跑起来并跑不死"。

这是 DeerFlow 命名上最值得注意的一点:它管自己叫 harness(挽具 / 引擎框架),而不是 framework 或 platform

harness 这个词在 AI 工程里特指"包裹并持有 Agent 的那一层 "------它不替你决定业务,只负责让 Agent 在各种执行环境里稳定存活。对应的证据是 backend/langgraph.json

复制代码
{
  "graphs": {
    "lead_agent": "deerflow.agents:make_lead_agent"
  },
  "checkpointer": {
    "path": "./packages/harness/deerflow/runtime/checkpointer/async_provider.py:make_checkpointer"
  }
}

图的入口在 packages/harness/deerflow/agents,而 backend/app/ 下是 gateway(HTTP)、channels(IM)、scheduler(定时)、subagent_batchesmcp_tasks------这些全是"入口/主机"层,不碰 Agent 内核。

一句话:harness 是可复用的 Agent 引擎,app 是把它接入不同管道的宿主。这个边界,是你看懂 DeerFlow 的第一把钥匙。


三、第一个闪光点:DeerFlow 建在 LangGraph 上,而不是自己造轮子

这是我认为 DeerFlow 最值得学习的设计决策之一,也正好和 OpenHands 形成对照。

OpenHands 选择自建一套 Runtime + Event + State(它在 V1 里明确把状态、事件、运行时做成自己的原语)。

DeerFlow 的选择相反------它直接站在 LangGraph 肩上

复制代码
# agents/lead_agent/agent.py
from langchain.agents import create_agent
...
def _assemble_lead_agent(config, *, app_config):
    ...
    graph = create_agent(
        model=...,
        tools=final_tools,
        middleware=normalize_middleware_state_schemas(middlewares, mode),
        state_schema=get_thread_state_schema(mode),
        ...
    )

create_agent 是 LangChain 的新一代 Agent 原语(不是 langgraph.prebuilt 的 create_react_agent),它返回一个标准的 CompiledStateGraph

这意味着:

DeerFlow 没有重新发明"推理-行动循环",而是把 LangGraph 当作自己的"操作系统",然后在上面叠加 harness 层的能力。

为什么这个设计重要?

假设 OpenHands 要支持一个新模型,它得改自己的 Runtime;DeerFlow 要支持新模型,只要 LangGraph/LangChain 支持,它就自动支持------因为模型解析、checkpoint、streaming、human-in-the-loop 这些"Agent 基础设施"全部由 LangGraph 提供。

复制代码
LangGraph 负责:推理循环 / 状态图 / 检查点 / 流式 / HITL

DeerFlow 负责:Sub-Agent / Run / Worker / RunStore /
              Memory / Skills / Sandbox / Guardrail / 容错

这正是"不要重复造轮子"在 Agent 工程里的具体体现。但也带来代价:你如果想彻底理解 DeerFlow,必须先懂 LangGraph------这就是它学习曲线陡的原因。


四、第二个闪光点:middleware 层,而不是一个大 Agent 类

很多初学者写 Agent 时会把所有逻辑堆进一个类:

复制代码
class Agent:
    def run(self, input):
        # 澄清歧义
        # 过滤工具
        # 注入上下文
        # 清洗输入
        # 处理 LLM 错误
        # 写记忆
        ...

DeerFlow 则把这些都拆成 middleware(中间件) ,挂在 create_agent 外面:

复制代码
agents/middlewares/
├── clarification_middleware.py      # 模糊时反问
├── deferred_tool_filter_middleware.py  # 延迟加载工具
├── durable_context_middleware.py   # 持久上下文
├── dynamic_context_middleware.py   # 动态上下文
├── input_sanitization_middleware.py  # 输入清洗
└── llm_error_handling_middleware.py  # LLM 错误处理

每个 middleware 都是一个独立职责,通过 LangGraph 的 middleware 机制在图执行的特定切面插入逻辑。

这其实是一条非常重要的工程边界:

把"Agent 该做什么"和"Agent 执行前后要做什么"分开。

澄清、清洗、错误处理、上下文注入,这些都是"横切关注点",不该污染核心推理逻辑。middleware 模式让它们可独立测试、独立开关、独立组合。


五、第三个闪光点(核心):Run / Worker / RunStore ------ 把"长任务"当成一等公民

这是 DeerFlow 2.0 最值钱的设计,也是它和普通 Agent 框架最大的分野。

普通 Agent 框架里,一次执行就是一个函数调用。DeerFlow 则把一次执行建模成一个 Run

复制代码
# runtime/runs/manager.py
class RunRecord:
    run_id: str
    owner_worker_id: str | None = None      # 谁在跑
    lease_expires_at: str | None = None     # 租约何时过期
    ownership_lost: bool = False            # 所有权是否丢失
    status: RunStatus                       # pending/running/interrupted/...

注意这三个字段:owner_worker_idlease_expires_atownership_lost

它们共同构成了一个基于租约的所有权模型------这是分布式系统里处理"进程死亡"的经典手段,被 DeerFlow 用在了单机 Agent 执行上。

为什么需要租约?

想象一个场景:

复制代码
Worker A 正在跑一个 2 小时的任务。
Worker A 所在的 pod 突然被 k8s 杀掉。
Worker B 启动了。

如果没有租约,Worker B 不知道 A 跑的任务是不是还在跑、跑到哪了、要不要接管。

有了租约:

复制代码
Worker A 每隔 lease_seconds/3 续一次租约(heartbeat)。
Worker A 死了 → 租约过期 → Worker B 发现这个 run 的 owner 已经不可达
→ 触发孤儿恢复(orphan recovery)→ 重新 hydrate 这个 run → 继续跑。

代码证据(runtime/runs/manager.py):

复制代码
async def _heartbeat_loop(self) -> None:
    """Periodically renew leases and reclaim orphaned runs from dead peers.
    Lease renewal runs every lease_seconds / 3. Reconciliation
    (sweeping for expired leases owned by dead workers) runs every
    lease_seconds (every 3rd cycle) so orphaned runs are recovered
    without waiting for a pod restart.
    """
    lease_seconds = self._run_ownership_config.lease_seconds
    interval = max(1, lease_seconds // 3)
    ...
    if cycle % 3 == 0:
        self._schedule_orphan_reconciliation()

ORPHAN_RECOVERY_STOP_REASON = "orphan_recovered"LEASE_ORPHAN_RECOVERY_ERROR = "Run lease expired --- owning worker is unreachable." 这两个常量,把这个容错故事写在了代码里。

一句话:DeerFlow 把"长任务"当成一个需要被持久化、被租赁、被恢复的一等公民,而不是一个转瞬即逝的函数调用。这是它能跑"几分钟到几小时"的根本原因。


六、第四个闪光点(核心):Failure Recovery 四件套

如果说 RunStore 解决了"任务状态存哪",那下面这四件套解决了"任务中途挂了怎么办"。这是 DeerFlow 2.0 真正的护城河,也正好回应了你最初强调的那些 GitHub Issue:

1. 检查点回滚(Checkpoint Rollback)

用户取消任务时,不是简单中止,而是回滚到运行前的检查点

复制代码
# runtime/runs/worker.py
rollback_point: RollbackPoint | None = None
...
async def _finish_cancellation(self, action):
    if action == "rollback":
        checkpoint_rollback_completed = await _rollback_to_pre_run_checkpoint(
            rollback_point=rollback_point,
            ...
        )
    else:  # "interrupted"
        RunStatus.interrupted

_capture_rollback_point 会在运行前抓取"物化状态 + 原始待定 channel_values",让取消操作能 fork 出一条干净的 pre-run 谱系。这意味着:用户在任务跑了一半点取消,系统能恢复到"好像没跑过"的状态,而不是留下一堆半成品文件。

2. 中断状态(Interrupted State)

interrupted 不是 error,它是一个独立状态,专门为"被取消但可恢复"设计:

复制代码
# runtime/runs/store/memory.py
if run["status"] not in ("pending", "running", "interrupted"):
    ...  # 只有这三个状态允许被 rollback

RunStore 把 interrupted 纳入合法的状态机,让恢复路径和错误路径解耦。

3. 循环检测 / 预算护栏(Loop & Budget Guards)

这是最漂亮的一处设计。DeerFlow 把"Agent 卡死"建模成一组护栏中间件 ,每个护栏在 runtime.context 里写入一个 stop_reason

复制代码
# runtime/runs/worker.py
#   loop_detection      -> "loop_capped"
#   token_budget        -> "token_capped"
#   safety_finish_reason -> "safety_capped"
#   subagent_limit       -> "subagent_limit_capped"
#   model_length_finish_reason -> "model_length_capped"

也就是说,当 Agent 在重复同样动作(loop)、token 超预算、触发安全终止、子代理数超限、模型输出超长时,worker 会拿到一个明确的 stop_reason,而不是无限空转。这对长任务至关重要------一个卡住的 Agent 空转一小时,比直接失败更可怕

4. 孤儿恢复(Orphan Recovery)

前面第五节的 heartbeat + 租约过期检测,最终落到的就是孤儿恢复:当持有租约的 worker 失联,其他 worker 周期性扫描过期租约,把孤儿 run 接管回来继续跑。

汇总成一张表

机制 解决什么失败场景 实现位置
租约续期(heartbeat) worker 进程假死但还在 RunManager._renew_leases
孤儿恢复 worker 进程真死(pod 被 kill) RunManager._heartbeat_loop_schedule_orphan_reconciliation
检查点回滚 用户取消 / 运行前失败 RunWorker._rollback_to_pre_run_checkpoint
中断状态 取消但可恢复 vs 真错误 RunStore 状态机(含 interrupted
循环/预算护栏 Agent 卡死 / 超预算空转 guard middleware 写 stop_reason
Run 水合(hydration) 从持久化存储恢复内存状态 RunManager.hydrate run from store

这六件套合起来,就是 DeerFlow 敢说"撑几分钟到几小时"的底气。普通 Agent 框架缺的,正是这一整层。


七、第五个闪光点:Sub-Agent 子系统 ------ 委派、隔离与验收

长任务往往可以拆成子任务并行跑。DeerFlow 有一整套 Sub-Agent 子系统(subagents/):

复制代码
# subagents/executor.py
class SubagentExecutor:
    """Executor for running subagents."""
    def __init__(self, config, tools, ...,
                 acceptance_criteria=None,
                 loop_detection_recorder=None,
                 execution_capacity=None):

几个关键设计:

1. 隔离的事件循环

子代理跑在独立的 asyncio 事件循环上,避免父子共享事件循环导致的阻塞:

复制代码
def run_on_isolated_subagent_loop[T](coro) -> Future[T]: ...
def _get_isolated_subagent_loop() -> asyncio.AbstractEventLoop: ...

这意味着父 Agent 不会因为某个子代理的阻塞而卡死。

2. 执行容量准入(execution_capacity)

不是无限制派发子代理,而是有准入控制

复制代码
max_concurrent_subagents = effective_subagent_concurrency(...)
max_total_subagents = cfg.get("max_total_subagents", _default_max_total_subagents(...))

SubagentExecutionCapacity 在父 Agent 的 task tool 派发时共享,防止子代理爆炸式增长。

3. 验收检查(acceptance_checks)

这是 DeerFlow 特别务实的一点------子代理的结果不是"返回就完事",而是有验收标准

复制代码
# subagents/acceptance_checks.py(1396 行)
# 例如 "tests_passed:<command>" 这类验收叶节点,
# 必须锚定到具体的执行记录

子代理的 SubagentResult 里携带 tool_receiptsbash_executionstoken_usage------父 Agent 能据此判断子任务是否真的完成,而不是轻信子代理的"我搞定了"。

一句话:Sub-Agent 不是"甩锅给小弟",而是"委派 + 隔离 + 准入 + 验收"的完整协议。


八、第六个闪光点:DeerMem ------ 会"挑食"的持久记忆

DeerFlow 2.0 的记忆系统是可插拔的(memory.manager_class),默认后端是 DeerMem 。它最值得注意的设计是:不是什么都记,而是有严格的"事实门槛"

复制代码
# agents/memory/backends/deermem/deermem/core/updater.py
def _fact_scope_gate_reason(fact) -> str | None:
    """Return the deterministic rejection reason for a model-extracted fact."""
    if _normalize_gate_label(fact.get("scope")) != "user":
        return ...  # 只收"关于用户"的事实
    if _normalize_gate_label(fact.get("durability")) != "durable":
        return ...  # 只要"持久"的
    if _normalize_gate_label(fact.get("authority")) != "descriptive":
        return ...  # 只要"描述性"的,不要结论性的

也就是说,模型从对话里抽取事实时,DeerMem 只保留关于用户、持久、描述性的事实,自动丢弃临时信息、关于第三方的信息、或带结论的信息。

这背后的工程思考是:

记忆系统的核心难题不是"怎么存",而是"记什么"。 什么都记 = 噪声爆炸 + 上下文污染。DeerMem 用确定的 gate 规则把"记忆膨胀"挡在门外。

此外还有 debounce(防抖)、容量裁剪(select_facts_for_capacity)、来源置信度校准(_coerce_source_confidence)------这些都是生产级记忆系统才会考虑的细节,而不是 demo 里一行 memory.append()


九、第七个闪光点:Sandbox 与 Skills 的可插拔

DeerFlow 的 sandbox 抽象支持多 provider:

复制代码
sandbox/
├── local/          # 本地
├── env_policy.py   # 环境策略
├── lease.py        # 沙箱租约
├── security.py     # 安全
├── tools.py        # 沙箱工具(2663 行)
└── ...
community/
├── e2b_sandbox/    # E2B 云沙箱
└── aio_sandbox/    # AIO 沙箱

沙箱同样有租约 (注意 _release_run_scoped_referencesSANDBOX_SERVER_OWNED_CONTEXT_KEYS)------这说明 DeerFlow 把"资源生命周期"当成一个统一问题来治:Run 有租约、Sandbox 也有租约,死亡时都要能被回收,避免孤儿资源泄漏。

Skills 系统则以 SKILL.md 为包边界(skills.deferred_discovery 控制延迟发现),支持按需加载,避免把所有技能一股脑塞进上下文。


十、但是这里也暴露出一个很值得讨论的问题

DeerFlow 的容错体系非常强,但是:

强,意味着复杂。

现在 backend 有约 16 万行 Python,runtime/runs/worker.py 单文件 2895 行,manager.py 2337 行,sandbox/tools.py 2663 行。你第一次进入源码,很容易看到:

复制代码
RunManager
RunWorker
RunStore
LeaseRenewal
StatusFinalization
RunIdempotencyConflict
create_run_atomic
create_thread_operation_atomic
_subagent_release_policy
_sandbox_orphan_reconciliation
...

然后产生:

"我是来看 Agent 的,怎么在看分布式系统?"

这其实就是成熟工程项目的特点:

功能复杂度最终会变成架构复杂度。

所以赏析 DeerFlow 最忌讳:

"我把每个类看懂了。"

真正应该问的是:

复制代码
为什么 Run 需要租约?

为什么 interrupted 是独立状态?

为什么子代理要隔离事件循环?

为什么记忆要挑食?

为什么 sandbox 也要租约?

这些问题,每一个答案都指向"长任务必然失败"这个根本事实。


十一、DeerFlow 的第一个不足:配置与概念爆炸

如果你只是想做:

复制代码
问答 Agent

根本不需要:

复制代码
RunManager
Worker
RunStore
Lease
Middleware
SubAgent
DeerMem
Sandbox Provider
Guardrail
...

DeerFlow 的架构是因为:

它需要成为一个真正的 long-horizon SuperAgent harness。

所以这种复杂度是有原因的。

但对于个人项目或小团队:

很容易学到"架构长什么样",却不知道"为什么需要这么复杂"。

正确的学习方式是:

学习它背后的容错边界,而不是照搬所有组件。

比如你自己的 Repo Doctor 项目(博客第五阶段 36--50 篇),目前是单进程、同步跑、没有 RunStore。当你发现"任务跑到一半进程被 kill 就全没了"时,再引入 DeerFlow 式的租约 + 检查点,才是正解------而不是一开始就上全套。


十二、第二个不足:站在 LangGraph 肩上,也背上了 LangGraph 的包袱

因为 DeerFlow 的图是 create_agent 返回的 LangGraph,它的很多行为(checkpoint 格式、streaming 协议、HITL 接口)都受 LangGraph 版本约束。

CHANGELOG 里大量 breaking changes 都和这个绑定有关:

复制代码
- gateway: Request trace ids 现在无条件签发
- memory: storage_path 语义从"文件路径"变为"根目录"
- sandbox: E2B 现在强制 sandbox.replicas 为进程级容量上限
- config: checkpoint_delta_snapshot_frequency 迁移到嵌套键

这些变更本质上是在"LangGraph 内核 + DeerFlow harness"两层之间做演进,复杂度叠加。

所以这个不足其实是一体两面的:

用 LangGraph 省下了造轮子的成本,但也让自己永远跟着 LangGraph 的节奏走。


十三、和 LangGraph、OpenHands 放在一起看

这是这次项目赏析最重要的地方。三个项目分别提供了不同视角:

复制代码
LangGraph
= 怎么编排 Agent(有向图 / State / Node / Edge)

OpenHands
= Agent 怎么执行真实动作(自建 Runtime / Event / Sandbox)

DeerFlow
= 长任务 Agent 怎么"跑不死"(Run / Worker / RunStore / 容错)

三者不是竞争关系,而是三个不同层次:

复制代码
Workflow / Graph   (LangGraph 教你的)

        ↓

Agent Runtime      (OpenHands 教你的)

        ↓

Long-running Fault Tolerance  (DeerFlow 教你的)

这里有一个特别有意思的对照:

维度 LangGraph OpenHands DeerFlow
推理循环 自建 StateGraph 自建 reasoning-action loop create_agent(LangGraph)
执行环境 不关心(交给用户) 自建 Runtime + Sandbox 用 Sandbox Provider(E2B/AIO)
状态持久化 Checkpointer(标准) Event Stream(自建) RunStore + Checkpoint(自建+LangGraph)
长任务容错 基础(HITL/断点) 中等(Session 恢复) 重武器(租约/孤儿/回滚/护栏)
子代理 无(单 Agent 强) 一等公民(委派/验收/准入)
记忆 外接 外接 DeerMem 内置可插拔
适用场景 编排复杂 workflow 软件工程执行 长时研究/创作/编码

一句话总结三者差异:

LangGraph 给你图,OpenHands 给你手,DeerFlow 给你"长跑不死"的心脏。


十四、正确的阅读路线

我建议按这个顺序,不要从 frontend 开始:

复制代码
第一层  create_agent 怎么组装 Agent
        (agents/lead_agent/agent.py + agents/factory.py)

        ↓

第二层  Run / Worker / RunStore 怎么管理长任务
        (runtime/runs/)

        ↓

第三层  容错四件套:heartbeat / 回滚 / 中断 / 护栏
        (manager.py 的 _heartbeat_loop + worker.py 的 _finish_cancellation)

        ↓

第四层  Sub-Agent 怎么委派与验收
        (subagents/executor.py + acceptance_checks.py)

        ↓

第五层  DeerMem 怎么记、怎么挑
        (agents/memory/backends/deermem/)

        ↓

第六层  Sandbox / Skills / Guardrail 怎么插拔
        (sandbox/ + skills/ + guardrails/)

        ↓

第七层  app 怎么把 harness 接到入口
        (backend/app/ 的 gateway / channels / scheduler)

不要:

复制代码
从 frontend 开始

否则很快迷路。


十五、这个项目真正让我学到的三个工程原则

如果整篇文章只留下三句话,我会留下这三个。

第一:长任务的本质是"容错",不是"智能"

复制代码
普通 Agent  = 模型够强就行
长任务 Agent = 模型强 + 跑不死

让 Agent 在进程死亡、网络抖动、用户取消、模型抽风时还能恢复,比让模型多答对一道题重要一百倍。


第二:把"任务"建模成可租赁、可恢复的对象

复制代码
Run  = 一等公民
租约  = 进程死亡的检测器
孤儿恢复 = 死亡后的接管者
检查点 = 取消时的后悔药

owner_worker_id + lease_expires_at + ownership_lost 这仨字段,比任何"Agent 怎么思考"的论文都实在。


第三:记忆的核心是"记什么",不是"怎么存"

复制代码
什么都记  = 噪声爆炸
只记 user/durable/descriptive = DeerMem 的 gate

DeerMem 的 _fact_scope_gate_reason 用确定规则把记忆膨胀挡在门外,这比 RAG 向量库的"全存"高级得多。


十六、如果让我给 DeerFlow 2.0 做一次工程评价

我不会简单地说:

"DeerFlow 很牛。"

而是:

维度 评价 说明
Run / Worker 抽象 ★★★★★ 长任务一等公民,业界少见
Failure Recovery ★★★★★ 租约/孤儿/回滚/护栏六件套
Sub-Agent 系统 ★★★★★ 委派+隔离+准入+验收完整
Memory(DeerMem) ★★★★★ 会挑食的可插拔记忆
站在 LangGraph 上 ★★★★☆ 省力但绑定内核版本
Sandbox 插拔 ★★★★☆ E2B/AIO/local 多 provider
初学者友好度 ★★☆☆☆ 16 万行,概念爆炸
源码学习成本 ★★☆☆☆ 必须先懂 LangGraph
小项目适用性 ★★☆☆☆ 杀鸡用牛刀
工程参考价值 ★★★★★ 长任务 Agent 的范本

它最大的优点:

把 Agent 从"一个能转圈的 LLM"提升成了"一个能长跑、会自愈的执行系统"。

它最大的缺点:

对于小型项目来说,架构和认知成本都偏高。


十七、不要抄 DeerFlow,要学 DeerFlow

这是这次项目赏析最重要的结论。

你完全没必要马上把自己的项目变成:

复制代码
RunManager
RunWorker
RunStore
Lease
SubAgent
DeerMem
SandboxProvider
Guardrail

如果你的项目只有:

复制代码
一个 Agent
三个 Tool
跑一次就结束

你可能只需要:

复制代码
Agent
 ↓
Tool Registry
 ↓
Checkpointer

等问题真的出现:

复制代码
进程会死
任务会卡
用户会取消
要并行子任务
记忆会膨胀

再逐步增加:

复制代码
Run / Worker
RunStore
Lease / Orphan Recovery
Sub-Agent
Memory Gating

这才是真正的工程演进。


十八、把 DeerFlow 映射回你自己的学习体系

现在你可以把之前学习的东西重新串起来。

复制代码
LangGraph
    ↓
Workflow / State / Graph

OpenHands
    ↓
Agent / Runtime / Event / Sandbox

DeerFlow
    ↓
Run / Worker / RunStore / Fault Tolerance / Sub-Agent / Memory

你的 AI Engineering OS
    ↓
Knowledge / Rules / Agent / Project / Review

这三个项目分别提供了不同视角:

复制代码
LangGraph  = 怎么编排 Agent
OpenHands  = Agent 怎么执行真实任务
DeerFlow   = 长任务 Agent 怎么跑不死

这时候你学习 Agent 的视角已经不再是:

"这个框架 API 怎么用?"

而变成:

"一个 Agent 系统到底要扛住哪些失败?"

这是非常大的提升。


十九、最终总结

DeerFlow 2.0 最值得赏析的,并不是它用了什么模型,也不是它有多少 Tool。

真正值得学习的是它背后的架构思想:

复制代码
Harness
负责把 Agent 跑起来并跑不死

Run / Worker
负责把长任务当成可租赁、可恢复的对象

RunStore / Checkpoint
负责状态持久化与回滚

Lease / Orphan Recovery
负责进程死亡后的接管

Loop / Budget Guards
负责 Agent 卡死时的熔断

Sub-Agent
负责把大任务拆成可委派、可验收的小任务

DeerMem
负责"记什么"而非"怎么存"

Sandbox / Skills
负责能力与环境的隔离与插拔

然后形成:

复制代码
提交任务
   ↓
Run 被租赁给某个 Worker
   ↓
Agent 在 Checkpoint 保护下推理-行动
   ↓
必要时委派 Sub-Agent(隔离 + 验收)
   ↓
失败?→ 租约过期触发孤儿恢复 / 取消触发检查点回滚 / 卡死触发护栏熔断
   ↓
成功 → 结果交付 + 记忆更新

这才是一个真正 long-horizon Agent 的基本生命循环。

而它暴露出的不足也同样值得学习:

系统越成熟,抽象越多;抽象越多,学习和维护成本也越高。

所以真正优秀的 Agent 工程不是:

"把 DeerFlow 全部搬过来。"

而是:

只在"长跑失败"的问题真正出现时,引入对应的容错机制。


这次项目赏析,我建议你最终记住这张图

复制代码
                    ┌──────────────────────────────┐
                    │           User / 入口          │
                    │  gateway / channels / scheduler │
                    └───────────────┬───────────────┘
                                    │
                                    ▼
                    ┌──────────────────────────────┐
                    │     app(宿主 / Host)          │
                    └───────────────┬──────────────┘
                                    │ 调用
                                    ▼
                    ┌──────────────────────────────┐
                    │   harness(引擎 / Engine)       │
                    │                                │
                    │   Agent(create_agent)         │
                    │      │ middleware 层            │
                    │      ▼                         │
                    │   Run → Worker(租约持有者)     │
                    │      │                         │
                    │      ├── RunStore(持久化)      │
                    │      ├── Checkpoint(回滚点)    │
                    │      ├── Heartbeat(租约续期)   │
                    │      ├── Orphan Recovery        │
                    │      ├── Loop/Budget Guards     │
                    │      ▼                         │
                    │   Sub-Agent(隔离+验收)         │
                    │      ▼                         │
                    │   Sandbox / Skills / Memory     │
                    │      ▼                         │
                    │   Guardrail(护栏)             │
                    └──────────────────────────────┘

如果你能把这张图真正理解,而不是背下来,这次 DeerFlow 2.0 源码赏析就已经达到了目的。

下一次继续赏析项目时,我建议看 Hermes Agent------它和 DeerFlow 正好形成一组对照:

复制代码
DeerFlow  → 长任务 SuperAgent(Runtime / Orchestration / Fault Tolerance)
Hermes    → 持久陪伴 + 自我进化 Agent(Memory / Skills / Learning Loop)

一个偏"任务怎么被执行得稳",一个偏"Agent 怎么随用户成长"。两块拼起来,你对 Agent 形态的理解就完整了。

相关推荐
Haooog1 小时前
Agent 开发中的 Memory:State、短期记忆、长期记忆与 Memory Retrieval
java·agent·memory
重生之我来学Python1 小时前
Docker套装的简介、安装、超级详细教程
linux·docker·容器·eureka·github
多学一分钟2 小时前
讲清 Agent:闭环、工具调用、记忆,以及 MCP 和 A2A
agent
每天都是不一样的太阳2 小时前
别让 AI Agent 先画靶再射箭:一套「结论忠于数据」的证据链工作流
agent·工作流引擎
静开2 小时前
模型没换、提示词没动,成功率从不到 70% 干到 95% —— 改的到底是什么
agent
掰头战士2 小时前
从LLM到Agent、Agent的6大核心。这些基础知识你还记得吗
node.js·llm·agent
甜辣uu2 小时前
智能体Agent性能优化从原理到实战
人工智能·性能优化·大模型·llm·agent·rag·智能体
一 铭2 小时前
软件诞生于 Commit 之间:聊聊 Zed 的 DeltaDB
人工智能·ai·agent
粥里有勺糖3 小时前
视野修炼-技术周刊第132期 | 一些有趣的组件
前端·github·aigc