Monorepo 多包工程实践
Monorepo 多包工程实践
学习目标
本章要解决什么问题:AutoGen 如何在一个仓库中管理多个独立 Python 包的构建、测试和发布。你将学到:
- uv + pyproject.toml 的 monorepo 配置模式
- 跨包依赖的管理方法
shared_tasks.toml共享构建配置- 包拆分策略与发布顺序
项目实践
包结构与独立版本
AutoGen 的 python/packages/ 下包含 9 个独立包:
python/├── pyproject.toml # 根级 uv 工作区配置├── uv.lock # 锁定所有依赖版本├── shared_tasks.toml # 共享 Ruff/pytest 配置└── packages/ ├── autogen-core/ # v0.7.5 ├── autogen-agentchat/ # v0.7.5 ├── autogen-ext/ # v0.7.5 ├── autogen-studio/ # 独立版本 ├── agbench/ # 独立版本 ├── autogen-magentic-one/ ├── magentic-one-cli/ ├── autogen-test-utils/ └── pyautogen/ # v0.2 向后兼容每个包有独立的 pyproject.toml:
[project]name = "autogen-agentchat"version = "0.7.5"dependencies = [ "autogen-core==0.7.5", # 依赖同版本 core]uv 工作区模式
根级 pyproject.toml 定义了工作区:
[tool.uv.workspace]members = ["packages/*"]优势:
- 所有包共享一个虚拟环境,无需手动管理依赖
uv sync一次性解析所有包的依赖图uv run pytest在工作区根目录即可运行所有包的测试
shared_tasks.toml
AutoGen 使用 shared_tasks.toml 共享构建配置:
[tool.ruff]target-version = "py310"line-length = 120
[tool.pytest.ini_options]minversion = "6.0"testpaths = ["tests"]各包的 pyproject.toml 引入共享配置:
# 继承共享任务配置[tool.ruff]extend = "../shared_tasks.toml"
[tool.pytest.ini_options]extend = "../shared_tasks.toml"为什么用 extend 而非 include? extend 允许每个包在共享配置基础上添加自己的覆盖,而 include 是硬引用不允许覆盖。
跨包依赖管理
AgentChat 依赖 Core,Extensions 依赖 Core:
autogen-agentchat → autogen-coreautogen-ext → autogen-coreautogen-studio → autogen-agentchat, autogen-ext在 uv 工作区中,跨包引用使用相对路径:
[project]dependencies = [ "autogen-core", # uv 自动解析为工作区内的本地包]uv 检测到工作区内同名的本地包,优先使用本地路径而非 PyPI 版本。这确保了开发时使用本地代码,发布时使用正确版本。
构建与发布
每个包独立发布到 PyPI:
# 构建所有包uv build --package autogen-coreuv build --package autogen-agentchatuv build --package autogen-ext
# 发布到 PyPIuv publish --package autogen-core发布顺序:Core → AgentChat/Extensions → 上层应用(Studio、CLI)
问题与规避
跨包版本不一致
陷阱:用户安装了 autogen-agentchat==0.7.5 但 autogen-core==0.7.4,可能导致接口不兼容。
规避策略:
- AgentChat 的
pyproject.toml中对 Core 使用精确版本约束(==0.7.5) - 同步发布所有包,确保版本号一致
依赖解析性能
陷阱:monorepo 中 9 个包的依赖图可能非常复杂,uv sync 解析时间过长。
规避策略:
- uv 使用基于 resolvelib 的快速解析器,比 pip 快数十倍
- 锁定文件(
uv.lock)避免重复解析 - 定期更新锁定文件,避免漂移
设计取舍
为什么选 uv 而非 Poetry 或 setuptools?
| 维度 | uv | Poetry | setuptools |
|---|---|---|---|
| Monorepo 支持 | 原生(workspace) | 有限 | 需要手动配置 |
| 解析速度 | 极快(Rust 实现) | 中等 | 慢 |
| 锁定文件 | 有 | 有 | 无(需 pip-tools) |
| 构建后端 | uv_build | poetry-core | setuptools |
| 生态兼容性 | 兼容 pyproject.toml | 自有格式 | 标准 |
AutoGen 的选择理由:
- monorepo 原生支持,9 个包统一管理
- 解析速度快,CI 耗时短
shared_tasks.toml的 extend 模式简洁
包拆分策略
AutoGen 将功能拆分为 9 个包,而非单一 autogen 包。
拆分依据:
- 职责分离:Core、AgentChat、Extensions 面向不同用户
- 依赖精简:只使用 Core 的用户不需要安装 AgentChat 的依赖
- 独立发布:Extensions 可以比 Core 更频繁地发布新版本
何时不拆分:autogen-test-utils 仅用于测试,不发布到 PyPI,保留在仓库中便于开发。
参考来源
- uv Documentation — uv 官方文档
- 源码验证:
python/pyproject.toml(工作区配置) - 源码验证:
python/shared_tasks.toml(共享构建配置)