Hugging Face 将 hf CLI 重构为面向智能体的命令行工具
Designing the hf CLI as an agent-optimized way to work with the Hub
Hugging Face 重构官方命令行工具 hf CLI,使其同时适配人类和编码智能体,并引入 agent-mode 输出。官方基准显示,在复杂多步任务上,不使用 CLI 而由智能体手写 curl 或 Python SDK 的方案最多消耗 6 倍 token;整体上 curl 与 SDK 约为 CLI 的 1.3 至 1.8 倍。
hf 是 Hugging Face Hub 的官方命令行入口。你在 Hub 上通过 Python SDK 能做的任何事情,都可以在终端中完成:下载和上传模型、数据集和 Spaces;创建和管理仓库、分支、标签和拉取请求;在 HF 基础设施上运行 Jobs;管理 Buckets、Collections、webhooks 和 Inference Endpoints。
hf CLI 多年来主要是为我们的用户构建的。但如今它越来越多地被 编码代理使用:Claude Code、Codex、Cursor 等等。因此我们重新构建了它,使其同时适用于这两类用户。这篇博客文章总结了我们所做的工作,以及我们如何对其进行基准测试。我们发现,在复杂的多步骤任务上,无 CLI 基线(代理手写 curl 或 Python SDK)消耗的 token 数量最多可达 hf CLI 的 6 倍。
Hub 上的 AI 代理流量
我们从 2026 年 4 月开始追踪 Hub 上的代理使用情况。hf CLI(以及它所基于的 huggingface_hub Python SDK)通过读取代理设置的环境变量来检测是否有编码代理在驱动它:Claude Code 的 CLAUDECODE/CLAUDE_CODE、Codex 的 CODEX_SANDBOX,以及 Cursor、Gemini、Pi 和通用的 AI_AGENT。这一个信号有两个作用:它塑造 CLI 的输出(详见下文),并为每个 Hub 请求打上 agent/<name> user-agent 标签,这样我们就能将流量归因于驱动它的代理。按去重用户数计算,最大的两个是 Claude Code 和 Codex,远远领先于其他所有代理,它们也是我们在本文后面进行基准测试的两个代理。
柱状图统计的是每个代理的去重用户数;请求量是子标签。仅 Claude Code 就有约 4 万用户和近 4900 万次请求,Codex 紧随其后。这些是早期数据(我们直到 2026 年 4 月才开始对代理流量进行归因),但规模已经相当可观,而且随着编码代理成为使用 Hub 的标准方式,我们预计它还会继续增长。
为人类和代理而构建
对于相同的 hf 命令,人类和编码代理期望不同的输出。人类想要丰富的终端输出:ANSI 颜色、截断以适应屏幕的填充表格、成功时的绿色 ✅、布尔值的 ✔、进度条、文字提示。代理想要的则相反:没有 ANSI,不截断任何内容,每个值都完整呈现,因为代理能处理比人类密集得多的输出,同时保持紧凑和结构化以节省 token。它也无法回答 CLI 提示,并且会在超时后愉快地重新运行命令。本节的其余部分介绍 hf 如何为双方提供各自所需。我们在 hf v1.9.0 中引入了代理模式输出,并在随后的版本中逐步将 CLI 的其余部分迁移到该模式。
一条命令,多种呈现
当 hf 自动检测到代理使用时(通过上述环境变量),它会以不同方式呈现同一条命令。它无需传递标志即可为人类或代理优化输出格式:
# human (default in a terminal): aligned table, truncated to fit, with a hint
> hf models ls --author Qwen --sort downloads --limit 3
ID CREATED_AT DOWNLOADS LIBRARY_NAME LIKES PIPELINE_TAG PRIVATE TAGS
------------------------ ---------- --------- ------------ ----- --------------- ------- -------------------------
Qwen/Qwen3-0.6B 2025-04-27 21156913 transformers 1285 text-generation transformers, safetens...
Qwen/Qwen2.5-1.5B-Ins... 2024-09-17 15143953 transformers 725 text-generation transformers, safetens...
Qwen/Qwen3-4B 2025-04-27 14808352 transformers 625 text-generation transformers, safetens...
Hint: Use `--no-truncate` or `--format json` to display full values.
# agent (auto-detected): TSV, full ids + ISO timestamps + every tag, nothing truncated
$ hf models ls --author Qwen --sort downloads --limit 3
id created_at downloads library_name likes pipeline_tag private tags
Qwen/Qwen3-0.6B 2025-04-27T03:40:08+00:00 21156913 transformers 1285 text-generation False ['transformers', 'safetensors', 'qwen3', 'text-generation', 'conversational', 'arxiv:2505.09388', 'base_model:Qwen/Qwen3-0.6B-Base', 'base_model:finetune:Qwen/Qwen3-0.6B-Base', 'license:apache-2.0', 'text-generation-inference', 'endpoints_compatible', 'deploy:azure', 'region:us']
Qwen/Qwen2.5-1.5B-Instruct 2024-09-17T14:10:29+00:00 15143953 transformers 725 text-generation False['transformers', 'safetensors', 'qwen2', 'text-generation', 'chat', 'conversational', 'en', 'arxiv:2407.10671', 'base_model:Qwen/Qwen2.5-1.5B', 'base_model:finetune:Qwen/Qwen2.5-1.5B', 'license:apache-2.0', 'text-generation-inference', 'endpoints_compatible', 'deploy:azure', 'region:us']
Qwen/Qwen3-4B 2025-04-27T03:41:29+00:00 14808352 transformers 625 text-generation False ['transformers', 'safetensors', 'text-generation', 'arxiv:2309.00071', 'arxiv:2505.09388', 'base_model:Qwen/Qwen3-4B-Base', 'base_model:finetune:Qwen/Qwen3-4B-Base', 'license:apache-2.0', 'endpoints_compatible', 'deploy:azure', 'region:us']
人类会得到一个对齐的表格,截断以适应终端,并附带如何查看更多内容的提示,以及状态的颜色提示(成功时为绿色 ✓,错误时为红色)。代理会得到完整的记录,以 TSV 格式呈现:完整的仓库 id、完整的 ISO 时间戳、每个标签,没有 ANSI 代码,没有任何截断,易于解析且 token 占用少。
在实践中,我们实现了诸如 .table(...)、.result(...)、.json() 等日志记录方法,它们以原始数据为输入并处理格式化。除了人类和 agent 模式外,我们还引入了 --json 和 --quiet 选项,以便更轻松地将命令串联起来。默认模式会根据上下文自动选择,但用户始终可以通过 --format human | agent | json | quiet 强制使用自己选择的格式。
下一条命令提示
CLI 命令很少孤立运行:一步通常意味着下一步(git add,然后 git commit)。许多 hf 命令现在以 提示 结尾:即接下来要运行的确切命令,已预填你刚刚使用的 ID,这样用户或 agent 就可以直接衔接到下一步,而不必从头琢磨。在后台启动一个 Job,它会指向其日志;创建一个 Space,它会指向其启动状态:
$ hf jobs run --detach python:3.12 python train.py
✓ Job started
id: 6f3a1c2e9b
url: https://huggingface.co/jobs/celinah/6f3a1c2e9b
Hint: Use `hf jobs logs 6f3a1c2e9b` to fetch the logs.
对人类来说,这是一种便利。对 agent 来说,这是一条轨道:下一个动作已被命名、用正确的 ID 参数化,并准备好运行,因此它需要更少的步骤来弄清楚该做什么。错误也是如此,它会指出修复方法,而不只是失败:
Error: Not logged in. Run `hf auth login` first.
提示、警告和错误都输出到 stderr,而数据输出到 stdout,因此这些指引都不会污染 agent 正在解析的输出。
非阻塞且可安全重试
hf 绝不会停留在交互式提示上,等待 agent 无法按下的按键。破坏性命令仍会要求人类确认,但在 agent 模式下它会快速失败,并在消息中给出修复方法(Use --yes to skip confirmation.),而 -y/--yes 会跳过它。而且由于 agent 会在超时和上下文丢失时重试,操作被设计为可安全重复:如果仓库已存在,hf repos create --exist-ok 是空操作,重新运行上传也会干净地重新提交。另外,移动真实数据的命令会接受一个 --dry-run,在运行前准确显示它们将传输什么,这对人类和 agent 都很方便,因为双方都不必承诺进行长时间下载或盲目同步:
# agent mode: a destructive command without --yes refuses, with the fix in the message
$ hf repos delete my-org/old-model
Error: You are about to permanently delete model 'my-org/old-model'. Proceed? Use --yes to skip confirmation.
# commands that move data take --dry-run to preview the transfer first
$ hf download deepseek-ai/DeepSeek-V4-Pro config.json --dry-run
[dry-run] Will download 1 files (out of 1) totalling 1.8K.
file size
config.json 1.8K
可发现、可预测的命令
hf 被设计为可探测的:运行 hf 查看资源组,对你需要的那一个运行 --help,而每个 --help 都以真实、可复制粘贴的示例结尾(agent 匹配这些示例的速度远快于解析描述):
$ hf models ls --help
...
Examples
$ hf models ls --sort downloads --limit 10
$ hf models ls --search "qwen" --author Qwen
$ hf models ls Qwen/Qwen3-4B --tree
命令树是一致的,资源 + 动词,并带有显而易见的别名(hf models ls、hf repos create、hf jobs ps、hf collections delete;list/ls、remove/rm),因此一旦 agent 学会一个命令,它就能猜出其余命令。而且输出可以组合:-q 每行打印一个 ID,以便管道传给下一条命令,--json 给你一些可以交给 jq 的东西。
$ hf models ls --author Qwen -q | head -3
Qwen/Qwen3-0.6B
Qwen/Qwen2.5-1.5B-Instruct
Qwen/Qwen3-4B
为 Coding Agents 基准测试 hf CLI
为了弄清 hf CLI 对 agent 是否真的更高效,我们进行了测量。我们构建了一个小型评估框架,并通过每种驱动 Hub 的方式,对同一组 Hub 任务反复运行多次,每次运行都对照实时 Hub 进行评分。在介绍方法之前,先给出结论:在两个 agent 上,hf CLI 都胜出,在复杂的多步骤任务上最为明显,因为它使用的 token 少得多。
| agent | 工具 | 成功分数 | token 使用量 | 自我报告错误 |
|---|---|---|---|---|
| Claude Code (Sonnet 4.6) | hf CLI |
0.94 | 基线 | 2 / 163 |
| curl / Python SDK | 0.84 | 1.3-1.6× tokens | 11 / 163 | |
| Codex (GPT-5.5) | hf CLI |
0.93 | 基线 | 3 / 163 |
| curl / Python SDK | 0.92 | 1.6-1.8× tokens | 10 / 163 |
(自报错误 = 智能体在 17 个可解任务上报告成功,但 Hub 表示并非如此。hf CLI 行是安装了其 skill 的 CLI;skill 在裸 CLI 之上增加的内容(主要是更少的工具调用)在下面的 skill 部分中单独列出。代表性记录发布在 此存储桶中。)
设置
我们定义了 18 个非平凡的 Hub 任务。不是“下载一个文件”,而是你实际会要求的那种事情:聚合一个热门组织的模型、检查仓库的文件及其大小、使用包含/排除规则上传文件夹、删除文件、跨仓库复制文件、打开一个添加许可证的 PR、创建一个带有分支和标签的仓库、同步并清理存储桶、构建一个集合。每个任务都交给一个全新的编码智能体,且只有一种方式与 Hub 通信:
hfCLI,或者- curl / Python SDK:完全没有
hfCLI,因此智能体只能退回到针对 REST API 使用curl或使用huggingface_hubPython 库。
我们以两种配置运行 hf CLI,带或不带其 skill(一份生成的命令参考,我们会在其单独部分中再讨论)。但下面最重要的比较只是 hf CLI vs curl / SDK;skill 的增量效果小到足以单独列出,而不是挤进主要结果中。
配置刻意保持干净:每次运行使用全新实例,没有自定义 MCP 服务器,没有 CLAUDE.md 或 AGENTS.md,上下文中没有任何会诱导行为的内容。任务和工具被放入单个提示中,智能体以 TASK_COMPLETE 或 TASK_FAILED 标记结束,但我们不信任该标记(智能体会对从未落地的工作报告成功),因此我们通过重新查询实时 Hub 来独立评分每次运行:分支真的创建了吗,文件真的删除了吗,存储桶存在吗?每个任务/工具组合运行 10 次,因为编码智能体是非确定性的,每个智能体约 520 次运行(18 个任务 × 3 个工具 × 10 次重复,减去一个可计费 Jobs 任务的上限),总共有约 1,000 次评分运行。我们在两个最流行的编码智能体上把整个实验跑了两次(使用 Sonnet 4.6 的 Claude Code 和使用 GPT-5.5 的 OpenAI Codex)。
结果
下面的两张图拆解了上表。首先,Sonnet 上的任务成功率,这是 curl 和 SDK 最吃力的智能体:
没有 CLI 时,curl 和 SDK 落后十个百分点,因为在 Sonnet 上它们根本无法完成部分工作(主要是写入),而 hf CLI 能完成这些。
第二张图显示了 GPT-5.5 上的 token 影响,按任务细分。每个柱形是同一任务上 curl/SDK token 数除以 CLI 的 token 数,因此 2.4× 表示非 hf 版本为做同样的事情消耗了 2.4 倍的 token:
在一次性的读取上(统计数据集行数、批量元数据),curl 和 SDK 表现不错,有时还更轻量。但随着任务变得更复杂并涉及多个依赖步骤,智能体必须手工编写整条 REST 调用链(或翻找 SDK),成本就会暴涨:在创建带分支和标签的仓库、删除文件、跨仓库复制或同步存储桶时,达到 CLI 的 2.4 倍到 6 倍。hf CLI 让智能体可以把任务表达为几个更高层的命令,而不是精心构造复杂工作流。
关键发现
hfCLI 比 curl 或 SDK 精简得多。对于同样的任务,在成功率相同或更高的情况下,curl 和 SDK 消耗的 token 大约是 1.3× 到 1.8×。在简单的读取任务上它们没问题,但在真正的多步骤工作中,它们要付出 2× 到 6× 的代价:CLI 把一连串 REST 调用组合成几个高层命令,而 curl 或 SDK 每次运行都要手动重新推导这条链。- 在更强的模型上,curl 和 SDK 能用,但依然浪费。在 Sonnet 上它们无法完成部分工作(主要是写入);在 GPT-5.5 上它们大多能成功,能正确地手写 REST 调用(或使用 SDK),但付出的 token 账单仍远高于 CLI。
hf-cli 技能
hf 附带一个技能:一份整个命令面的紧凑参考,agent 将其作为上下文加载。它从实时的 hf 命令树自动生成,每个命令一行(其签名、一行描述,以及重要的标志),按资源分组,并附有常见选项的简短词汇表。它有意跳过那些不言自明的标志,以保持简洁、对上下文负担轻,并且每次发布都会重新生成。运行 hf skills preview 可打印它,或用以下方式安装:
# for Codex, Cursor, OpenCode, Pi and other agents that load skills from `.agents/skills`
hf skills add
# includes the above + Claude Code
hf skills add --claude
它能带来什么?主要是让 agent 不再靠猜。最清晰的一个视角是每次运行需要多少条命令,有技能和没有技能对比:
在两个 agent 上,每个任务从大约十条命令降到大约七条,工具调用大约减少 30%。这是因为 agent 不再为了找到正确的命令和参数而反复试探 --help。技能不会削减你的 token 账单,因为它会在上下文前附加一段固定信息,所以同一任务的 token 大致不变或略微上升。技能也不会让 CLI 更可靠,但它能帮助 agent 把时间花在运行你的任务上,而不是去弄清楚工具怎么用。在使用 hf 搭配本地模型时,这可能特别有帮助。
我们在全新会话中运行每个任务,所以技能在每个任务上都要付出其上下文成本。在真实的多任务会话中,这个成本会被摊薄(agent 只需了解一次命令面),因此 token 情况在那里可能会改善;我们没有测量这种情况。
自己试试
我们对这一切做了基准测试,因为我们认为这很重要。Agent 正在成为 Hub 的真实用户:它们训练模型、构建和清理数据集,并以 Spaces 形式发布演示,几乎总是代表某个人。一个对 agent 好用的 Hub,也是一个对使用它们的人更好用的 Hub。Agent 的工具越好,它就能为你做越多的事。
如果你的 agent 与 Hugging Face Hub 交互,我们建议给它 hf CLI:
# macOS / Linux
curl -LsSf https://hf.co/cli/install.sh | bash
# Windows (PowerShell)
powershell -ExecutionPolicy ByPass -c "irm https://hf.co/cli/install.ps1 | iex"
然后交给它技能,这样它从第一轮起就了解整个命令面:
hf skills add # Codex, Cursor, OpenCode, Pi and other agents that load skills from .agents/skills
hf skills add --claude # the above + Claude Code
然后把你的 agent 指向 Hub,让它工作。确保你已登录(hf auth login),然后给它一个这样的提示:
Use `hf` to list my Hugging Face Hub models, datasets, and Spaces.
Take a look at how I am currently using the Hub and suggest a few ways you could help me.
它会自己推导出命令,并带回有用的结果。
完整的命令参考见 hf CLI 指南。
注册 agent harness
正在构建 agent harness?把它注册起来!这样 hf 才能学会检测它,Hub 也才能把其流量归因到你的 harness。你只需开一个小 PR,向 agent-harnesses.ts 添加一个条目。更多细节请阅读 注册你的 agent harness 指南。
来源:Hugging Face Blog · huggingface.co