当一切软件都在「CLI 化」:Agent 时代,为什么命令行才是终极接口?

4 阅读10分钟

当一切软件都在「CLI 化」:Agent 时代,为什么命令行才是终极接口?

本文综合自多篇关于 CLI 与 Agent 的深度分析,结合个人思考整理而成。

一个正在发生的现象

2026 年初,一个反直觉的趋势正在席卷整个技术圈:越来越多的大厂,正在把自家的产品「压扁」成命令行。

钉钉发布了「悟空」平台,宣布全面 CLI 化。飞书紧随其后,开源了 Go 语言编写的 lark-cli,2500+ API 端点全覆盖。两家都不约而同地——没有选择 MCP

这不是个案。Composio 发布了 Universal CLI,ScaleKit 用严格的 benchmark 证明 CLI 比 MCP 在 token 消耗上便宜 10 到 32 倍。旧金山街头的随机投票,CLI 以 17:3 压倒性胜出。

一个曾经被认为「只有程序员才用」的古老界面,正在成为 AI Agent 时代最核心的软件入口。

为什么?


CLI 是 LLM 的母语

要理解这个趋势,得先理解一件事:Agent 是怎么「想」的。

LLM 的训练数据里有数十亿行 shell 命令、man page、Stack Overflow 问答和 bash 脚本。CLI 对它来说,不是需要学习的新工具,而是与生俱来的「母语」。相比之下,MCP 那套 JSON Schema 定义和协议握手,更像是后天学的外语。

ScaleKit 做了一组严格的对照实验,拿 GitHub 官方 MCP 服务器和 gh CLI 做对比,跑了 75 轮:

  • Token 消耗:CLI 比 MCP 便宜 10~32 倍。查一个仓库用什么语言,CLI 只需 1,365 tokens,MCP 需要 44,026 tokens。
  • 可靠性:CLI 25 次全部成功,MCP 成功率仅 72%,28% 的失败率全是 TCP 层面的超时。
  • 月成本:1 万次操作,CLI 约 3.2 美元,MCP 约 55.2 美元。17 倍的差距。

问题出在 MCP 的 schema bloat。GitHub 的 MCP 服务器有 43 个工具定义,每次对话都得把所有工具的完整描述塞进上下文。你只是想查个仓库语言,模型却得先读完 43 本说明书。

而 CLI 呢?Agent 只需要按需跑一下 --help,只读当前需要的那一条命令的说明。

一个按需查询,一个全量注入。这是架构层面的效率鸿沟。


从「给人类用」到「给 Agent 用」

但 CLI 并不是天生就适合 Agent 的。传统的 CLI 设计规范,是给人类设计的。Agent 有完全不同的认知特点和失败模式。

Berkeley 最新的 BFCL V4 显示,即使最强的模型,在复杂多步工具调用场景下准确率也达不到 100%。Surge AI 的一个案例更直观:让一个前沿模型处理只需改 2 行代码的问题,它走了 39 轮对话,改了 693 行代码,最终还是失败了——因为第一步就幻觉出了一个不存在的类名,然后在错误的基础上越陷越深。

好的 CLI 设计,需要帮 Agent 减少它需要猜的东西,增加它能验证的东西。

这就是「Agent 友好的 CLI」设计哲学的核心。


给 Agent 造 CLI,需要注意什么?

综合业界最佳实践和实际案例,以下是面向 Agent 的 CLI 设计中最关键的几个维度:

一、命令结构:名词在前,动词在后

命令用 noun-verb 结构,比如 docker container lslark-cli calendar +agenda

因为 Agent 发现命令的过程本质上是一个树搜索。先跑 --help 看到名词分类,再在某个分类下找具体动作。这是一个确定性的、逐层缩小范围的过程。而 verb-noun 结构把所有操作平铺成扁平列表,没有层级引导。

Docker 是典范:containerimagevolume 是名词,lsrmcreate 是动词。Agent 学会了 docker container ls,就能推断出 docker volume ls

二、长参数优先,短参数可选

--verbose-v 好。因为 -v-V 一个字母的大小写差异可能意味着完全不同的功能(verbose vs version)。而 --verbose--version 之间不存在混淆风险。

LLM 在训练数据中见过无数次 --output,它和「指定输出位置」的语义绑定经过了海量样本的强化。而 -o 的语义绑定弱得多,在不同工具中可能指代完全不同的东西。

对 Agent 来说,多花几个 token 用长参数,换来的是大幅降低的出错概率。

三、输出是 API 契约

JSON 数据走 stdout,进度条、警告、日志全走 stderr。这样 Agent 可以安全地用管道处理,不用担心非 JSON 内容污染数据流。

GitHub CLI 做得最好:检测到输出被管道传输时,自动切换为 tab 分隔格式,去掉颜色转义符。飞书 CLI 支持 JSON、NDJSON、table、CSV、pretty 五种格式。

关键原则:结构化输出一旦发布,就是 API。 加字段安全,改字段类型或名称就是破坏性变更。

四、感知运行环境

CLI 应该检测自己跑在终端(TTY)还是管道(pipe)中。Agent 几乎永远在非 TTY 环境中调用 CLI。如果你的 CLI 在非 TTY 时还弹确认框、显示 spinner、输出 ANSI 颜色码,Agent 就会卡住或解析出错。

更理想的做法:非 TTY 环境下默认输出 JSON,不该要求 Agent 额外加 --json flag。

五、干跑优先

每个会产生副作用的命令都应该支持 --dry-run。这给 Agent 提供了一个零成本的试错机制——先看看会发生什么,再决定是否真正执行。

Lightning Labs 甚至给 --dry-run 定义了专门的退出码(exit code 10),这样 Agent 可以通过退出码区分「干跑成功」和「真正执行成功」。

六、退出码要有语义

对人类来说,退出码是可以忽略的细节。对 Agent 来说,退出码是控制流本身。

只用 0 和 1 远远不够:

退出码含义Agent 应对
0成功继续执行
1一般错误读 stderr 诊断
2参数错误修正参数重试
3资源不存在跳过或创建
4权限不足提示用户授权
5冲突/已存在跳过或更新

七、错误信息要能指导修复

Agent 犯了错之后,错误信息是它唯一的修复依据。好的错误信息应该包含四个要素:

{
  "error": "permission_denied",
  "message": "缺少 calendar:read 权限",
  "suggestion": "运行 lark-cli auth login --domain calendar 授权",
  "retryable": false
}

错误类型(机器可读)、描述(发生了什么)、修复建议(怎么解决)、是否可重试。飞书 CLI 在权限不足时会自动告诉你缺什么权限、怎么补——这个设计对 Agent 特别友好。

八、幂等设计

Agent 会重试。网络超时重试、执行结果不确定重试、任务中断后恢复还是重试。如果命令不是幂等的,重试就可能创建两个重复用户、发送两封重复邮件。

能用声明式就别用命令式:mytool user ensure --name "john"mytool user create --name "john" 更安全。飞书 CLI 的 +messages-send 支持 --idempotency-key 参数,即使命令被重复执行,服务端也只处理一次。


造 CLI 的门槛,已经降到了「写清楚需求就行」

说完了设计原则,一个更实际的问题:怎么造?

2026 年造 CLI 的门槛已经低到前所未有的程度。

框架成熟

五大主流 CLI 框架已经非常成熟:

  • Go / Cobra(43,500 星):kubectldockergh 全是它造的。子命令树管理、自动生成 --help、shell 补全,中大型 CLI 的首选。飞书 CLI 用的就是它。
  • Rust / Clap(10,000+ 星):ripgrepbatfd 背后的引擎。追求极致性能和类型安全。
  • Python / Typer(18,300 星):FastAPI 作者出品,几行代码出一个功能完整的 CLI。适合快速原型。
  • Node.js / Commander.js(28,000 星):零依赖,启动 18 毫秒,Node.js 栈的默认选择。
  • Java / Picocli(5,200 星):支持 GraalVM native image 编译,Java 生态的现代 CLI 选择。

对大多数场景来说,Go + Cobra 依然是最稳的选择。不是因为它最强,是因为它从「造出来」到「分发出去」这条路径最短——单二进制文件,一行 curl 安装。

AI 辅助开发

现在的流程大概是:

  1. 整理设计规范(命令结构、参数命名、输出格式等)
  2. 喂给 Coding Agent(Claude Code / Codex)框架知识和业务需求
  3. 生成命令树骨架,调整参数命名和边界情况
  4. 两三轮迭代定型

整个过程,从零到 80 分的代码,以前可能要一两周,现在可能只需要 2 小时。瓶颈不再是「怎么写代码」,而是「怎么把需求描述清楚」。


CLI 的三波浪潮

回头看 CLI 这五十年,其实就是三波浪潮。

第一波(1970~1995),Unix 黄金期。 一群天才在贝尔实验室和伯克利造出了 lsgrepawksedpipe,奠定了命令行的基石。每一个命令都算得上是一件精密的手工艺品。

第二波(2015~2024),终端文艺复兴。 Go 和 Rust 让分发变简单了——单二进制文件,一行 curl 安装。Rust 社区把经典工具重写了一遍:ripgrepgrep 快 10 倍,batcat 加了语法高亮和行号,fdfind 的语法更直觉。CLI 不再是「难用但高效」的代名词,它变好用了。但这还只是给人类用的。

第三波(2024~现在),Agent 时代。 Agent 让 CLI 从开发者的效率工具升级为软件的通用入口。AI 让造 CLI 的门槛降到了「写清楚需求就行」。钉钉和飞书官方亲自下场,两家都选了 CLI 而非 MCP。

一个反直觉的现象出现了:人机交互经历了「命令行 → 图形界面 → 触屏」三次升级后,Agent 时代又回到了命令行。 不是从旧到新,而是从新回到旧——因为 GUI 是给人类视觉系统设计的翻译层,Agent 不需要这个翻译层。


MCP 会死吗?

倒也不会。

它会退到它该待的地方:开放生态的接入协议层。就像 SOAP 没有死,只是退回到了企业内部集成的角落。

Smithery 在《MCP vs CLI Is the Wrong Fight》中给了更精确的判断:CLI 赢在 LLM 已有训练先验的本地工具(gitdockerffmpeg 这些),MCP 赢在零训练数据的远程内部 API。CircleCI 也给了类似结论:内循环用 CLI(速度和 token 效率),外循环用 MCP(团队规模和结构化鉴权)。

MCP 是给陌生人设计的安检流程,CLI 是给自家人用的厨房工具。 硬把安检流程套在自家人身上,除了浪费时间,没有任何安全增益。

而 CLI,将成为 Agent 操作一切软件的默认界面。


写在最后

CLI 已经 50 岁了。但你如果今天造一个,可能比任何时代都更应该。

框架在,工具在,规范在,速度在。Agent 正在成为软件的主要用户,它不点按钮、不填表单、不看界面。它说的是命令行的语言。

把你的产品能力暴露为 CLI,很可能已经不是可选项了。

当你的用户从人变成了 AI,你就该用 AI 最擅长的方式暴露你的能力。这不是技术的倒退,而是交互本质的回归——去掉一切不必要的翻译层,让能力以最直接的方式被调用。

下一个被 CLI 化的,会是什么?


参考资源: