Reed's News
← 返回精选

使用AI和开放工具实现huggingface_hub的每周发布

Tech 74 2026/6/23 1539 字 原文 ↗

文本生成 • 753B • 更新版 • 11.9万次浏览 • 2.82k次互动

huggingface_hub是Hugging Face生态系统的核心Python客户端,transformersdatasetsdiffuserssentence-transformers等数十个库都依赖它与Hub进行交互。我们每推迟一周发布新版本,就意味着有一周的修复内容和新功能被卡在main分支无法上线。

过去我们每隔4至6周发布一次新版本,如今通过单一GitHub Actions工作流,实现了每周发布。整个流程基于开源工具和开源权重模型搭建,仅在需要主观判断的环节保留人工审核。本文介绍的方案无需签订供应商合同、无需使用闭源模型,也无需依赖无法自行部署的基础设施——这从一开始就是我们的设计目标,希望其他项目维护者也能轻松借鉴和适配。

读完本文,你将掌握搭建这套流程的全部方法。

旧流程:半自动化,半人工

已实现CI自动化的环节:

仍需每次手动完成的环节:

  • 维护__init__.py文件、提交代码、打标签、推送至仓库
  • 导出git log记录
  • main分支版本号升级至下一个dev0版本
  • 撰写高质量版本说明:汇总数十个不同主题的PR,本身没有技术难度,但需投入数小时精力专注整理,再加上发布公告,一次小版本发布往往要分散耗时半天。

因此我们决定全面优化流程。梳理上述环节后,工作可分为两类:

一类是纯机械性操作,完全可以自动化完成:版本号升级、代码提交、打标签、推送、开启下游测试分支、创建发布后PR。这些操作无需人工思考,只需确保每次按正确顺序执行,而这正是CI工作流的擅长之处。

另一类则需要人工判断:撰写版本说明、确定重点内容、面向用户撰写发布公告——这类工作需要动脑,也是长期以来发布流程依赖人工的原因。AI的价值正在于此:能在几秒内将空白文档转化为可用的初稿。但我们也需谨慎:一份看似专业却暗藏错误的初稿,反而不如没有初稿。

在着手优化时,我们预先设定了一个约束:所有环节必须是任何维护者都能自行运行的。不能依赖无法替换的API闭源模型,不能使用专有发布平台,也不能有“独家秘方”。

完整技术栈

组件 功能
GitHub Actions 编排整个发布流程
OpenCode 驱动模型运行的智能体运行时
开源权重模型(当前使用Z.ai的GLM-5.2 生成版本说明初稿和Slack公告初稿
HF Inference Providers 提供模型推理服务
PyPI Trusted Publishing 发布Python包

我们的第二个原则是:AI生成初稿,人工最终决策。语言模型擅长将30条简洁的PR标题转化为通顺的版本说明,但绝不能盲目信任。因此流程采用人工监督模式:AI完成初稿,确定性脚本校验内容,人工审核编辑后再发布(下文将详细介绍)。

完整流程仅需一个文件.github/workflows/release.yml,通过Actions界面手动触发,仅需输入一个参数:

on:
workflow_dispatch:
inputs:
release_type:
type: choice
options:
- minor-prerelease # 从main分支创建RC版本
- minor-release # 将RC版本正式发布
- patch-release # 在现有发布分支上发布bug修复版本

触发后,任务大致按以下顺序执行:

  1. 更新__version__、提交代码、打标签、推送至huggingface_hub仓库
  2. 并行构建并上传hf CLI作为独立PyPI包
  3. transformersdatasetsdiffuserssentence-transformers中创建固定RC版本的测试分支,通过它们的CI快速验证新版本是否引入问题
  4. main分支版本号升级至下一个dev0版本
  5. 更新hf CLI技能文档

剩余的人工环节仅为:审核并发布版本说明初稿,以及审核并发送内部Slack消息。这两个环节是我们特意保留的人工决策点。

AI生成内容的可靠性保障

大家最担心AI生成版本说明的问题是:模型悄悄遗漏某个PR,或是虚构一个本不属于当前版本的PR。一份近乎正确的变更日志反而比没有更糟,因为没人会再去仔细核对。

我们不会默认AI生成的版本说明是完整的,而是通过确定性方式校验:在模型运行前,用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生成版本说明初稿。完成后,我们将其输出与初始PR列表进行比对:

expected = set(load_manifest()) # 应包含的PR
found = extract_pr_refs(notes_md) # 模型实际写入的PR(#1234 转换为 1234)
missing = expected - found # 被模型遗漏的PR
extra = found - expected # 模型混入的其他版本PR

如果发现遗漏或多余内容,我们不会直接终止流程或发布错误文件,而是将差异反馈给智能体,要求它针对性修正:

for _ in range(MAX_ITERATIONS):
missing, extra = validate(notes)
if not missing and not extra:
break # 与基准数据完全匹配
run_agent_fix(missing_prs=missing, extra_prs=extra)

这正是整套流程值得信赖的关键模式:用确定性校验机制包裹非确定性模型。模型擅长撰写流畅文本,但在完整性上不可靠,因此我们让模型负责文本创作,用代码保障内容一致性。

完整性是一方面,准确性是另一方面。仅基于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初稿的发布草稿,这就是人工介入的环节:

  • 审核并编辑版本说明,然后触发minor-release流程,将RC版本转为正式版本
  • 审核并发送内部Slack公告

审核者只需花15分钟润色内容,替代了过去半天的撰写工作。

我们还保留了完整记录以持续优化:将两个文件并行存档至Hugging Face Bucket——RC版本发布时上传未经修改的AI原始初稿,正式版本发布时上传人工编辑后的版本。

# 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溯源信息。无需使用可能泄露或需要定期轮换的长期密钥。

permissions:
id-token: write # 为PyPI生成OIDC令牌
attestations: write # 生成Sigstore溯源信息
# ...
- uses: pypa/gh-action-pypi-publish@v1.14.0
with:
attestations: true # 无需密码或API令牌,仅通过OIDC验证

智能体运行时版本固定并验证:我们不会直接curl | bash安装最新版OpenCode,而是固定版本号,并在运行前校验其SHA256哈希值:

curl -fsSL https://opencode.ai/install | bash -s -- --version "${OPENCODE_VERSION}"
echo "${OPENCODE_SHA256} $(which opencode)" | sha256sum -c -

开源工具不代表可以疏忽大意。

成本几乎为零

一次完整发布(生成版本说明和Slack公告,处理20至40个PR,经过几轮提示词交互)在Inference Providers上的成本约为0.25美元。使用按次付费的开源权重模型,每周唯一需要考虑的问题就是“有没有值得发布的内容”——而答案通常是肯定的。

发布频率从过去的4至6周一次,提升至每周一次。更重要的是带来的连锁效应:

可复用性

这是我们最关注的一点。这套流程是围绕huggingface_hub设计的,但整体架构具有通用性。

几乎可直接复用的部分

  • 版本发布的三种类型(minor-prereleaseminor-releasepatch-release
  • AI初稿生成+确定性校验+人工审核的核心流程
  • PyPI可信发布机制
  • 开源工具栈

仅适用于我们的部分

  • 下游库测试环节
  • 与Hugging Face基础设施相关的存档逻辑

如需适配你的项目:只需复刻工作流文件脚本,指向你的包,重写技能Markdown文件以匹配项目风格,设置两个仓库变量(模型ID和OpenCode版本),在PyPI上配置可信发布,若无需下游测试则删除对应任务即可。其中“信任但验证”的循环机制尤其值得直接复用,正是它让AI生成的内容可以安全发布。

过去需要半天专注投入的发布工作(撰写说明、起草公告、协调下游测试),恰恰是模型擅长生成初稿的部分;其余纯机械操作则可以完全纳入YAML工作流。关键从来不是“让AI包办一切”,而是让AI负责初稿、让确定性代码负责校验、让人类负责最终决策。整套流程完全基于开源工具和开源权重搭建,成本几乎为零,任何人都可以运行。

完整工作流文件已公开。如果你是Python库维护者,欢迎复刻使用,并告诉我们你的体验!

更多博客文章

感谢分享!这会帮到很多人🤗