断点续跑机制:ThreadState 唯一可信源 + 双模式持久化的状态管理

系列第 6 篇 / 共 7 篇。上一篇拆解了 Sandbox 三层抽象架构,本文深入 DeerFlow 的状态管理基石——断点续跑机制。


一、长时任务的三大核心难题

分布式 AI Agent 编排中,长时任务(分钟到小时级)面临三个核心痛点:

状态碎片化:主 Agent 的状态、多个子 Agent 的执行进度、沙箱文件系统状态散落在不同组件里。服务重启后,没法从一个地方完整恢复所有状态。

持久化逻辑冗余:旧版自研了多套存储类(SQLiteCheckpointSaverPostgresCheckpointSaver),与 LangGraph 原生 Checkpointer 协议存在隐式差异。升级 LangGraph 版本时兼容性风险高。

多节点快照冲突:子 Agent 独立做断点快照时,可能与主线程快照产生时间差——主线程已保存新状态,子 Agent 快照却基于旧状态,恢复时数据不一致。

DeerFlow 2.0 的答案是一套四位一体设计:LangGraph 原生 Checkpointer + ThreadState 统一持久化 + SubagentExecutor 后台任务状态同步 + 同步/异步双模式持久化。


二、五层分层架构

统一持久化层 (双模式)

async_provider.py (异步)

provider.py (同步)

后端: InMemorySaver / SqliteSaver / PostgresSaver

子代理执行层

SubagentExecutor._aexecute / execute

_background_tasks 全局状态存储

LangGraph 编排层

StateSnapshot 全量序列化

Super-step 自动快照点

next_node 精准续跑路由

Runtime 调度层

RunWorker
续跑调度 + checkpointer 双模式入口

应用层 API

/threads/thread_id/resume

/tasks/task_id/status

从上到下形成"接入 → 调度 → 编排 → 执行 → 持久化"的完整闭环。上层只关心"续跑 / 查询",中间层负责"状态路由与恢复",下层负责"执行与存储"。


三、四大核心模型

3.1 ThreadState:主线程唯一可信源

定位:整个系统唯一可信状态源,断点快照的核心载体。所有需要持久化的状态全部收敛于此——主代理状态、子代理进度、沙箱配置、文件路径、产出物列表。

续跑逻辑:加载 ThreadState 的最新快照 → 反序列化 → 恢复全部上下文环境。不存在任何碎片化状态需要从多个地方拼凑。

路径:deerflow/agents/thread_state.py

3.2 SubagentResult:子代理唯一状态载体

定位:封装子代理从启动到结束的全生命周期信息。包括 task_idtrace_idstatuserrorcompleted_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"  # 超时

状态流转不可逆:

PENDING

RUNNING

COMPLETED

FAILED

CANCELLED

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 搬运

task_tool 轮询同步

RunWorker + save_checkpoint

SubagentResult
子代理运行时实时更新

_background_tasks
内存临时中转, 线程安全

ThreadState
主线程唯一可信状态源

checkpointer 持久化
memory / SQLite / PostgreSQL

result_holder 是 SubagentResult 的"搬运工",SubagentResult 是 result_holder 搬运的"货物"。 二者协作完成子代理状态"生成 → 同步 → 持久化"的全链路。

这样设计的核心收益:

  1. 状态一致性:所有状态通过 ThreadState 统一快照,不存在子代理快照与主线程快照的时间差问题
  2. 存储精简:不需要为每个子代理维护独立快照,避免存储冗余
  3. 续跑简洁:只需恢复 ThreadState 即可同步所有子代理最新状态,无需单独恢复

五、双模式持久化深度拆解

DeerFlow 2.0 彻底移除了自研的 SQLiteCheckpointSaverPostgresCheckpointSaver,持久化能力完全由 async_provider.py(异步)和 provider.py(同步)提供。

模式 核心文件 核心入口 适用场景 后端
异步 async_provider.py make_checkpointer() FastAPI/ASGI 服务、长时异步 AsyncSqliteSaver / AsyncPostgresSaver
同步 provider.py get_checkpointer() / checkpointer_context() CLI、单元测试、短生命周期 SqliteSaver / PostgresSaver

FastAPI/ASGI
长时异步任务

CLI/单元测试
短生命周期

同步模式 (provider.py)

get_checkpointer()
单例复用

_sync_checkpointer_cm(config)
同步后端调度器

SqliteSaver /
PostgresSaver

异步模式 (async_provider.py)

make_checkpointer()
无参数, 自动读配置

_async_checkpointer(config)
异步后端调度器

AsyncSqliteSaver /
AsyncPostgresSaver

config.yaml
checkpointer.type

异步场景

同步场景

两种模式共享相同的三层架构

接口层(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.pyprovider.py 封装,配置驱动后端切换。生态对齐的价值:减少重复开发 + 兼容性自动跟随 LangGraph 升级。

6.5 CheckpointMiddleware 彻底移除

断点快照职责从中间件完全剥离到 RunWorker。这是单一职责原则的深度实践:

  • Middleware:流程拦截、校验、增强
  • RunWorker:任务调度 + 快照触发
  • checkpointer:持久化存储

七、断点续跑完整流程

执行 + 快照流程

checkpointer ThreadState _background_tasks SubagentExecutor Lead Agent RunWorker 用户 checkpointer ThreadState _background_tasks SubagentExecutor Lead Agent RunWorker 用户 发起任务请求 开始执行 创建子 Agent SubagentResult 实时同步 _aexecute() 执行 task_tool 轮询同步状态 Super-step 触发 save_checkpoint ThreadState 全量序列化 持久化完成
  1. 用户发起任务 → RunWorker 开始执行
  2. Lead Agent 创建子 Agent → SubagentExecutor 启动 → SubagentResult 实时更新 → 同步到 _background_tasks
  3. task_tool 轮询获取子代理状态 → 同步到 ThreadState
  4. LangGraph Super-step 自动触发快照点 → RunWorker 调用 save_checkpoint
  5. checkpointer 将 ThreadState 全量序列化持久化

续跑流程

SubagentExecutor ThreadState checkpointer RunWorker API Layer SubagentExecutor ThreadState checkpointer RunWorker API Layer /threads/thread_id/resume 加载最新快照 ThreadState 序列化数据 反序列化恢复 主代理 + 子代理进度 + 沙箱环境 next_node 精准续跑路由 检查子代理状态 COMPLETED 跳过 RUNNING/FAILED 按策略重试 续跑完成
  1. 服务重启 → API 调 /threads/{thread_id}/resume
  2. RunWorker 通过 make_checkpointer() / get_checkpointer() 加载最新快照
  3. ThreadState 反序列化 → 恢复主代理状态 + 所有子代理进度 + 沙箱环境
  4. next_node 精准续跑路由 → 从上次中断的节点继续
  5. 子代理状态检查(COMPLETED 跳过,RUNNING/FAILED 按策略重启)

八、架构思维总结

从架构思维高度看,DeerFlow 2.0 断点续跑机制的重构遵循三条核心原则:

1. 状态收敛(单一可信源)。 ThreadState 是唯一快照载体。不存在碎片化状态。续跑只需恢复一个对象。这条原则是整套机制稳定性的基石。

2. 解耦分层(单一职责)。 中间件专注流程增强 → RunWorker 负责调度与快照 → checkpointer 处理持久化。三者不越界、不耦合。旧版 CheckpointMiddleware 的臃肿是反面教材,2.0 的职责拆分是正面典范。

3. 生态对齐(复用而非自研)。 放弃自研存储类,对齐 LangGraph 原生 Checkpointer 协议。双模式(异步 + 同步)适配不同场景,配置驱动屏蔽底层差异。生态协同优于重复造轮——LangGraph 升级,DeerFlow 自动受益。

整套重构后的架构,是"工程化落地与架构设计美感"的统一——既满足了生产级长时任务的可靠性需求,又保留了灵活可扩展的架构骨架。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐