第 5 章讲完了 Hermes 的技能系统,我们已经知道怎么给 Agent 装上新能力。但有一个更底层的问题值得聊聊:当 Agent 需要调用外部能力时,为什么它更倾向于用 CLI 而不是 API?
这一节从程序员最熟悉的 API 讲起,梳理从「万物皆 API」到「Agent 更爱 CLI」的范式转变。理解了这条脉络,才能明白 Hermes 这样的工具为什么长成现在这个样子。
2.1 当系统需要外部能力,我们第一反应是什么
答案几乎是条件反射式的:调 API。
这已经成了程序员的本能。想查天气?调天气 API。想发短信?调短信 API。想对接支付?调支付 API。过去二十年,整个软件行业都在围绕 API 构建系统——微服务之间通过 API 通信,前后端通过 API 交互,第三方集成还是通过 API 完成。
API 这个词有广义和狭义两层含义。广义上,任何「应用程序编程接口」都算 API,操作系统提供的文件读写函数是 API,数据库提供的查询接口也是 API。但今天大家嘴里说的 API,绝大多数时候指的是狭义的 API——也就是 RESTful API(或者它的兄弟们:GraphQL API、RPC 等)。
这类 API 通常是一个跑在远端的 HTTP 服务,你发请求,它返回 JSON。以前除了 JSON 还有 XML,但现在基本已经被弃用了。
这种狭义的 API 模式统治了太长时间,以至于我们很少去想一个问题:它真的是 Agent 调用外部能力的最佳方式吗?
2.2 RESTful API:为人类设计的,不是为 Agent 设计的
RESTful API 的设计哲学,处处都带着人类工程师的痕迹。
先看一个典型的 API 调用流程。假设你想让程序把一张图片上传到某个云存储服务:
1. 先调 POST /auth/token 拿到访问令牌
2. 再调 POST /upload/init 创建上传任务,拿到 upload_id
3. 调 PUT /upload/{upload_id}/chunk 分片上传文件
4. 最后调 POST /upload/{upload_id}/complete 确认上传完成
5. 如果任何一步返回了 4xx/5xx 错误码,还得自己处理重试逻辑
这五步里,每一步都有固定的 URL、固定的请求方法、固定的请求头、固定的参数格式、固定的错误码体系。这些「固定」是给人看的——人类工程师读文档、理解流程、写代码把五步串起来。
RESTful API 本质上是给人类程序员设计的契约。 它假设调用方具备以下能力:
- 能读懂 API 文档,理解每个参数的含义和约束
- 能处理认证、鉴权、令牌刷新这些安全流程
- 能编写代码把多个 API 调用编排成一个完整的业务流程
- 能解析 JSON 响应,根据错误码决定重试还是报错
- 能处理分页、限流、超时这些边界情况
这些能力对人类来说已经是肌肉记忆了,但对 Agent 来说,每一个都是额外的负担。
2.3 Agent 调 API 的四个缺陷
让 Agent 去调用 RESTful API,技术上完全可行,但用起来就是别扭。具体别扭在哪?
第一,发现成本高。 Agent 要使用一个外部服务,首先得知道这个服务有哪些 API、每个 API 的参数是什么。这些信息通常藏在文档网站里,有些文档还不全、版本还对不上。Agent 要么事先被灌入完整的 API 文档(占上下文窗口),要么自己去爬文档(不稳定)。相比之下,CLI 工具的 --help 一条命令就能列出所有能力,Agent 读起来轻松得多。
第二,编排复杂。 一个业务流程往往要调多个 API,而且步骤之间有依赖关系——上一步的返回值是下一步的输入。人类工程师用代码把这些调用串起来,逻辑清晰、可控。但 Agent 要用自然语言推理来编排这些调用,每一步都要构造 HTTP 请求、解析 JSON 响应、提取字段、填入下一个请求。步骤越多,出错的概率越大,消耗的 Token 也越多。
第三,状态管理麻烦。 RESTful API 天然是无状态的——每次调用都是独立的,状态要调用方自己维护。上传文件要自己记 upload_id,创建订单要自己记 order_id,发起支付要自己记 transaction_id。人类写代码用变量存就行了,Agent 得在上下文窗口里记住这些中间状态,还要确保不弄混。
第四,错误处理脆弱。 API 的错误码体系五花八门——有的用 HTTP 状态码,有的在 JSON body 里塞一个 error_code 字段,有的直接返回 200 但 body 里有个 success: false。每对接一个新 API,Agent 就得适应一套新的错误表示方式。而 CLI 工具把这些复杂性都屏蔽了——成功就返回 0,失败就返回非 0,错误信息直接打在 stderr 上,简单直接。
总结一下:RESTful API 是为「人类写代码调用」而优化的,不是为「Agent 直接调用」而优化的。 它灵活、标准、可编程,但这些优点主要是对人类程序员而言的。
2.4 CLI:Agent 时代的天然接口
有意思的是,Agent 调用外部能力时,更自然的方式反而是看起来更「古老」的 CLI。
CLI(Command Line Interface,命令行界面)工具,就是我们在终端里敲的那些命令。git、docker、kubectl、aws、gh、ffmpeg、curl……这些工具陪伴程序员几十年了。其实这本书里我们一直在用的 hermes 本身也是一个 CLI——你在终端里敲下 hermes 启动它,通过命令行和它对话,这就是标准的 CLI 交互。这些工具在 Agent 时代焕发出了新的生命力。
为什么 CLI 对 Agent 更友好?
一条命令就是一个完整的能力单元。 gh pr create --title "Fix bug" 一条命令就创建了一个 PR。Agent 不需要知道背后调了哪些 GitHub API、怎么拼请求头、怎么处理分页。CLI 工具把这些复杂性全部封装了,对外暴露的是一个简洁的、语义明确的命令。
输出是结构化的文本。 大多数现代 CLI 工具都支持 JSON 输出(--output json)或者格式化的表格输出。Agent 可以直接解析这些文本来获取结果,不需要处理复杂的 HTTP 响应头和状态码。
错误信息是给人看的。 CLI 工具的错误信息通常是自然语言描述——Error: repository not found、Error: permission denied。这些信息 Agent 理解起来毫无障碍,比解析一个 {"error": {"code": 404, "message": "Not Found", "documentation_url": "..."}} 要直接得多。
--help 就是最好的文档。 Agent 想知道一个 CLI 工具能做什么?跑一下 tool --help 或者 tool subcommand --help,所有能力、所有参数、所有选项一目了然。不需要爬文档网站,不需要猜版本号。
天然支持管道组合。 多个 CLI 命令可以通过管道串起来,前一个命令的输出直接作为后一个的输入。这种组合方式对 Agent 来说非常自然——它只需要规划好「先用 A 工具做这一步,再用 B 工具做下一步」,不需要写代码来编排。
来看看实际对比。同样是「把一份 Markdown 报告上传到飞书文档」这个任务:
Agent 调 RESTful API:
1. 推理:需要先拿到租户访问令牌
2. 构造 HTTP POST 请求到 https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal
3. 请求体带上 app_id 和 app_secret
4. 解析响应 JSON,提取 tenant_access_token
5. 推理:需要创建一篇飞书文档
6. 构造 HTTP POST 请求到 https://open.feishu.cn/open-apis/docx/v1/documents
7. 请求体带上 title 和 folder_token
8. 解析响应,提取 document_id
9. 推理:需要把 Markdown 内容转成飞书 Block 格式写入文档
10. 构造 HTTP POST 请求到 https://open.feishu.cn/open-apis/docx/v1/documents/{document_id}/blocks/{block_id}/children
11. ...
Agent 调 CLI:
lark-cli docs import ./report.md --title "季度报告"
一个要推理九步,一个只需要一条命令。差距不在速度上,而在认知负担上。Agent 的上下文窗口是有限的,每多一步推理就多一分出错的风险,也多消耗一批 Token。CLI 把十步压缩成一步,Agent 的大脑就腾出来做更重要的事情——理解用户意图、规划整体任务、检查结果是否正确。
2.5 越来越多的工具在提供 CLI
如果你留意,会发现一个明显的趋势:近几年发布的新工具,几乎都会同时提供一个 CLI 版本。
国外的老牌工具不用多说:
- GitHub 有
gh - AWS、Azure、GCP 各有自己的 CLI
- Docker 有
docker - Kubernetes 有
kubectl - Vercel 有
vercel
国内这边,2026 年春天发生了一件有意思的事:飞书、钉钉、企业微信在 72 小时内集体开源了官方 CLI。
- 飞书 CLI(
lark-cli):200+ 命令,覆盖消息、文档、多维表格、日历、邮箱、会议等 11 个业务域,还内置了 24 个 Agent Skills,开源 47 天星标破万 - 钉钉 Workspace CLI(
dws):首批开放 AI 表格、日历、待办、机器人、通讯录、DING 消息等 10 项能力 - 企业微信 CLI(
wecom-cli):开放消息、日程、文档、智能表、会议、待办、通讯录 7 大核心能力
三家几乎同时动手,不是巧合——他们都意识到 CLI 不再只是程序员的效率工具,而是 Agent 进入企业工作流的入口。钉钉高层在发布会上说的那句话很到位:「过去是人用钉钉来工作,未来是 AI 用钉钉来工作。」
更有意思的是,CLI 的浪潮不只在办公场景。连网易云音乐都把自己的搜索、推荐、播放控制封装成了 CLI(ncm-cli),成了业内首个向 Agent 开放核心能力的音乐平台。你可以直接跟 Agent 说「推荐几首适合深夜写代码的歌」,它自己调 ncm-cli 搜歌、建歌单、开始播放。B 站也有 CLI,支持视频投稿、数据统计、互动管理。
从办公到娱乐,从工作流到内容创作,CLI 正在成为 Agent 连接各种产品的通用接口。
2.6 为什么这些产品纷纷推出 CLI
这么多产品几乎同时推出 CLI,背后有一个很现实的考量:在 Agent 时代,如果你的产品不能被 Agent 调用,对 Agent 来说你就不存在。
想想看。用户跟 Agent 说「帮我推荐几首适合写代码的歌」。如果网易云音乐有 CLI,Agent 一条命令就搜到歌、建好歌单、开始播放,用户体验丝滑。如果网易云音乐没有 CLI,只有 API,Agent 得自己拼 HTTP 请求、处理认证、解析 JSON——步骤多、出错概率高、Token 消耗大。Agent 大概率会放弃,转而用其他方式完成任务。
用户不会觉得「哦,网易云音乐没有 CLI 所以用不了」。用户只会觉得「这个 Agent 连听歌都搞不定,不好用」。
这就是为什么这些产品急着出 CLI——不是为了程序员,是为了让 Agent 能顺畅地调用自己。
飞书、钉钉、企业微信在 72 小时内集体开源 CLI,也是同一个逻辑。企业用户开始用 Agent 处理工作了,如果你的办公工具不能被 Agent 调用,用户就会换到能被调用的那个。钉钉高层说「过去是人用钉钉来工作,未来是 AI 用钉钉来工作」——这句话的潜台词是:如果 AI 用不了钉钉,用户就会去找 AI 能用的工具。
网易云音乐更明显。音乐平台那么多,QQ 音乐、酷狗、Apple Music……谁先让 Agent 能顺畅调用,谁就多一个被用户选择的理由。网易云音乐选择开放 CLI,本质上是在争夺 Agent 时代的入口。
这跟当年移动互联网刚兴起时,各家纷纷做 App 是一样的道理。那时候你的产品没有 App,用户就觉得你不正规。现在你的产品没有 CLI,Agent 就觉得你不好用。CLI 正在成为产品在 Agent 时代的「入场券」。
2.7 不是说 API 不重要
说到这里,需要做一个重要的澄清。
API 仍然是软件世界的基石。 微服务之间通过 API 通信,前后端通过 API 交互,第三方服务通过 API 集成——这些场景不会改变,也不应该改变。API 的标准化、可编程、可编排的特性,是构建大规模分布式系统的基础。
CLI 也不是万能的。 需要精确控制请求参数、处理复杂业务逻辑、编写可复用的集成代码时,直接调 API 仍然是正确的选择。
这一节想说的是:当调用方从「人类程序员」变成「AI Agent」时,CLI 是一个比 RESTful API 更自然的接口。 这不是技术上的倒退,而是接口设计终于从「为人设计」转向了「也为 Agent 设计」。
我们不应该让 Agent 去处理 HTTP 请求头、解析嵌套 JSON、管理认证令牌这些本可以被封装掉的复杂性。CLI 把这些复杂性封装好了,留出来的是一个干净的、语义明确的、Agent 友好的接口。
2.8 最后
API 是人与人之间的契约,CLI 是 Agent 与机器之间的桥梁。 在 Agent 时代,CLI 不是过时的遗产,而是被重新发现的最佳实践。
理解了这一点,就能理解 Hermes 的架构设计为什么把终端命令执行作为核心能力。接下来的几节,我们来看看 Hermes 具体是怎么通过 CLI 来完成各种任务的。
最后,容我多说一句。
很多人说程序员是最早被 AI 替代的一批人。这话对,也不对。对的部分是——AI 确实在快速接管我们以前亲手干的活:写代码、调 API、排 bug、部署服务,这些以前要花几个小时的事情,现在一句话就能搞定。不对的部分是——正因为我们是写代码的人,Agent 用的 CLI 是我们写的,Agent 调的工具是我们造的,Agent 跑的环境是我们搭的。程序员是最早被 AI 替代的,但也是最晚被完全替代的。
所以与其焦虑「我会不会被替代」,不如想想「我能不能成为那个指挥 Agent 的人」。
2.9 ■ 学点英语
| 中文 | English | 音标 | 说明 |
|---|---|---|---|
| 命令行界面 | Command-Line Interface | /kəˈmænd laɪn ˈɪntərfeɪs/ | 通过文本命令与程序交互的界面 |
| 应用程序接口 | Application Programming Interface | /ˌæplɪˈkeɪʃən ˈproʊɡræmɪŋ ˈɪntərfeɪs/ | 软件之间互相调用能力的接口 |
| 交互模式 | Interaction Pattern | /ˌɪntərˈækʃən ˈpætərn/ | 用户与系统交换信息和触发能力的方式 |
| 能力封装 | Capability Encapsulation | /ˌkeɪpəˈbɪləti ɪnˌkæpsjuˈleɪʃən/ | 把复杂功能包装成稳定接口的做法 |