Hugging Face 把 hf CLI 改造成面向智能体的命令行工具并给出基准测试
Designing the hf CLI as an agent-optimized way to work with the Hub
Hugging Face 重新设计官方命令行工具 hf CLI,使其同时服务人类用户和编码智能体,通过读取 CLAUDECODE、CODEX_SANDBOX、AI_AGENT 等环境变量自动切换到智能体模式:输出 TSV、保留完整 id 与 ISO 时间戳、不截断、无 ANSI 转义。
原文给出 CLI 面向智能体重构的渲染、hint 与基准数据,读者可据此评估智能体调用 Hub 的 token 成本。
hf 是 HF Mirror 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()等日志记录方法,它们以原始数据为输入并处理格式化。除了人类和智能体模式外,我们还引入了--json和--quiet选项,以便更轻松地将命令串联起来。默认模式会根据上下文自动选择,但用户始终可以通过--format human | agent | json | quiet强制使用自己选择的格式。
下一条命令提示
CLI 命令很少孤立运行:一步通常暗示着下一步(git add,然后git commit)。许多hf命令现在以提示结尾:即确切的下一步要运行的命令,并预先填入你刚使用过的 ID,这样用户或智能体可以直接衔接到下一步,而不必从头推导。在后台启动一个 Job,它会指向其日志;创建一个 Space,它会指向其启动状态:
$ hf jobs run --detach python:3.12 python train.py
✓ Job started
id: 6f3a1c2e9b
url: https://hf-mirror.com/jobs/celinah/6f3a1c2e9b
Hint: Use `hf jobs logs 6f3a1c2e9b` to fetch the logs.
对人类来说这是一种便利。对智能体来说这是一条轨道:下一个动作已被命名、用正确的 ID 参数化,并随时可运行,因此它推导该做什么所需的步骤更少。错误的行为方式也一样,会指出修复方法,而不只是失败:
Error: Not logged in. Run `hf auth login` first.
提示、警告和错误都输出到 stderr,而数据输出到 stdout,因此这些指引都不会污染智能体正在解析的输出。
非阻塞且可安全重试
hf绝不会卡在交互式提示上等待智能体按不了的键。破坏性命令仍会要求人类确认,但在智能体模式下它会快速失败,并在消息中给出修复方法(Use --yes to skip confirmation.),而-y/--yes会跳过它。而且由于智能体会在超时和上下文丢失时重试,各项操作都被设计为可安全重复:如果仓库已存在,hf repos create --exist-ok是空操作,重新运行上传会干净地重新提交。另外,那些移动真实数据的命令接受一个--dry-run,它会在运行前准确显示将要传输的内容,这对人类和智能体都很方便,因为双方都不必承诺进行一次长时间下载或盲目同步:
# 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都以真实、可复制粘贴的示例结尾(智能体匹配这些示例的速度远快于解析描述):
$ 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),因此智能体一旦学会一个命令,就能猜出其余的。而且输出可以组合:-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 是否真的对智能体更高效,我们进行了测量。我们构建了一个小型评估框架,并通过每种驱动 Hub 的方式对同一组 Hub 任务运行了多轮,每次运行都针对实时 Hub 进行评分。在介绍方法之前,先给出要点:在两个智能体上,hf CLI 都胜出,在复杂的多步任务上最为明显,因为它使用的 token 少得多。
| agent | tool | 成功分数 | 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 部分中单独列出。代表性转录记录发布在 这个 bucket 中。)
设置
我们定义了 18 个非平凡的 Hub 任务。不是“下载一个文件”,而是你实际会提出的那种请求:聚合一个热门组织的模型、检查某个仓库的文件及其大小、按包含/排除规则上传文件夹、删除文件、跨仓库复制文件、发起一个添加许可证的 PR、创建一个带分支和标签的仓库、同步并清理一个 bucket、构建一个 collection。每个任务都交给一个全新的编码智能体,且只有一种方式与 Hub 通信:
hfCLI,或- curl / Python SDK:完全没有
hfCLI,因此智能体只能退而使用curl调用 REST API 或huggingface_hubPython 库。
我们以两种配置运行 hf CLI,带或不带其 skill(一份生成的命令参考,我们会在它自己的部分中再谈)。但下面最重要的比较很简单,就是 hf CLI 对比 curl / SDK;skill 的增量效果小到我们把它单独列出,而不是挤进主要结果里。
配置是刻意保持干净的:每次运行使用全新实例,没有自定义 MCP 服务器,没有 CLAUDE.md 或 AGENTS.md,上下文中没有任何会引导行为的东西。任务和工具被放进单个提示中,智能体以 TASK_COMPLETE 或 TASK_FAILED 标记结束,但我们不信任这个标记(智能体会对从未落地的工作报告成功),所以我们通过重新查询实时 Hub独立地给每次运行评分:分支真的创建了吗,文件真的没了吗,bucket 存在吗?每个任务/工具组合运行 10 次,因为编码智能体是非确定性的,每个智能体大约 520 次运行(18 个任务 × 3 种工具 × 10 次重复,减去一个可计费 Jobs 任务的上限),总共有约 1,000 次评分运行。我们把整个过程跑了两次,使用两个最流行的编码智能体(Claude Code 搭配 Sonnet 4.6,以及 OpenAI Codex 搭配 GPT-5.5)。
结果
下面两张图表拆解了上面的表格。首先,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),成本就会暴涨:在创建带分支和标签的仓库、删除文件、跨仓库复制或同步 bucket 时,达到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 的形式发布 demo,几乎总是代表某个人来完成。一个对 agent 好用的 Hub,也是一个对使用它们的人更好用的 Hub。Agent 的工具越好,它能为你做的事就越多。
如果你的 agent 与 HF Mirror 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 HF Mirror 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 运行框架
正在构建 agent 运行框架?去注册它! 这样 hf 才能学会检测它,Hub 也才能将其流量归因于你的运行框架。你只需开一个小 PR,向 agent-harnesses.ts 添加一个条目。更多细节请阅读 注册你的 agent 运行框架 指南。
来源:Hugging Face Blog · hf-mirror.com