AutoGen Python 开发指南:基于 uv 工作区的多包开发、质量检查与文档构建实践
本篇指南面向 AutoGen 项目的 Python 方向开发者与维护者,系统讲解 python/ 目录下基于 uv 工作区的多包开发流程:如何搭建虚拟环境、运行格式化/静态检查/测试等全套质量门禁、构建并校验 Sphinx 文档,以及用 cookiecutter 模板创建新的 AutoGen 生态包。读完后,你可以在当前仓库源码状态下独立完成一次完整的“拉取代码 → 建环境 → 跑检查 → 改文档 → 提交 PR”的开发生命周期。
Python 目录是一个 uv 工作区
AutoGen 的 Python 代码集中在 python/ 目录中。该目录作为一个单一的 uv workspace,统一管理与安装所有项目包,而不是各自独立维护的仓库。当前工作区包含以下核心包(均为 python/packages/ 下的子目录):
| 包 | 定位 | 当前版本 |
|---|---|---|
autogen-core |
接口定义与参考实现:agent runtime、model、tool、workbench、memory、tracing 等核心抽象 | 0.7.5 |
autogen-agentchat |
基于 autogen-core 之上的单 agent / 多 agent 工作流(agents 与 teams 库) |
0.7.5 |
autogen-ext |
生态集成实现,例如 autogen-ext[openai] 提供 OpenAI 模型客户端,另有 anthropic、ollama、gemini、docker 等 extras |
0.7.5 |
autogen-studio |
用于构建和运行 AutoGen agent 的 Web IDE(包名 autogenstudio) |
— |
autogen-test-utils |
测试工具包 | 0.0.0 |
agbench |
AutoGen 基准测试工具(Benchmarking Tools) | — |
component-schema-gen |
为组件配置生成 JSON Schema | 0.1.0 |
magentic-one-cli |
安装 m1 命令行工具的 Magentic-One 通用多 agent 系统 CLI |
0.2.4 |
上述包与版本信息来自各包自己的 pyproject.toml,例如 packages/autogen-core/pyproject.toml。
工作区的成员关系由 python/pyproject.toml 中的 [tool.uv.workspace] 段声明:
[tool.uv.workspace]
members = ["packages/*"]
exclude = ["packages/autogen-magentic-one"]
即 packages/ 下所有目录都是工作区成员,但 autogen-magentic-one 被显式排除在同步范围之外。同时,[tool.uv.sources] 段把 autogen-core、autogen-agentchat、autogen-ext、autogenstudio、agbench、component-schema-gen、magentic-one-cli、autogen-test-utils 都标记为 { workspace = true },意味着包之间的相互依赖(例如 autogen-ext 依赖 autogen-core==0.7.5)在本地开发时会解析为工作区内的源码包,而不是从 PyPI 拉取——这正是“基于当前目录状态安装包”的关键机制。
autogen-ext 采用“核心零依赖 + extras 按装”的结构:基础依赖只有 autogen-core,而 openai、anthropic、ollama、gemini、docker、graphrag、chromadb、grpc、docker-jupyter-executor 等都定义在 [project.optional-dependencies] 中(见 packages/autogen-ext/pyproject.toml)。这也是后文 uv sync --all-extras 命令存在的意义所在。
从 0.2.x 迁移而来?
如果你还在使用 AutoGen Python 0.2.x 的旧 API,需要先阅读迁移指南,将代码迁移到 0.4.x 及之后的新架构(即当前 autogen-core / autogen-agentchat / autogen-ext 三层结构)。迁移指南位于 migration-guide.md。
快速开始(TL;DR)
完整走一遍所有检查只需三步,在 python/ 目录下执行:
uv sync --all-extras
source .venv/bin/activate
poe check
三条命令分别完成:同步并安装全部包(含可选依赖)到虚拟环境 → 激活虚拟环境 → 运行整套质量检查(格式化、lint、类型检查、测试、文档与示例校验,详见下文“常用任务”)。
环境搭建:安装 uv
uv 是负责创建开发环境并安装包的 Python 包管理器。首先按官方说明安装 uv;安装后如需升级到最新版,运行:
uv self update
创建虚拟环境(Virtual Environment)
开发过程中你经常需要验证自己对任意一个包的改动。此时必须让虚拟环境中的 AutoGen 包基于当前目录的代码状态来安装(即工作区内以源码方式解析,而非 PyPI 上的发布版)。在 python/ 目录的根层级执行:
uv sync --all-extras
source .venv/bin/activate
uv sync --all-extras:在当前层级创建.venv目录,并把当前工作区里的各包(packages/*)连同它们各自的依赖一起安装。--all-extras标志会额外安装所有可选依赖(对应上文autogen-ext等包中定义的 extras),使文档构建、gRPC 生成、Docker 代码执行器等依赖可选依赖的开发任务都能运行。source .venv/bin/activate:激活该虚拟环境,此后的poe、pytest等命令都在其中运行。
常用任务:poe 质量检查体系
提交 PR 前需要满足一组检查。这些检查既可以逐条运行,也可以一次性全跑:
| 任务 | 命令 | 作用 |
|---|---|---|
| Format | poe format |
ruff 格式化 |
| Lint | poe lint |
ruff 静态检查 |
| Test | poe test |
运行 pytest 测试 |
| Mypy | poe mypy |
mypy 类型检查 |
| Pyright | poe pyright |
pyright 类型检查 |
| Build docs | poe docs-build |
构建 Sphinx 文档 |
| Check docs | poe docs-check |
带 --fail-on-warning 的文档构建 |
| Clean docs | poe docs-clean |
删除构建目录与参考目录 |
| Check code blocks in API references | poe docs-check-examples |
校验 API 参考中的代码块 |
| Auto rebuild+serve docs | poe docs-serve |
文档自动重建并本地服务 |
Check samples in python/samples |
poe samples-code-check |
对 samples/ 做 pyright 检查 |
| 全部检查 | poe check |
依次运行上面大部分检查 |
注意:以上命令都必须在激活的虚拟环境中运行。
poe check 到底检查了什么
这些任务定义在 python/pyproject.toml 的 [tool.poe.tasks] 段中,其中聚合检查是:
check = ["fmt", "lint", "pyright", "mypy", "docs-mypy", "test", "markdown-code-lint", "samples-code-check"]
值得注意的是 fmt、lint、pyright、mypy、test 这几条并不是直接执行工具,而是转发给一个分发脚本:
fmt = "python run_task_in_pkgs_if_exist.py fmt"
lint = "python run_task_in_pkgs_if_exist.py lint"
pyright = "python run_task_in_pkgs_if_exist.py pyright"
mypy = "python run_task_in_pkgs_if_exist.py mypy"
test = "python run_task_in_pkgs_if_exist.py test"
分发逻辑由 run_task_in_pkgs_if_exist.py 实现,从源码结构看它做了两件事:
- 发现项目:读取根
pyproject.toml的[tool.uv.workspace].members(支持 glob,如packages/*),并应用exclude列表,得到实际需要检查的包目录列表; - 逐包转发任务:对每个包,解析其自身
pyproject.toml中的[tool.poe.tasks](含include引用的共享任务),只有当该包确实定义了同名任务时才在其目录下用 PoeThePoet 运行;任何一个包执行失败(返回非零)整个检查即失败。
各包的具体任务则来自共享定义文件 shared_tasks.toml:
[tool.poe.tasks]
fmt = "ruff format"
lint = "ruff check"
mypy = "mypy --config-file $POE_ROOT/../../pyproject.toml src tests"
pyright = "pyright"
也就是说,每个包复用了同一套 ruff / mypy / pyright 配置(统一指向 python/pyproject.toml 的 [tool.ruff]、[tool.mypy]、[tool.pyright] 段),而像 autogen-ext 还会在自身 pyproject.toml 中额外定义 test = "pytest -n auto" 等包级任务。
根配置中的工具版本与严格度(同样来自 python/pyproject.toml)包括:
- ruff:
line-length = 120、fix = true,目标版本py310,lint 规则集E, F, W, B, Q, I, ASYNC, T20,且通过banned-api明确禁止使用unittest(要求“Usepytestinstead”); - mypy:
strict = true,python_version = "3.10",并开启disallow_untyped_defs、no_implicit_optional等严格项; - pyright:
typeCheckingMode = "strict",检查范围覆盖src、tests、samples; - pytest:定义了
grpcmarker(“tests invoking gRPC functionality”),便于筛选 gRPC 相关测试。
因此,一次 poe check 实际是:ruff 格式化与 lint、pyright strict 类型检查、mypy strict 类型检查、文档 notebook 的 mypy 检查(docs-mypy = "nbqa mypy docs/src ...")、全量测试、根 README 与 docs 中 Markdown 代码块的 lint(markdown-code-lint)、以及 samples/ 目录的 pyright 检查(samples-code-check = "pyright ./samples")。
同步依赖(Syncing Dependencies)
当你 pull 到新代码后,可能需要更新虚拟环境中的依赖。确认自己已处于虚拟环境中,然后在 python/ 目录运行:
uv sync --all-extras
该命令会按当前 pyproject.toml 与 uv.lock 的最新状态刷新虚拟环境中的依赖。
构建文档(Building Documentation)
文档源目录位于 docs/src/,采用 Sphinx + MyST 构建。在 python/ 目录根下:
# 构建文档
poe docs-build
# 本地自动重建并服务文档
poe docs-serve
对应 python/pyproject.toml 中的任务定义:
docs-build = "sphinx-build docs/src docs/build"
docs-serve = "sphinx-autobuild docs/src docs/build --watch packages/ --port 8000 --jobs auto"
docs-check = "sphinx-build --fail-on-warning docs/src docs/build"
docs-check-examples = "sphinx-build -b code_lint docs/src docs/build"
docs-clean = "rm -rf docs/build docs/src/reference"
docs-serve 会同时监视 packages/ 目录,源码或文档字符串一有改动即自动重建并热更新。
当你修改了 docstring 或新增模块后,API 参考页可能需要刷新——先清理再重建:
poe docs-clean # 删除构建目录 docs/build 和参考目录 docs/src/reference
poe docs-build # 从零重建整个文档
API 参考的目录结构由脚本自动生成:generate_api_reference.py 会扫描 autogen_core、autogen_agentchat、autogen_ext 三个包的模块,为 API 文档的 index.md 生成 toctree 条目,因此新增公开模块后“clean + build”流程尤为重要。
撰写文档:docstring 规范
新增公开类或函数时,必须补充 docstring。docstring 遵循 Google 风格布局与 Sphinx RST 格式,应包含:
- 紧跟
"""之后的简短描述; - 必要时的长描述,说明用途与用法;
Args小节:列出每个参数名、类型与简述;Returns小节:返回值及其类型(无返回值可省略);Raises小节(可选但推荐):函数可能抛出的异常及说明;Examples小节:使用示例,用.. code-block:: python指令书写,可选地用.. code-block:: text附上输出。
文档给出了 McpWorkbench 的完整示例,其核心用法是作为上下文管理器包裹 MCP 会话:
class McpWorkbench(Workbench, Component[McpWorkbenchConfig]):
"""A workbench that wraps an MCP server and provides an interface
to list and call tools provided by the server.
...
Examples:
Here is a simple example of how to use the workbench with a `mcp-server-fetch` server:
.. code-block:: python
import asyncio
from autogen_ext.tools.mcp import McpWorkbench, StdioServerParams
async def main() -> None:
params = StdioServerParams(
command="uvx",
args=["mcp-server-fetch"],
read_timeout_seconds=60,
)
# You can also use `start()` and `stop()` to manage the session.
async with McpWorkbench(server_params=params) as workbench:
tools = await workbench.list_tools()
print(tools)
result = await workbench.call_tool(tools[0]["name"], {"url": "https://github.com/"})
print(result)
asyncio.run(main())
"""
三条配套规则:
- 代码块会被静态检查。
.. code-block:: python中的代码块由docs-check-examples任务(sphinx-build -b code_lint)交给 Pyright 校验,代码必须可类型检查通过;作者建议“把示例当脚本跑一遍并用 pyright 检查”来确保正确性。 - 交叉引用使用 Sphinx 指令。引用类、方法或函数时必须用
:class:、:meth:、:func:指令建立链接,且始终写包含包名的全限定名,并用~前缀缩短渲染效果。例如引用autogen-agentchat包中的AssistantAgent类,应写作`:class:~autogen_agentchat.AssistantAgent`。 - 公开数据类(包括 Pydantic 模型)的每个字段也要写 docstring。
编写测试(Writing Tests)
新增公开类或函数时,必须同时补充测试;项目跟踪测试覆盖率,目标是新改动不降低覆盖率。规范要点:
- 统一使用
pytest,并始终使用 fixtures 来组织测试依赖; - 使用 mock 对象模拟依赖,避免在测试中发起真实 API 调用或数据库查询,可参考 packages/autogen-core/tests/ 等目录下既有测试的写法;
- 对模型客户端,使用
autogen_ext.models.replay.ReplayChatCompletionClient作为模型客户端的“直接替换件”(drop-in replacement),通过回放预设响应来模拟 LLM,无需真实 API 调用。该客户端的实现位于 packages/autogen-ext/src/autogen_ext/models/replay/; - 确实需要真实模型 API 或外部服务的测试,必须配置成“服务不可用时跳过”。例如测试依赖 OpenAI API key 的模型客户端时,可用
pytest.mark.skipif装饰器在环境变量(API key)未设置时跳过该测试。
创建新的 AutoGen 包
要创建一个与 autogen-core、autogen-agentchat 同级的新包,使用仓库自带的 cookiecutter 模板:
uv sync --python 3.12
source .venv/bin/activate
cookiecutter ./templates/new-package/
模板位于 templates/new-package/,由 cookiecutter.json 驱动,交互输入项包括:
package_name(默认my-project):新包名;version(默认0.1.dev0):版本号;description:包描述;depends_on_core(默认false):是否依赖autogen-core;__final_destination:固定为../packages,即生成的包会直接落在packages/下,自动成为 uv 工作区成员。
生成出的包骨架({{cookiecutter.package_name}}/ 目录)包含 pyproject.toml、README.md、LICENSE-CODE、src/ 与 tests/。生成的 pyproject.toml 有两个值得注意的继承设计:
[tool.ruff]
extend = "../../pyproject.toml"
[tool.pyright]
extends = "../../pyproject.toml"
[tool.poe]
include = "../../shared_tasks.toml"
[tool.poe.tasks]
test = "pytest -n auto"
即新包自动复用工作区根部的 ruff/pyright 严格配置与共享的 fmt/lint/mypy/pyright 任务,并自带并行测试任务 pytest -n auto——创建完成后无需额外配置,poe check 的分发脚本就会把新包纳入整套检查范围。
小结:一次完整开发循环
把上文串起来,在 AutoGen 的 Python 侧维护一个特性或修一个缺陷的完整闭环是:
uv sync --all-extras && source .venv/bin/activate建立/刷新工作区环境(pull 新代码后重复执行);- 在
packages/对应包中修改代码,补写符合 Google 风格 + Sphinx RST 的 docstring,并编写基于 fixtures 与 mock(模型场景用ReplayChatCompletionClient)的 pytest 用例; poe check一次性通过 fmt / lint / pyright / mypy / docs-mypy / test / markdown-code-lint / samples-code-check 全套门禁;- 若涉及公开 API 变动,
poe docs-clean+poe docs-build刷新 API 参考,poe docs-serve本地审阅; - 新增独立包时,用
cookiecutter ./templates/new-package/生成骨架后同样纳入上述检查循环。
以上流程的每一项都能在当前仓库中找到对应依据:工作区声明与任务定义在 python/pyproject.toml,任务分发逻辑在 python/run_task_in_pkgs_if_exist.py,共享任务在 python/shared_tasks.toml,包清单在 python/packages/,文档源在 python/docs/src/,新包模板在 python/templates/new-package/。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0624
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00