跳转到内容

框架独立架构

学习目标

理解 CrewAI 为什么选择脱离 LangChain 独立构建,以及其 Monorepo 结构如何实现各子系统的解耦。


项目实践

Monorepo 结构

CrewAI 使用 uv workspace 管理多个子包:

lib/
├── crewai/ # 主框架(Agent、Crew、Flow、事件、遥测)
├── crewai-core/ # 核心提供者(内容处理、人工输入)
├── crewai-tools/ # 工具库(独立发布)
├── crewai-files/ # 文件处理模块(独立发布)
├── cli/ # CLI 工具(crewai-cli)
└── devtools/ # 开发工具

pyproject.toml无 langchain/langgraph 依赖,核心依赖仅为 Pydantic v2、HTTP 客户端和各 LLM 提供商的 SDK。

Protocol 抽象层

各子系统之间通过 Python Protocol 实现接口抽象:

子系统Protocol作用
存储StorageBackend统一向量存储接口(LanceDB/Qdrant)
RAGBaseClient统一向量数据库客户端(ChromaDB/Qdrant)
知识BaseKnowledgeStorage统一知识存储接口
持久化FlowPersistence统一 Flow 持久化接口(SQLite/内存)
检查点BaseProvider统一检查点存储接口(JSON/SQLite)

零依赖的设计考量

脱离 LangChain 的原因(从代码中可以推断):

  • 传递依赖膨胀:LangChain 的依赖链导致启动延迟和版本锁定
  • 控制力:独立构建意味着可以针对 Agent 场景优化,不受通用框架的约束
  • 版本自由:不需要跟随 LangChain 的发布节奏

替代方案分析

方案优势代价
零依赖无传递依赖、启动快、版本可控需要自己实现每个子系统
基于 LangChain快速开发、生态丰富依赖膨胀、启动慢、版本锁定

CrewAI 选择零依赖,意味着每个子系统(LLM/Tools/Memory/Events)都需要自己实现,但换来了完全的控制权和更低的运行时开销。


问题与规避

子系统之间的版本同步

  • Monorepo 中各子包独立发布,版本可能不同步
  • 对策:uv workspace 锁定子包版本,uv sync 确保一致性

LangGraph 适配器的依赖

  • LangGraphAgentAdapter 需要 langgraph 作为可选依赖
  • 对策:langgraph 不在核心依赖中,仅在需要使用适配器时安装

设计取舍

Monorepo vs 单包

  • Monorepo 允许独立发布子包(如 crewai-tools 可单独安装),减少不需要某些功能的用户负担
  • 代价是构建和测试复杂度增加,需要管理多个包的发布流程

参考来源

  • 源码验证: pyproject.toml — 核心依赖列表
  • 源码验证: lib/ 目录结构 — Monorepo 布局