huggingface_hub 是 Hugging Face 生态底层的 Python 客户端。transformers、datasets、diffusers、sentence-transformers 等数十个库依赖它与 Hub 通信。每多等一周才发布,就意味着修复与功能继续滞留在 main 上。
长期以来,原作者所在的 Hugging Face 团队每隔4到6周发布一次。现在只需一套 GitHub Actions 工作流,就能每周发布。Hugging Face 团队使用开源工具和开放权重模型搭建流程,并在判断最重要的环节保留人工审核。本文中的方案无需供应商合同、封闭模型或无法自行运行的基础设施。Hugging Face 团队从一开始就希望其他维护者能够取用并调整这套流程。
读完本文,你将具备构建自己发布流程所需的全部信息。
Hugging Face 团队的起点
旧流程部分自动化,但主要依靠手工操作。
已经在 CI 中完成的工作:
- 推送标签后发布到 PyPI。
- 在下游库中创建测试分支,将依赖固定为候选发布版本。
每次仍需手工完成的工作:
- 创建发布分支,修改 __init__.py 中的版本号,提交、打标签并推送。
- 观察下游 CI 运行,分析和处理失败。
- 阅读上次发布以来合并的所有 PR,手写发布说明:按主题分组、补充背景,让语气不像直接倾倒 Git 日志。
- 在 RC 阶段结束后发布稳定版。
- 起草内部 Slack 公告与社交媒体帖子。
- 在发布之后创建 PR,将 main 的版本提升为下一个 dev0。
写好一个新版本的发布说明是最费力的部分,需要汇总不同主题的数十个 PR。这在技术上并不难,却需要数小时专注。加上公告,一次次要版本发布很容易消耗半天工作,而且分散在数天里。
两类工作
Hugging Face 团队决定精简整个流程。从上述列表来看,工作可分为两类。
一些步骤纯属机械操作,可以自动化:提升版本、提交、打标签、推送、创建下游测试分支、创建发布后 PR。它们不需要人工思考,只需每次按正确顺序执行,而 CI 工作流正擅长此事。
其他步骤则不同。撰写发布说明、选择突出内容、面向读者措辞公告,都需要判断。这些工作使发布流程多年来保持手动。AI 可以在数秒内将空白页面变为扎实的初稿;但也必须小心,因为看起来很自信、却存在隐蔽错误的初稿,可能比没有初稿更糟。
设计原则:开放组件,人人可复用
开始改进时,Hugging Face 团队先设下一条约束:所有组件都必须能由维护者自行运行。不依赖无法替换的封闭模型 API、专有发布平台或秘密技术。
完整技术栈如下:
组件 作用 GitHub Actions 编排整个发布流程 OpenCode 驱动模型的代理运行时 开放权重模型,原文使用 Z.ai 的 GLM-5.2 起草发布说明与 Slack 公告 HF Inference Providers 提供模型推理服务 PyPI Trusted Publishing 发布软件包 (OpenCode · GLM-5.2 · HF Inference Providers · PyPI Trusted Publishing)
第二条原则是:模型起草,人工决定。语言模型擅长将三十个简短的 PR 标题整理成可读的发布说明,却不适合被盲目信任。因此,流程由人工监督:模型完成初稿,确定性脚本检查其结果,然后在交付前由人工审阅和编辑。下文将详细介绍。
浏览发布流水线
完整工作流位于单个文件 .github/workflows/release.yml,从 Actions 界面手动触发。它只接受一个输入:(.github/workflows/release.yml)
on:
workflow_dispatch:
inputs:
release_type:
type: choice
options:
- minor-prerelease # cut an RC from main
- minor-release # promote the RC to final
- patch-release # bugfix on an existing release branch
随后,各任务大致依次运行:
- 准备:计算下一个版本,创建或复用发布分支,提升 __version__,提交、打标签、推送。
- 发布到 PyPI:构建并上传 huggingface_hub。同时,将 hf CLI 作为独立的 PyPI 包构建并上传。
- 发布说明:比较上一个标签以来的提交范围,通过 GitHub API 获取 PR 元数据,让模型起草结构化的更新日志,并保存为 GitHub 发布草稿。原文链接提供近期实例。(近期发布示例)
- 下游测试分支:对于 RC,在 transformers、datasets、diffusers、sentence-transformers 中创建固定依赖为该 RC 的分支,以便 CI 快速发现破坏性变化。
- Slack 公告:读取发布说明,按团队语气生成内部公告。
- 归档说明:将原始 AI 草稿与人工编辑版并排上传到 Hugging Face Bucket。
- 发布后提升版本:稳定版发布后,在 main 创建 PR,将版本提升到下一个 dev0。
- 在已交付的 PR 中评论:为本次发布包含的每个 PR 留下“已随 vX.Y.Z 发布”的评论。
- 同步 CLI 文档:在 skills 仓库创建 PR,更新重新生成的 hf CLI 技能文档。(技能库)
- 向 Slack 报告:每一步都将状态作为线程回复发出;最后一个任务用成功或失败标记更新主消息。
剩下的手动步骤是审阅并发布 GitHub 发布说明草稿,以及审阅并发送内部 Slack 消息。这两个步骤正是Hugging Face 团队希望保留人工参与的地方。
信任但验证:人工参与的核心
大家最担忧 AI 发布说明出现的错误是:模型悄悄遗漏某个 PR,或编造一个不属于本次发布的 PR。几乎正确的更新日志甚至比没有更糟,因为读者不会逐项复查。
Hugging Face 团队不相信初次生成的发布说明一定完整,而是进行确定性验证。在运行模型之前,Python 脚本取得本次发布的全部 PR,将其存为事实基准。
# Deterministic: extract PR numbers from squash-merge commits in the range.
PR_NUMBER_PATTERN = re.compile(r"\(#(\d+)\)$")
pr_numbers = [
int(m.group(1))
for commit in commits_since_last_tag
if (m := PR_NUMBER_PATTERN.search(commit.title))
]
save_manifest(pr_numbers) # the source of truth
模型基于这些 PR 起草说明。完成后,将输出与最初的 PR 清单比较:
expected = set(load_manifest()) # what should be there found = extract_pr_refs(notes_md) # what the model wrote (#1234 -> 1234) missing = expected - found # silently dropped extra = found - expected # belongs to a different release
如果存在遗漏或多出的 PR,不会简单失败,也不会交付错误文件。Hugging Face 团队把差异反馈给代理,要求它只修复这些 PR:
for _ in range(MAX_ITERATIONS):
missing, extra = validate(notes)
if not missing and not extra:
break # matches the manifest exactly
run_agent_fix(missing_prs=missing, extra_prs=extra)
这套模式使流程可靠:用确定性的约束包裹非确定性的模型。模型擅长写文字,却无法可靠地穷尽全部项目;因此让模型写作,让代码强制保证一致性。
给模型事实依据,避免凭空编造
完整性是一方面,准确性是另一方面。仅依据 PR 标题总结时,模型可能轻易编造与真实 API 不符的代码示例。
为避免这一点,取得 PR 元数据时,也拉取该 PR 的实际文档差异:docs/ 下所有受影响 .md 文件的 unified diff。
def fetch_doc_diffs(pr):
return [
{"filename": f.filename, "status": f.status, "patch": f.patch}
for f in pr.get_files()
if f.filename.startswith("docs/") and f.filename.endswith(".md") and f.patch
]
这些差异进入模型上下文。因此模型写“下面是新 CLI 命令”时,引用的是 PR 作者实际写入文档的例子。逻辑与前面相同:提供真实来源材料,并限制模型的任务范围。
提示本身以 Skills 形式存放:提交到仓库的小型 Markdown 文件,包括 SKILL.md 与参考模板。发布说明技能规定如何选重点、组织章节、何时添加文档链接等。它读起来像新人入职说明,这正是适合的理解方式。(技能文件)
人工检查点
发布 RC 后,GitHub 发布草稿中已有 AI 的初次结果。这时由人工介入:
- 审阅者阅读草稿,调整语气与重点,修正模型过度强调或强调不足的内容。
- 完成后才触发 minor-release,将 RC 提升为最终版本。
审阅者的时间用于润色,把半天写作变成约十五分钟的编辑。
Hugging Face 团队也保留审计轨迹,持续改进。两个文件并排归档到 Hugging Face Bucket:RC 阶段任何人尚未修改时上传的 AI 原始稿,以及正式发布时上传的人工编辑版。
# at RC time: straight from the model, untouched
hf cp release_notes_raw.txt "hf://buckets/huggingface/releases/huggingface_hub/${V}/release_notes_raw.txt"
# at release time: after the human review
hf cp release_notes_edited.txt "hf://buckets/huggingface/releases/huggingface_hub/${V}/release_notes_edited.txt"
每周积累两份文件,就得到不断增长的数据集,记录“模型写了什么”与“Hugging Face 团队希望它写什么”的差别,随后可以用它更新代理的技能。
开放而安全的基础流程
重构发布流程也是强化安全的好机会,尤其是防范供应链攻击。
无需 PyPI token。发布使用 Trusted Publishing:PyPI 验证 GitHub 为这个具体工作流签发的短期 OIDC token,并为每项产物生成 PEP 740 证明与 Sigstore 来源证明。不存在需要轮换或可能泄漏的长期密钥。(Trusted Publishing · PEP 740)
permissions:
id-token: write # mint the OIDC token for PyPI
attestations: write # generate Sigstore provenance
# ...
- uses: pypa/gh-action-pypi-publish@v1.14.0
with:
attestations: true # no password, no API token, just OIDC
代理运行时固定版本并验证。Hugging Face 团队不会直接用 curl | bash 安装最新版 OpenCode 后寄希望于一切正常,而是固定版本,运行前检查 SHA256:
curl -fsSL https://opencode.ai/install | bash -s -- --version "${OPENCODE_VERSION}"
echo "${OPENCODE_SHA256} $(which opencode)" | sha256sum -c -
采用开放工具,并不意味着可以疏于管理。
成本是多少?
原作者团队报告几乎没有成本。一次完整发布,包括20到40个 PR 的发布说明、Slack 公告与数轮提示,在 Inference Providers 上约花费0.25美元。开放权重模型按用量收费,每周只需考虑“有没有值得交付的内容”,而答案总是有。此费用是原文当时的使用案例。
实践中发生了什么变化
Hugging Face 原作者团队的发布节奏从每4到6周一次变成每周一次。更有意思的是随后出现的效果:
- 说明质量提升。总有一份初稿,审阅时间因此用于润色;分组更一致,遗漏更少。
- 破坏性问题更早暴露。每个 RC 的下游测试分支都能在候选阶段捕捉集成问题。
- 贡献者反馈循环缩短。“已随 vX.Y.Z 发布”的自动评论比预期更有价值:有人在已关闭 PR 中报告问题时,所有人马上能看到修复属于哪个版本,以前还需要手动查标签。
调整为自己的流程
这是Hugging Face 团队最重视的部分。工作流围绕 huggingface_hub 设计,但整体结构通用。
几乎无需修改即可复用的部分:
- 触发与版本提升逻辑:minor-prerelease、minor-release、patch-release。
- “信任但验证”循环:确定性清单、模型草稿、验证、重新提示。这个思路可以迁移,不取决于正在生成什么。
- OIDC Trusted Publishing、固定版本并校验摘要的运行时、Slack 线程。
- 基于技能的提示:更换模板,保留结构。
属于Hugging Face 团队项目特定内容的部分:
- 下游仓库列表,以及各仓库固定依赖版本的格式。
- 技能中的具体章节分类与语气。
- Slack 与 bucket 的目的地。
调整时,可以 fork 工作流文件和脚本,指向自己的包,改写技能 Markdown 以符合项目语气,设置两个仓库变量(模型 ID 与 OpenCode 版本),在 PyPI 配置 Trusted Publishing;没有下游项目时,删除下游测试任务。最值得原样复用的是“信任但验证”循环,它使生成产物能够可靠交付。(工作流文件 · 脚本 · 技能 Markdown)
下一步
- 原作者团队希望自动分析下游失败。目前工作流创建测试分支,人工读取 CI。下一步可以检查失败日志,将结果报告在内部 Slack 消息中。
- 原作者团队希望扩展这一模式。大部分内容通用,预计会在生态中其他 Python 库上复用大量组件。
要点
在原作者团队的实践中,以前需要人工专注半天的发布工作,如写说明、起草公告、协调下游检查,正适合由模型起草;其他机械操作则可以写在 YAML 中。诀窍不只是“交给 AI”,而是模型起草、确定性代码验证、人工决定。整个方案由开放工具与开放权重构建,成本很低,任何人都能运行。
完整工作流已经公开。如果你维护 Python 库,可以 fork、调整它,再向原文作者分享使用情况。(复制并调整工作流)












暂无评论内容