DeerFlow2.0 框架架构06:断点续跑机制
断点续跑机制:ThreadState 唯一可信源 + 双模式持久化的状态管理
系列第 6 篇 / 共 7 篇。上一篇拆解了 Sandbox 三层抽象架构,本文深入 DeerFlow 的状态管理基石——断点续跑机制。
一、长时任务的三大核心难题
分布式 AI Agent 编排中,长时任务(分钟到小时级)面临三个核心痛点:
状态碎片化:主 Agent 的状态、多个子 Agent 的执行进度、沙箱文件系统状态散落在不同组件里。服务重启后,没法从一个地方完整恢复所有状态。
持久化逻辑冗余:旧版自研了多套存储类(SQLiteCheckpointSaver、PostgresCheckpointSaver),与 LangGraph 原生 Checkpointer 协议存在隐式差异。升级 LangGraph 版本时兼容性风险高。
多节点快照冲突:子 Agent 独立做断点快照时,可能与主线程快照产生时间差——主线程已保存新状态,子 Agent 快照却基于旧状态,恢复时数据不一致。
DeerFlow 2.0 的答案是一套四位一体设计:LangGraph 原生 Checkpointer + ThreadState 统一持久化 + SubagentExecutor 后台任务状态同步 + 同步/异步双模式持久化。
二、五层分层架构
从上到下形成"接入 → 调度 → 编排 → 执行 → 持久化"的完整闭环。上层只关心"续跑 / 查询",中间层负责"状态路由与恢复",下层负责"执行与存储"。
三、四大核心模型
3.1 ThreadState:主线程唯一可信源
定位:整个系统唯一可信状态源,断点快照的核心载体。所有需要持久化的状态全部收敛于此——主代理状态、子代理进度、沙箱配置、文件路径、产出物列表。
续跑逻辑:加载 ThreadState 的最新快照 → 反序列化 → 恢复全部上下文环境。不存在任何碎片化状态需要从多个地方拼凑。
路径:deerflow/agents/thread_state.py
3.2 SubagentResult:子代理唯一状态载体
定位:封装子代理从启动到结束的全生命周期信息。包括 task_id、trace_id、status、error、completed_at 等。
核心设计:子代理无独立断点。 子代理状态通过 result_holder 对象实时同步到 _background_tasks,再由 task_tool 同步至 ThreadState,最终由 RunWorker 统一触发快照。
路径:deerflow/subagents/executor.py
3.3 SubagentStatus:六状态枚举
class SubagentStatus(Enum):
PENDING = "pending" # 待执行
RUNNING = "running" # 执行中
COMPLETED = "completed" # 完成
FAILED = "failed" # 失败
CANCELLED = "cancelled" # 取消(2026年4月新增)
TIMED_OUT = "timed_out" # 超时
状态流转不可逆:
续跑时的判断逻辑:RUNNING/CANCELLED/FAILED 状态可按策略决定是否重启;COMPLETED 无重复执行。
3.4 _background_tasks:线程安全的内存中转
_background_tasks: dict[str, SubagentResult] = {} # task_id → SubagentResult
_background_tasks_lock = threading.Lock() # 多子代理状态竞争保护
子代理运行时的状态实时存在这里,最终同步至 ThreadState 由 checkpointer 持久化。它和 ThreadState 的关系是"临时中转 → 持久化存储"。
四、核心设计:子代理无独立断点
这是 DeerFlow 2.0 断点续跑机制最关键的架构决策。完整的状态流转链路:
result_holder 是 SubagentResult 的"搬运工",SubagentResult 是 result_holder 搬运的"货物"。 二者协作完成子代理状态"生成 → 同步 → 持久化"的全链路。
这样设计的核心收益:
- 状态一致性:所有状态通过 ThreadState 统一快照,不存在子代理快照与主线程快照的时间差问题
- 存储精简:不需要为每个子代理维护独立快照,避免存储冗余
- 续跑简洁:只需恢复 ThreadState 即可同步所有子代理最新状态,无需单独恢复
五、双模式持久化深度拆解
DeerFlow 2.0 彻底移除了自研的 SQLiteCheckpointSaver 和 PostgresCheckpointSaver,持久化能力完全由 async_provider.py(异步)和 provider.py(同步)提供。
| 模式 | 核心文件 | 核心入口 | 适用场景 | 后端 |
|---|---|---|---|---|
| 异步 | async_provider.py | make_checkpointer() |
FastAPI/ASGI 服务、长时异步 | AsyncSqliteSaver / AsyncPostgresSaver |
| 同步 | provider.py | get_checkpointer() / checkpointer_context() |
CLI、单元测试、短生命周期 | SqliteSaver / PostgresSaver |
两种模式共享相同的三层架构:
接口层(Public API):对外提供统一入口,屏蔽底层差异。异步用 make_checkpointer()(无参数,自动读配置,返回 AsyncIterator[Checkpointer]),同步用 get_checkpointer()(单例复用)。
策略层(Backend Dispatcher):核心调度器,根据配置选择后端。异步用 _async_checkpointer(config),同步用 _sync_checkpointer_cm(config)。
依赖层(External Integrations):集成 LangGraph 原生后端,桥接 DeerFlow 配置体系。不包含任何自研存储类。
配置驱动,一行切换
# config.yaml
checkpointer:
enabled: true
type: sqlite # memory(默认)| sqlite | postgres
path: ./deerflow.db # 仅 sqlite
connection_string: "postgresql://user:pass@pg:5432/deerflow" # 仅 postgres
cleanup:
enabled: true
retain_days: 7
max_versions: 20
配置为空时自动降级为 InMemorySaver,保障基础功能。配置错误时抛出带安装指引的友好错误(如缺失 PostgreSQL 依赖时提示 pip install deerflow[postgres])。
六、旧版类为何被移除:重构的架构思维
DeerFlow 2.0(2026 年 4 月)做了一次彻底的架构重构。多个旧版核心类被移除:
6.1 SubagentState → SubagentResult
旧版 SubagentState 与主线程的状态结构存在字段重叠、数据冗余。改为 SubagentResult 单一结构,状态全部收敛到 _background_tasks,最终同步至 ThreadState。子代理不再维护独立状态对象。
6.2 _aexecute_with_checkpoint 移除
旧版子代理有独立的 _aexecute_with_checkpoint 方法做快照。2.0 中完全移除——子代理不单独做断点快照,统一由 RunWorker 负责保存全量状态。避免了多节点快照导致的不一致。
6.3 ResumeService → 并入 RunWorker
旧版有独立的 ResumeService 处理续跑逻辑,与 RunWorker 职责重叠。2.0 中将续跑逻辑全部并入 RunWorker,完全基于 LangGraph 原生的 get_tuple() / put() 接口实现,无需自研续跑代码。
6.4 SQLiteCheckpointSaver / PostgresCheckpointSaver 移除
放弃自研存储类,直接复用 LangGraph 原生实现。通过 async_provider.py 和 provider.py 封装,配置驱动后端切换。生态对齐的价值:减少重复开发 + 兼容性自动跟随 LangGraph 升级。
6.5 CheckpointMiddleware 彻底移除
断点快照职责从中间件完全剥离到 RunWorker。这是单一职责原则的深度实践:
- Middleware:流程拦截、校验、增强
- RunWorker:任务调度 + 快照触发
- checkpointer:持久化存储
七、断点续跑完整流程
执行 + 快照流程
- 用户发起任务 → RunWorker 开始执行
- Lead Agent 创建子 Agent → SubagentExecutor 启动 → SubagentResult 实时更新 → 同步到
_background_tasks task_tool轮询获取子代理状态 → 同步到 ThreadState- LangGraph Super-step 自动触发快照点 → RunWorker 调用
save_checkpoint - checkpointer 将 ThreadState 全量序列化持久化
续跑流程
- 服务重启 → API 调
/threads/{thread_id}/resume - RunWorker 通过
make_checkpointer()/get_checkpointer()加载最新快照 - ThreadState 反序列化 → 恢复主代理状态 + 所有子代理进度 + 沙箱环境
next_node精准续跑路由 → 从上次中断的节点继续- 子代理状态检查(COMPLETED 跳过,RUNNING/FAILED 按策略重启)
八、架构思维总结
从架构思维高度看,DeerFlow 2.0 断点续跑机制的重构遵循三条核心原则:
1. 状态收敛(单一可信源)。 ThreadState 是唯一快照载体。不存在碎片化状态。续跑只需恢复一个对象。这条原则是整套机制稳定性的基石。
2. 解耦分层(单一职责)。 中间件专注流程增强 → RunWorker 负责调度与快照 → checkpointer 处理持久化。三者不越界、不耦合。旧版 CheckpointMiddleware 的臃肿是反面教材,2.0 的职责拆分是正面典范。
3. 生态对齐(复用而非自研)。 放弃自研存储类,对齐 LangGraph 原生 Checkpointer 协议。双模式(异步 + 同步)适配不同场景,配置驱动屏蔽底层差异。生态协同优于重复造轮——LangGraph 升级,DeerFlow 自动受益。
整套重构后的架构,是"工程化落地与架构设计美感"的统一——既满足了生产级长时任务的可靠性需求,又保留了灵活可扩展的架构骨架。
更多推荐



所有评论(0)