跳转到内容

检查点与分支谱系

学习目标

理解 CrewAI 的检查点系统如何实现事件驱动触发、JSON/SQLite 双后端存储、分支谱系追踪和版本迁移。


项目实践

RuntimeState 运行时状态

RuntimeState(RootModel) 管理所有活动实体:

  • _provider: BaseProvider — 检查点存储后端
  • _event_record: EventRecord — 事件记录图
  • 谱系追踪:_checkpoint_id_parent_id_branch
  • 方法:checkpoint()acheckpoint()fork()from_checkpoint()afrom_checkpoint()
  • 基于版本的迁移系统(_migrate())用于向后兼容

EventRecord 事件记录图

EventNode 包装事件,带有类型边(parent/child/trigger/triggered_by/next/previous/started/completed_by)。

EventRecord 提供:

  • O(1) 节点查找
  • BFS 后代遍历
  • 根节点查找
  • 通过 RWLock 实现线程安全

CheckpointConfig

# 伪代码
CheckpointConfig(
location="./.checkpoints",
on_events=["task_completed", "crew_finished", ...], # 100+ 事件类型
provider=JsonProvider() | SqliteProvider(),
max_checkpoints=100, # 修剪上限
restore_from="checkpoint_id", # 从检查点恢复
)

JSON Provider

文件系统 JSON 存储:

  • 文件名格式:{ts}_{uuid8}_p-{parent}.json 位于 location/branch/
  • 分支目录验证防止路径逃逸
  • 按文件修改时间修剪
  • 通过 aiofiles 实现异步支持

SQLite Provider

SQLite 存储:

  • 表结构:checkpoints(id TEXT PRIMARY KEY, created_at TEXT, parent_id TEXT, branch TEXT, data JSONB)
  • WAL 日志模式支持并发读取
  • 位置格式:db_path#checkpoint_id
  • 通过 rowid 排序修剪

CheckpointListener

  • 延迟处理程序注册(仅在第一个 CheckpointConfig 解析时)
  • _find_checkpoint() 遍历关系链:Task → Agent → Crew
  • _do_checkpoint() 序列化状态、通过 provider 写入、发射事件
  • 每次写入后修剪(如果配置了 max_checkpoints

问题与规避

max_checkpoints 修剪可能删除需要的历史

  • 修剪策略基于文件修改时间或 rowid,可能删除你需要回退的检查点
  • 对策:对需要保留的检查点使用 restore_from 明确引用,或设置更大的 max_checkpoints

分支目录路径逃逸

  • 如果 branch 名称包含 ..,可能写入到非预期目录
  • 对策:JSON Provider 的分支目录验证拒绝包含 .. 的路径

版本迁移的兼容性

  • 旧版本检查点的序列化格式可能与新版本不兼容
  • 对策:_migrate() 方法在从旧检查点恢复时自动执行格式转换

设计取舍

JSON vs SQLite 双后端

维度JSONSQLite
可读性高(纯文本)低(需要工具查询)
查询能力优(SQL)
并发中等(文件锁)高(WAL 模式)
适用场景调试、审计生产、频繁读写

CrewAI 同时支持两种后端,用户根据场景选择。

事件驱动触发 vs 定时触发

  • 事件驱动:在特定事件(如 task_completed)时触发检查点
  • 优势:精确控制何时保存,避免不必要的检查点
  • 代价:需要在 CheckpointConfig 中显式声明 100+ 事件类型

参考来源

  • 源码验证: lib/crewai/src/crewai/state/runtime.py
  • 源码验证: lib/crewai/src/crewai/state/checkpoint_config.py
  • 源码验证: lib/crewai/src/crewai/state/provider/json_provider.py
  • 源码验证: lib/crewai/src/crewai/state/provider/sqlite_provider.py