Shipping huggingface_hub every week with AI, open tools, and a human in the loop
TL;DR · AI 摘要
Hugging Face 通过结合 AI、开源工具和人工审核,实现了每周发布 huggingface_hub 的自动化流程。
核心要点
- huggingface_hub 每周发布一次,依赖于 GitHub Actions 和开源工具。
- AI 用于生成发布说明初稿,但人工审核确保准确性。
- 流程设计强调开放性和可复用性,无需依赖封闭模型或专有平台。
结构提纲
按章节快速跳转。
- §引言
huggingface_hub 是 Hugging Face 生态系统的核心 Python 客户端,每周发布一次。
- ·旧流程
旧的发布流程部分自动化,但大部分工作仍需人工完成,包括版本更新、测试分支创建和发布说明编写。
- ·工作分类
发布流程分为机械性工作(可自动化)和判断性工作(需人工或 AI)。
- ·设计原则
流程设计强调开放性和可复用性,确保任何维护者都能自行运行所有组件。
思维导图
用一张图看清主题之间的关系。
查看大纲文本(无障碍 / 无 JS 友好)
- huggingface_hub 自动化发布
- 旧流程
- 部分自动化
- 大量人工工作
- 新流程
- AI 生成初稿
- 人工审核
- GitHub Actions 自动化
- 设计原则
- 开放性
- 可复用性
金句 / Highlights
值得收藏与分享的关键句。
AI 用于生成发布说明初稿,但人工审核确保准确性。
流程设计强调开放性和可复用性,无需依赖封闭模型或专有平台。
旧的发布流程中,发布说明编写需要数小时的专注工作。
每周使用 AI、开源工具和人工参与发布 huggingface_hub
返回文章列表
[-1
]
[0
发布于 2026 年 6 月 23 日
GitHub 上的更新
点赞
16
[
- +10
Lucain Pouget
Wauplin
关注
Célina Hanouti
celinah
huggingface_hub 是 Hugging Face 生态系统基础的 Python 客户端。transformers、datasets、diffusers、sentence-transformers 以及其他数十个库都依赖它与 Hub 进行通信。如果我们每周不发布一个新版本,就说明有一周的修复和功能被卡在主分支上。
很长一段时间,我们每 4 到 6 周发布一次。现在,我们通过一个 GitHub Actions 工作流,每周都发布一次。我们使用开源工具和开源权重模型构建了这个流程,并在唯一需要判断的地方保留了人工参与。本文中提到的内容不需要任何供应商合同、封闭模型或你无法自行运行的基础设施。从一开始,我们的设计目标就是创建一个其他维护者可以采用和适应的工作流程。
到本文结束时,你将拥有构建自己版本所需的一切。
我们是如何开始的
旧的流程部分是自动化的,大部分是手动操作的。
已经在 CI 中实现的:
- 一旦推送了标签,就发布到 PyPI。
- 在下游库中打开测试分支,并固定发布候选版本。
仍然需要手动完成,每次都要:
- 创建发布分支,在 __init__.py 中更新版本,提交、打标签、推送。
- 观察下游 CI 的运行情况,并处理失败项。
- 阅读自上次发布以来合并的每一个 PR,并手动撰写发布说明:按主题分类,附有上下文,语气不像是 Git 日志的转录。
- 在 RC 周期结束后发布稳定版本。
- 起草内部 Slack 公告和社交媒体帖子。
- 打开发布后的 PR,将主分支更新到下一个 dev0 版本。
为新版本撰写好的发布说明是繁重的工作,需要整合几十个不同主题的 PR。虽然技术上并不困难,但需要几个小时的专注注意力。再加上公告,一个次要版本的发布可能需要几天时间,每天花费几个小时。
两种类型的工作
因此,我们决定简化整个流程。查看这个列表后,工作可以分为两类。
一些步骤完全是机械的,可以自动化:更新版本、提交、打标签、推送、打开下游测试分支、打开发布后的 PR。没有人需要考虑这些步骤。它们只需要按照正确的顺序执行,每次都要完成,而这正是 CI 工作流擅长的地方。
其余的工作则不同。撰写发布说明、决定突出哪些内容、为人类受众撰写公告:这些是脑力工作。这种判断力多年来使发布过程保持手动操作。在这里,AI 发挥了作用,可以在几秒钟内将空白页面转化为一份完整的初稿。但我们也必须小心,因为一份看起来自信但又微妙错误的初稿,比完全没有初稿还要糟糕。
设计原则:任何人都可以重复使用的开放组件
当我们决定解决这个问题时,我们设定了一个前提条件:每一个可移动的部分都必须是任何维护者都可以自行运行的。我们不使用无法替换的 API 后面的封闭模型,不使用专有的发布平台,也不使用任何秘密配方。
以下是整个技术栈:
部分
功能
GitHub Actions
协调整个发布过程
OpenCode
驱动模型的代理运行时
一个开源权重模型
(目前是 Z.ai 的 GLM-5.2)
撰写发布说明和 Slack 公告
HF 推理提供商
模型发布
PyPI 可信发布
发布包
第二个原则:模型起草,人类决定。语言模型擅长将三十个简洁的 PR 标题转化为可读的发布说明。它们并不擅长被盲目信任。因此,工作流程是人类监督的:模型进行初步处理,一个确定性的脚本检查其工作,然后在任何内容发布之前,由人类进行审核和编辑(下面会更详细地介绍这一点)。
管道之旅
完整的流程是一个单独的文件,.github/workflows/release.yml,通过 Actions UI 手动触发。它只接受一个输入:
on:
workflow_dispatch:
inputs:
release_type:
type:
choice
options:
-
minor-prerelease
# 从 main 分支生成一个 RC
-
minor-release
# 将 RC 提升为最终版本
-
patch-release
# 在现有发布分支上进行 bug 修复从这里开始,作业大致按以下顺序运行:
- 准备。计算下一个版本,创建或重用发布分支,提升
__version__,提交、打标签、推送。
- 发布到 PyPI。构建并上传
huggingface_hub。同时,构建并上传hfCLI 作为其自己的 PyPI 包。
- 发布说明。比较自上次标签以来的提交范围,从 GitHub API 获取 PR 元数据,并让模型起草一个结构化的变更日志(这里有一个最近的例子)。保存为草稿的 GitHub 发布。
- 下游测试分支。对于 RC,打开
transformers、datasets、diffusers、sentence-transformers中的分支,将 RC 固定,以便它们的 CI 快速告诉我们是否破坏了某些功能。
- Slack 通知。阅读说明并以我们团队的语气生成内部公告。
- 存档说明。将原始 AI 草稿和人工编辑的版本并排上传到 Hugging Face 存储桶。
- 发布后版本提升。在稳定版本发布后,打开 main 分支上的 PR,提升到下一个 dev0 版本。
- 评论已发布的 PR。在发布版本中的每个 PR 上留下“此内容已发布在 vX.Y.Z”评论。
- 同步 CLI 文档。打开一个 PR 到我们的技能仓库,以重新生成的 hf CLI 技能文档。
- 向 Slack 报告。每一步都以线程回复的方式发布其状态;最后的作业会用 ✅ 或 ❌ 更新根消息。
剩下的手动步骤是审核并发布草稿发布说明,以及审核并发布内部 Slack 消息。这两个步骤是我们希望人类参与的地方。
信任但验证:人机协作的核心
这是每个人对 AI 生成的发布说明都担心的失败模式:模型悄悄地遗漏了一个 PR 或者虚构了一个不在此次发布中的 PR。一个几乎正确的变更日志比没有变更日志更糟糕,因为没有人会重新检查它。
我们不信任生成的发布说明在第一次尝试时是完整的,我们通过确定性的方式验证它。在模型运行之前,一个 Python 脚本会检索属于此次发布的所有 PR,并将其保存为真实来源。
# 确定性:从范围内的 squash-merge 提交中提取 PR 编号。
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)
# 真实来源然后模型根据这些信息起草说明。完成之后,我们将其输出与初始的 PR 列表进行对比:
expected =
set
(load_manifest())
# 应该存在的内容
found = extract_pr_refs(notes_md)
# 模型写的内容 (#1234 -> 1234)
missing = expected - found
# 悄悄遗漏的内容
extra = found - expected
# 属于其他发布的内容如果缺少或多余的内容,我们不会失败,也不会发送错误的文件。我们会将差异返回给代理,并要求它修复这些特定的 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 标题来总结 PR 的模型,会很乐意编造一个与实际 API 不匹配的代码示例。
为了防止这种情况,当我们获取 PR 元数据时,我们还会从每个 PR 中提取实际的文档差异:即 PR 中涉及的任何 docs/ 下的 .md 文件的统一差异。
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 的首次尝试。这时人工审核就起作用了:
- 审核人员阅读草稿,调整语气和重点,修复模型过度或不足强调的任何内容。
- 只有在完成这些之后,才会触发小版本发布运行,将 RC 提升为最终版本。
审核人员的时间用于润色,将半天的写作时间转化为十五分钟的编辑时间。
我们还保留了纸质记录,以便随着时间改进。我们将两个文件并排存档到 Hugging Face Bucket:一个是原始 AI 草稿,在 RC 发布时上传,尚未被任何人修改;另一个是人工编辑后的版本,在最终发布时上传。
# 在 RC 时:直接从模型中获取,未经过任何修改
hf
cp
release_notes_raw.txt
"hf://buckets/huggingface/releases/huggingface_hub/
${V}
/release_notes_raw.txt"
# 在发布时:在人工审核后上传
hf
cp
release_notes_edited.txt
"hf://buckets/huggingface/releases/huggingface_hub/
${V}
/release_notes_edited.txt"每周收集这两个文件,为我们提供一个不断增长的数据集,显示“模型写了什么”与“我们希望它写什么”之间的差异。然后我们可以利用这个数据集来更新代理的技能。
开放且安全的管道
重新设计发布流程是一个很好的机会,可以加强安全性,特别是针对供应链攻击。
不使用 PyPI 令牌。发布使用可信发布(Trusted Publishing):PyPI 验证 GitHub 为此特定工作流程生成的短期 OIDC 令牌,并为每个工件颁发 PEP 740 证明 / Sigstore 来源。没有长期的密钥需要泄露或轮换。
权限:
id-token:
写入
# 为 PyPI 生成 OIDC 令牌
证明:
写入
# 生成 Sigstore 来源
# ...
-
使用:
pypa/gh-action-pypi-publish@v1.14.0
with:
证明:
true
# 不需要密码,也不需要 API 令牌,只需 OIDC代理运行时被固定并验证。我们不会下载并运行最新的 OpenCode,希望它没问题。我们固定一个版本,并在运行之前检查其 SHA256 哈希值:
curl -fsSL https://opencode.ai/install | bash -s -- --version
"
${OPENCODE_VERSION}
"
echo
"
${OPENCODE_SHA256}
$(which opencode)
"
|
sha256sum
-c -开源工具并不意味着粗心的工具。
那么,成本是多少?
几乎可以忽略不计。一次完整的发布(包括发布说明和 Slack 公告,涵盖 20-40 个 PR 和几轮提示)在推理提供商上的成本约为 0.25 美元。使用按需计费的开源权重,每周唯一真正的问题是“是否有值得发布的内容?”,而答案总是肯定的。
实践中的变化
发布频率从每 4 到 6 周一次变为每周一次。次要影响是更有趣的:
- 发布说明变得更好,而不是更差。总是有一个初稿,所以审查时间用于润色。分类更加一致,遗漏的内容更少。
- 问题更早暴露。每个 RC 的下游测试分支在候选窗口期间可以捕捉到集成问题。
- 贡献者循环缩短。自动的“已发布在 vX.Y.Z”评论比我们预期的更重要。当有人在一个已关闭的 PR 上报告问题时,每个人都能立即看到修复是在哪个版本中。以前需要手动查找标签。
使其成为你自己的
这是我们最关心的部分。这个流程围绕 huggingface_hub 构建,但结构是通用的。
几乎可以直接复用:
- 触发器和版本升级逻辑(minor-prerelease 然后 minor-release 然后 patch-release)。
- 信任但验证的循环:确定性清单、模型草稿、验证、重新提示。这是可转移的想法,与你生成的内容无关。
- OIDC 可信发布、固定并经过校验和验证的运行时、Slack 线程。
- 基于技能的提示:替换模板,保留结构。
特定于我们:
- 下游仓库列表及其依赖项固定格式。
- 技能中确切的分类和语气。
- Slack 和存储桶目标。
要进行适配:fork 工作流文件和脚本,指向你的包,重写技能 Markdown 以符合你项目的语气,设置两个仓库变量(模型 ID 和你的 OpenCode 版本),在 PyPI 上设置可信发布,并如果你没有下游测试,删除下游测试任务。信任但验证的循环是值得直接复用的部分。正是它使得生成的工件可以安全地发布。
下一步
- 自动分类下游失败。目前,工作流打开测试分支,由人工阅读 CI。一个显而易见的下一步是检查失败日志,并在内部 Slack 消息中报告它们。
- 扩展这种模式。大部分内容是通用的。我们预计在生态系统中的其他 Python 库中可以复用大部分内容。
总结
发布过程中原本需要耗费半天时间专注人力完成的部分(撰写说明、起草公告、协调下游检查)正是模型擅长的部分。其余部分则属于机械性工作,可以放入 YAML 文件中。关键从来不只是“让 AI 去做”。而是让模型起草,让确定性代码验证,再让人类做决定。整个系统完全由开源工具和开源权重构建,因此成本可以忽略不计,任何人都可以运行它。
完整的流程文件是公开的。如果你维护一个 Python 库,请进行 Fork,进行适配,并告诉我们结果!
本文中提到的模型 1
更多来自我们博客的文章
cli
huggingface_hub
agents
将 hf CLI 设计为一种面向代理优化的 Hub 工作方式
58
2026年6月4日
announcement
mcp
代理资源发现:让代理进行搜索
15
2026年6月17日
社区
编辑
预览
通过拖拽到文本输入框、粘贴或
点击此处
来上传图片、音频和视频。
轻点或粘贴此处上传图片
评论
· 注册或登录以评论
- +4