LiteLLM Proxy 发布实战:构建与发布 litellm-proxy-extras PyPI 包完整指南
本文基于 LiteLLM 仓库中的官方 runbook build_and_publish.md,系统讲解 litellm-proxy-extras 这个辅助 PyPI 包的版本升级、构建与发布全流程,并结合仓库内的 pyproject.toml 配置、Prisma 迁移机制与代理层源码,说明每一步背后的原理与配套关系。读完本文,你将掌握:如何用 commitizen 自动同步多处版本号、为何必须同步修改根包元数据、uv build 产物结构,以及如何安全地把包上传到 PyPI。
litellm-proxy-extras 是什么:为什么要单独拆一个包
在谈发布流程之前,先明确这个包的定位。根据包内 README 与 pyproject.toml 的描述:
"Additional files for the LiteLLM Proxy. Reduces the size of the main litellm package."
也就是说,litellm-proxy-extras 承载的是 LiteLLM Proxy 的"附加文件",当前主要是 Prisma 数据库迁移的 SQL 文件(litellm-proxy-extras/litellm_proxy_extras/migrations/ 目录下已有上百个按时间戳命名的迁移目录,如 20250326162113_baseline/、20260901000000_shadow_eval_multi_router/),目的是把这些体量较大的资产从主 litellm 包中剥离,控制主包的安装体积。
安装与使用方式(来自 README):
uv add litellm-proxy-extras
或者随主包 proxy 附加依赖一起安装:
uv tool install 'litellm[proxy]' # 会一并安装 litellm-proxy-extras 和其他 proxy 依赖
数据库迁移的使用入口是:
litellm --use_prisma_migrate
从源码结构看,这个命令最终会走到 litellm/proxy/db/prisma_client.py 中的 PrismaManager.setup_database():当 use_migrate=True 时,它会在运行时惰性导入 litellm_proxy_extras.utils.ProxyExtrasDBManager 并委托其执行迁移;若该包未安装则直接报错返回。此外 litellm/proxy/db/prisma_client.py 中的 _apply_replica_identity_full_if_requested() 等钩子对 litellm_proxy_extras 采用了"缺失即 no-op"的 try/except 设计——可以推断,extras 包被刻意设计为可选安装,主包在不装它的情况下仍可运行,这正是发布节奏可以独立于主包的原因之一。
发布前置条件(Prerequisites)
Runbook 明确列出了发布前的三项硬性前置条件,全部满足后才可进入版本升级步骤:
-
所有
schema.prisma文件已同步。仓库中存在多份 schema 副本,必须保持一致,详见配套文档 migration_runbook.md 的 Step 0:文件 用途 schema.prisma(仓库根目录)Source of truth(唯一事实来源) litellm/proxy/schema.prismaProxy 服务器运行时使用 litellm-proxy-extras/litellm_proxy_extras/schema.prisma迁移生成使用 同步方法是对根文件做
diff,有差异时把根 schema 拷贝到两处,并再次 diff 验证一致性。 -
迁移已生成并提交(migration has been generated and committed)。迁移的生成流程(含分支新鲜度检查、破坏性 DDL 拦截等防护)由 ci_cd/run_migration.py 驱动,完整规则见 migration_runbook.md。
-
当前处于
litellm-proxy-extras/目录。后续构建命令均假设工作目录已切换到该包内。
Step 1:升级版本号
版本号在整个仓库中有两处权威位置,且必须同步。这一点可以直接从 litellm-proxy-extras/pyproject.toml 的 commitizen 配置中得到源码级印证:
[tool.commitizen]
version = "0.4.93"
version_files = [
"pyproject.toml:^version",
"../pyproject.toml:litellm-proxy-extras==",
]
version_files 声明了 commitizen 需要维护的两处版本锚点:包自身的 pyproject.toml 中 ^version 匹配行,以及根目录 pyproject.toml 中 litellm-proxy-extras== 锚点。这解释了为什么 runbook 反复强调"漏改根包元数据 = 用户装到旧版本"。
Option A:commitizen 自动升级(推荐)
使用 commitizen 一次性把所有声明过 version_files 的位置都升上去:
cd litellm-proxy-extras
cz bump --increment patch
该命令会自动完成:
- 升级
pyproject.toml中的版本(同时更新[project].version与[tool.commitizen].version两处); - 更新
../pyproject.toml(仓库根)中的litellm-proxy-extras==X.Y.Z版本引用; - 创建一个版本升级的 git commit。
完成后直接跳到 Step 3(清理旧产物),无需再手动改任何文件。
Option B:手动升级版本
手动方式分两步。第一步在包内查看并修改版本:
cd litellm-proxy-extras
# 查看当前版本
grep 'version' pyproject.toml
然后编辑 pyproject.toml,把 [project].version 和 [tool.commitizen].version 两处都改成新版本(注意二者当前同为 0.4.93,必须保持一致)。
Step 2(仅手动方式需要):同步根包元数据。 升级包内版本后,必须同步更新根 pyproject.toml 中的版本引用:
| 文件 | 需要更新的行 |
|---|---|
pyproject.toml(根目录) |
[project.optional-dependencies].proxy 中的 litellm-proxy-extras==X.Y.Z |
# 在仓库根目录执行 — 把 OLD 替换为旧版本,NEW 替换为新版本文本
sed -i '' 's/litellm-proxy-extras==OLD/litellm-proxy-extras==NEW/' pyproject.toml
切勿跳过此步。 主
litellm包以精确 pin 的方式引用 extras 版本——若不更新,用户执行pip install 'litellm[proxy]'时仍会安装旧版本的 extras。
仓库根 pyproject.toml 当前实际内容印证了这一 pin 方式:proxy 可选依赖列表中写着 "litellm-proxy-extras==0.4.93"(与 extras 包当前版本一致);同时根配置还声明了 [tool.uv.sources] 下 litellm-proxy-extras = { workspace = true } 与 [tool.uv.workspace] 的 members = ["enterprise", "litellm-proxy-extras"]——即开发态下 extras 作为 uv workspace 成员被本地解析,而发布态下则依赖 PyPI 上的精确版本 pin,两条路径的版本必须一致。
一点实操提示:文档给出的 sed -i '' 语法是 BSD/macOS 风格,在 Linux(GNU sed)上应去掉 '' 参数,例如 sed -i 's/litellm-proxy-extras==OLD/litellm-proxy-extras==NEW/' pyproject.toml,或者干脆直接编辑文件以免误伤其他同名匹配。
Step 3:清理旧的构建产物
在重新构建前清理历史产物,避免陈旧文件混入新包:
rm -rf dist/ build/ *.egg-info
Step 4:构建包
uv build
构建完成后 dist/ 目录下会生成 .tar.gz(sdist)与 .whl(wheel)两种分发格式。用下面命令验证产物:
ls -la dist/
这里的构建后端也值得说明:litellm-proxy-extras/pyproject.toml 声明构建系统为 uv_build==0.11.8(build-backend = "uv_build"),并通过 [tool.uv.build-backend] module-root = "" 指定模块根目录为包目录本身(即 litellm_proxy_extras/ 直接位于 litellm-proxy-extras/ 下),同时 [tool.uv] 要求 uv 版本 >=0.10.9。因此执行 uv build 前需确认本机 uv 满足该版本要求,且包目录下的 litellm_proxy_extras/(含 utils.py、prisma_toolchain.py、replica_identity.py、schema.prisma 及 migrations/)即为最终打包内容。
Step 5:上传到 PyPI
uv tool run --from 'twine==6.2.0' twine upload dist/*
使用 uv tool run 临时运行固定版本的 twine(6.2.0),避免依赖本机 twine 版本漂移。执行后会提示输入 PyPI API token:
Enter your API token: pypi-...
用户名固定填写
__token__,密码位置粘贴你的 PyPI API token。
Quick Reference(可直接复制粘贴的完整流程)
cd litellm-proxy-extras
rm -rf dist/ build/ *.egg-info
uv build
uv tool run --from 'twine==6.2.0' twine upload dist/*
交互式决策:本次是否真的需要发版
Runbook 结尾给出了一个面向执行者的 y/n 决策环节:"Do you want to build and publish a new litellm-proxy-extras package? (y/n)"
- 若回答 yes:按顺序执行上述 Quick Reference 中的四条命令;
twine upload运行时凭据填写:- Username:
__token__ - Password: (粘贴你的 PyPI API key)
- Username:
- 若回答 no:本次无需发版,流程结束——例如你只是改了与 extras 无关的代码,或 schema/迁移尚未就绪。
这个 y/n 环节实际上是一个轻量的发布门禁:由于主包 pin 住 extras 的精确版本,只有当 migrations/ 下确实新增了需要随 litellm --use_prisma_migrate 下发的迁移、或包内工具代码(如 utils.py 中供 prisma_client.py 调用的 ProxyExtrasDBManager)有变更时,才真正需要走一遍完整的版本升级 + 构建 + 上传流程。
配套机制速览:迁移 runbook 与发布流程的衔接
发布 runbook 与迁移 runbook 是同一工作流的上下游。migration_runbook.md 规定了:先同步三份 schema.prisma(Step 0),再执行 uv run --with testing.postgresql python ci_cd/run_migration.py "your_migration_name" 生成迁移;该脚本会校验当前分支与基线分支的新鲜度、在临时 PostgreSQL 中回放既有迁移并与 schema 做 diff,且默认拒绝写入包含 DROP COLUMN / DROP TABLE / DROP INDEX 的生成 SQL(需显式传 --allow-destructive 才能放行)。其结尾也反向链接回本文:"Done with migration? See build_and_publish.md to publish a new litellm-proxy-extras package."
完整闭环因此是:同步 schema → 生成并审查迁移 SQL → 提交 schema + 迁移 → 升级双处版本号(commitizen 或手动)→ 清理并 uv build → twine 上传 PyPI → 主包 proxy extra 的 pin 指向新版本生效。每一步都有明确的文件级证据可依:版本锚点在 litellm-proxy-extras/pyproject.toml,主包 pin 在 pyproject.toml 的 proxy 可选依赖中,迁移资产在 litellm-proxy-extras/litellm_proxy_extras/migrations/,运行时消费入口在 litellm/proxy/db/prisma_client.py。
适用前提与限制
- 本文流程依据仓库中 runbook 原文整理,属于 LiteLLM 工程团队的内部发布规范(runbook 自述 "For use by litellm engineers only"),涉及 PyPI 上传权限,普通用户只需安装、无需发布。
- 版本相关事实(如当前
0.4.93、twine6.2.0、uv_build0.11.8)以当前仓库文件快照为准,实际执行前请以仓库最新状态核对。 cz bump --increment patch仅演示了 patch 级升级;minor/major 升级同理,替换 increment 参数即可,但根包 pin 同步逻辑不变。
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 StartedRust0623
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