深夜提醒

现在是深夜,建议您注意休息,不要熬夜哦~

🏮 🏮 🏮

新年快乐

祝君万事如意心想事成!

share-image
ESC

面向 Agent 的命令行工具(CLI)最佳设计实践

在 Agent 时代,命令行工具(CLI)正在从”工程师的手工工具”蜕变为”AI Agent 的天然执行面”。本文系统梳理为什么 Agent 时代反而更需要 CLI、如何设计 Agent 友好的 CLI,并结合 OpenCLI、CLI-Anything 以及钉钉、飞书、谷歌 Workspace、Stripe 等实际案例展开分析。

Agent-Native CLI

参考来源:莫尔索 - 面向 Agent 的命令行工具(CLI)最佳设计实践

为什么 Agent 时代反而更需要 CLI

过去很多人把 CLI 看成”给工程师手工敲命令的老工具”,而在 Agent 时代,这个判断反而过时了。对于大模型驱动的 Agent 而言,CLI 并不是落后的接口,而是最天然的一类执行面:

  • 它是文本输入、文本输出,和 LLM 的工作方式天然匹配
  • 它通常自带 --help--version、退出码、标准输出/错误输出,具备自描述性
  • 它容易组合,适合被 shell、脚本、CI/CD、子 Agent 链式调用
  • 它不要求额外协议栈,部署和运行成本低

更重要的是,Agent 不会像人一样脑补一个 CLI 的意图——它需要明确的命令、清晰的参数、结构化的输出。

CLI 是 Agent 的理想接口

1. CLI 比 GUI 自动化更稳定

GUI 自动化依赖截图、DOM、像素、焦点状态和时序,天然脆弱。CLI 只要求明确的命令、参数和输出,状态面更小,可复现性更强。

2. CLI 比直接调 API 更接近 Agent 的工作流

API 本身当然重要,但 Agent 不一定擅长从零拼装 HTTP 请求、认证方式、分页逻辑和错误恢复。设计良好的 CLI 已经把这些复杂性收敛成命令语义,Agent 可以直接发现并调用。

3. CLI 比很多 MCP 包装器更轻

MCP 适合做权限治理、工具注册、上下文注入和多工具编排,但并不是所有事情都值得单独做成 MCP Server。很多 MCP 本质上只是把已有 CLI 再包一层。如果底层 CLI 已经设计得足够好,直接调用 CLI 常常更便宜、更快,也更符合 Unix 的组合哲学。

Mario Zechner 在 MCP vs CLI 基准测试 中对比了 terminalcp 的 MCP 版本和 CLI 版本,结果很有代表性:两者都达到了 100% 成功率,差异更多来自工具设计本身,而不是协议名字本身。

协议只是管道,接口质量才是决定 Agent 成败的核心。

讨论 CLI 和 MCP 时,一个常见误区是把它们当成互斥方案。更准确的理解应该是:

  • CLI 是执行接口——先把底层能力做成稳定、可组合、可脚本化的 CLI
  • MCP 是工具分发与治理接口
  • API 是产品能力接口

这样做的好处是:

  • 人类、脚本、Agent 都能复用同一套能力
  • 文档、测试、错误码、输出契约只维护一份
  • 如果某个平台不支持 MCP,只要有 shell 就还能工作

Agent 友好 CLI 的 7 条设计原则

1. 默认非交互

任何 Agent 可能自动化的命令,都不应依赖交互式 prompt。

推荐做法:

  • 支持 --yes--force--quiet--no-input
  • 检测非 TTY 时自动禁用交互
  • 必填项都能通过 flag、stdin、配置文件或环境变量传入

原因很直接:当一个 Agent 启动子 Agent,再由子 Agent 调起 CLI 时,中间通常没有办法把”请输入 y/n”回传到最上层用户。

2. 为机器输出结构化结果

如果命令返回的是数据,而不是纯展示信息,就应该提供稳定的机器可读格式。

推荐做法:

  • 提供 --json
  • 成功结果写入 stdout
  • 警告、进度、错误写入 stderr
  • 输出字段命名稳定,不要今天叫 id 明天改成 resource_id

这是 Agent 友好的基础,否则模型只能靠脆弱的文本解析来猜。

3. 错误要能指导下一步修复

对人类可接受的报错,对 Agent 往往不够。

坏报错:

Error: missing required arguments

好报错:

Error: --content is required.
Usage: blog-cli publish --content <file> [--status <status>]
Available statuses: draft, published, scheduled
Example: blog-cli publish --content my-post.md

Agent 需要的不只是哪里错了,更是下一次怎么改才对

4. 可安全重试,边界清晰

Agent 会重试、恢复、回放。对有副作用的命令,CLI 设计必须考虑这一点。

推荐做法:

  • 幂等化创建/更新类操作
  • 提供 --dry-run
  • 危险操作必须显式确认
  • 返回可审计标识,如资源 ID、任务 ID、变更摘要

5. 帮助系统要支持渐进发现

Agent 通常不会先读完整文档,而是这样探索:

tool --help
tool subcommand --help
看一两个例子再尝试执行

因此好的 --help 至少要包含:

  • 命令用途
  • 用法形状
  • 必选参数
  • 常用例子

6. 命令结构要一致,可组合

Agent 很依赖模式学习。如果 posts list--limitcomments list 又换成 --max-results,模型就要多记一个例外。

推荐做法:

  • 相关命令复用同一套 flag 命名
  • 支持 stdin / stdout 管道
  • 保持子命令层级稳定

7. 输出要有边界,默认高信号

人类能滚动看 500 行日志,Agent 会把这 500 行一股脑放进上下文窗口。

推荐做法:

  • 默认分页/限量
  • 支持 --limit--page--since
  • 截断时告诉用户如何继续缩小范围

这不是”抠 token”,而是让模型把注意力放在真正重要的信息上。

从 Agent 友好 CLI,走到 Agent 友好产品设计

如果把前面 7 条原则再往前推一步,会发现一个更大的问题:Agent 真正消费的不只是某个命令,而是整个产品的执行面

在传统软件里,主路径通常是:

用户 → 图形界面 → 数据库

但在 Agent-native 的环境里,更常见的路径开始变成:

用户 → 用户自己的 Agent → 产品能力层 → 数据库

如果产品方也开始提供自己的 agent 或更强的工具层,这条路径还会继续演化成:

用户 → 用户 Agent → 软件 Agent → 数据库

这意味着产品团队不能只想着”把能力暴露出来”,还得思考另一件事:如何让调用你的那个 agent 更容易成功

1. 不要让 Agent 猜,要把成功条件显式写出来

人类开发者在接 API 时,愿意去翻长文档、试几次、自己脑补规则。但 Agent 往往不是这样工作的。它更像是:

  • 先看 --help
  • 再看 tool description
  • 再读一小段最相关的约束
  • 然后立刻尝试执行

所以产品如果有特殊格式要求、领域约束、对象模型差异,最好的做法不是把这些信息埋在文档站深处,而是在调用时主动交给 Agent

2. “帮助系统”不该只回答怎么调命令,还要回答怎么避免犯错

很多 CLI 的 --help 只写到”参数是什么”,但 Agent 真正需要的是:

  • 这个参数意味着什么业务语义
  • 哪些值是常见正确值
  • 遇到歧义时优先怎么选
  • 哪些写法虽然语法合法,但会导致低质量结果

因此,Agent 时代的帮助系统应该从”参数手册”升级成**”成功说明书”**。

格式规则前置的重要性

当工具没有把格式规则显式交代清楚时,Agent 往往会按”通用常识”输出,结果在人类界面里看起来就不对。问题不一定是模型不够强,而是接口没有把规则前置。

让工具自己形成反馈闭环

除了”让 Agent 知道怎么成功”,另一件事同样重要:让产品团队知道 Agent 为什么失败

1. 给每次调用加上 rationale

如果某个 CLI 或工具要求调用方附带一个 rationale 字段,说明”为什么要发起这次调用”,产品团队就能在不读取完整对话的前提下,重建很多真实任务意图。

长期来看,这些 rationale 会变成非常高价值的产品信号:

  • 哪些需求反复出现
  • 哪些场景总要绕很多步
  • 哪些工具名义上有人用,实际上只是被迫凑合

2. 给 Agent 一个”卡住时上报”的出口

大多数工具今天只定义了成功路径和报错路径,但对 Agent 来说还应该有第三条路径:受阻反馈路径

当 Agent 遇到下面这类问题时,能主动上报:

  • 我知道目标,但缺少必要上下文
  • 我试了几种写法都不符合你的规则
  • 这个工具缺少一个明显应该有的参数
  • 我拿到了数据,但无法继续推断下一步

这类反馈比普通用户的 bug 反馈更结构化,因为 Agent 天然会描述:它想做什么、它试了什么、它卡在哪一步。

3. 为关键工具补充专用上下文字段

有些上下文如果不在调用时显式带上,后面就很难还原:

  • 当前任务是在生成周报,还是在做事故复盘
  • 这是给客户看的摘要,还是内部工作笔记
  • 这次查询是为了归档,还是为了后续自动执行

为关键工具增加少量”场景型参数”,可以大幅提升后续分析和迭代效率。

设计 Agent 与产品之间的”上下文分工”

当一个 Agent 调你的 CLI、MCP 或 API 时,双方的上下文其实并不对称。

调用方 Agent 可能知道:

  • 用户最近在聊什么
  • 日历、邮件、聊天记录里的隐含背景
  • 当前任务在更大工作流中的位置

产品自己的系统更清楚:

  • 内部对象模型和字段含义
  • 权限边界与业务规则
  • 历史模式、状态机和默认策略

一个很常见的糟糕设计,是把所有内部复杂性原样抛给调用方。更好的方法是把交互设计成**”让调用方补它知道的上下文,让系统补它擅长的业务判断”**。

例如,不要要求 Agent 直接传一个生硬的内部字段编码,而应该允许它传:

  • 这是客户招待还是团队聚餐
  • 这笔支出对应哪个会议或项目
  • 是否属于个人行程

然后由系统根据自己的规则去完成最终映射。

好的执行接口,不只是参数少、输出稳,还要把参数设计在正确的抽象层级上。

CLI-Anything:把任何软件转换为 Agent 原生 CLI

CLI-Anything 是最近最有代表性的项目之一。它的目标是解决一个更底层的问题:现实世界里大量软件只有 GUI、插件接口或内部代码结构,并没有一套真正适合 Agent 消费的命令行面。

工作流程

CLI-Anything 把为现有软件生成 Agent 友好的 CLI 这件事流程化、工程化,总结为全自动 7 阶段流水线

  1. 分析:扫描目标代码库,识别可暴露的能力和内部调用路径
  2. 设计:规划命令组、状态模型、输入输出约定
  3. 实现:生成带 REPL、--help--json 的 CLI
  4. 规划测试:生成测试计划
  5. 编写测试:补齐单元测试和端到端测试
  6. 文档:生成命令文档与说明
  7. 发布:把结果打包成可安装 CLI

它的转换路径不是 录制鼠标键盘 → 回放,而是 映射为软件已有内部能力 → 生成稳定 CLI 命令,这也是它比 RPA 更适合 Agent 的原因。

典型案例

  • LibreOffice:Agent 可以真正完成文档创建、PDF 导出等动作
  • Blender:围绕场景、渲染、导出、批量参数修改构建工作流
  • GIMP / Audacity:批量裁剪、格式转换、滤镜套用、音频降噪

OpenCLI:统一 CLI Hub

OpenCLI 解决的是另一类问题:系统里已经有很多工具和网站,但 Agent 缺少统一、稳定、低成本的入口。

核心能力

  • 内建适配器:把网站动作收束成确定命令(如 opencli hackernews top --limit 5
  • Browser Bridge:复用浏览器现有登录态,安全边界清晰
  • 低层浏览器控制:open、click、type、screenshot、eval 等
  • 反向生成适配器:从浏览器行为提炼为新适配器

OpenCLI vs CLI-Anything

维度 CLI-Anything OpenCLI
主要对象 有代码库的软件 网站、浏览器、Electron、本地 CLI
核心动作 生成新的正式 CLI 统一调度和适配现有工具/网站
工作方式 代码分析 + 7 阶段流水线 适配器 + 浏览器桥接 + 命令发现
最适合场景 需要长期沉淀正式接口 需要快速接管现有工具生态

值得关注的官方 CLI 工具

GitHub CLI

命令层级清晰(gh prgh issuegh repo),帮助系统完善,很多命令支持 --json,是官方产品能力已经很好地命令化的典型。

Google Cloud CLI

支持脚本和自动化、--quiet 可关闭交互、stdout/stderr 分离、--format 支持 json/csv/yaml/value——几乎是 Agent 友好 CLI 的标准答案。

Stripe CLI

把认证、请求形状、常见开发动作封装成稳定命令,本地 webhook 转发非常适合开发自动化。

Cloudflare Wrangler

典型的”平台型 CLI”:管理 Worker 项目、部署与开发调试一体化、适合脚本和 CI。

飞书 CLI

飞书官方开源的命令行工具,强调是为 AI Agent 使用方式专门设计。覆盖消息、日历、云文档、多维表格、邮件、知识库、通讯录等能力。

企业微信 wecom-cli

“企业微信开放平台命令行工具,让人类和 AI Agent 都能在终端中操作企业微信”。覆盖通讯录、待办、会议、消息、日程、文档、智能表格。

总结:三层检查清单

1. 发现层

Agent 必须知道工具能做什么:--helplist、清晰的命令层级、可推断的命名模式。

2. 执行层

Agent 必须能稳定执行:非交互默认、幂等或可审计副作用、标准退出码、stdout/stderr 分离。

3. 解析层

Agent 必须拿到可消费结果:--json、稳定字段、默认高信号输出、支持分页/过滤/limit。

CLI 会成为 Agent 的基础设施

CLI 正在从给人类手工操作的界面,变成给 Agent 稳定消费的基础设施。

  • CLI-Anything 是在为没有 CLI 的软件补基础设施
  • OpenCLI 是在为分散的网站与工具统一基础设施
  • gh、gcloud、stripe、wrangler、飞书 CLI、wecom-cli 则说明越来越多产品开始主动把 CLI 当成正式产品面

如果你今天在设计一个面向 AI 的产品或内部工具,至少要检查:

  1. 这项能力有没有一个稳定、可发现、可脚本化的 CLI 面?
  2. 它是否支持 --help--json、非交互执行和可恢复错误?
  3. 它是否把关键格式规范、领域约束和成功条件前置给 Agent,而不是让模型自己猜?
  4. 它能否收集足够的 rationale、失败反馈和场景上下文,帮助团队持续改进工具?
  5. 如果明天接入 Claude Code、Codex、Cursor、Copilot CLI,它能否被直接消费?

真正缺的往往不是更聪明的 Agent,而是更像样的执行面。

参考来源

文章作者:阿文
文章链接: https://www.awen.me/post/83721.html
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 阿文的博客

评论

0 条评论
😀😃😄 😁😅😂 🤣😊😇 🙂🙃😉 😌😍🥰 😘😗😙 😚😋😛 😝😜🤪 🤨🧐🤓 😎🥸🤩 🥳😏😒 😞😔😟 😕🙁☹️ 😣😖😫 😩🥺😢 😭😤😠 😡🤬🤯 😳🥵🥶 😱😨😰 😥😓🤗 🤔🤭🤫 🤥😶😐 😑😬🙄 😯😦😧 😮😲🥱 😴🤤😪 😵🤐🥴 🤢🤮🤧 😷🤒🤕 🤑🤠😈 👿👹👺 🤡💩👻 💀☠️👽 👾🤖🎃 😺😸😹 😻😼😽 🙀😿😾 👍👎👏 🙌👐🤲 🤝🤜🤛 ✌️🤞🤟 🤘👌🤏 👈👉👆 👇☝️ 🤚🖐️🖖 👋🤙💪 🦾🖕✍️ 🙏💅🤳 💯💢💥 💫💦💨 🕳️💣💬 👁️‍🗨️🗨️🗯️ 💭💤❤️ 🧡💛💚 💙💜🖤 🤍🤎💔 ❣️💕💞 💓💗💖 💘💝💟 ☮️✝️☪️ 🕉️☸️✡️ 🔯🕎☯️ ☦️🛐 🆔⚛️🉑 ☢️☣️📴 📳🈶🈚 🈸🈺🈷️ ✴️🆚💮 🉐㊙️㊗️ 🈴🈵🈹 🈲🅰️🅱️ 🆎🆑🅾️ 🆘 🛑📛 🚫💯💢 ♨️🚷🚯 🚳🚱🔞 📵🚭 ‼️⁉️🔅 🔆〽️⚠️ 🚸🔱⚜️ 🔰♻️ 🈯💹❇️ ✳️🌐 💠Ⓜ️🌀 💤🏧🚾 🅿️🈳 🈂🛂🛃 🛄🛅🛗 🚀🛸🚁 🚉🚆🚅 ✈️🛫🛬 🛩️💺🛰️
加载中...

留言反馈

😀😃😄 😁😅😂 🤣😊😇 🙂🙃😉 😌😍🥰 😘😗😙 😚😋😛 😝😜🤪 🤨🧐🤓 😎🥸🤩 🥳😏😒 😞😔😟 😕🙁☹️ 😣😖😫 😩🥺😢 😭😤😠 😡🤬🤯 😳🥵🥶 😱😨😰 😥😓🤗 🤔🤭🤫 🤥😶😐 😑😬🙄 😯😦😧 😮😲🥱 😴🤤😪 😵🤐🥴 🤢🤮🤧 😷🤒🤕 🤑🤠😈 👿👹👺 🤡💩👻 💀☠️👽 👾🤖🎃 😺😸😹 😻😼😽 🙀😿😾 👍👎👏 🙌👐🤲 🤝🤜🤛 ✌️🤞🤟 🤘👌🤏 👈👉👆 👇☝️ 🤚🖐️🖖 👋🤙💪 🦾🖕✍️ 🙏💅🤳 💯💢💥 💫💦💨 🕳️💣💬 👁️‍🗨️🗨️🗯️ 💭💤❤️ 🧡💛💚 💙💜🖤 🤍🤎💔 ❣️💕💞 💓💗💖 💘💝💟 ☮️✝️☪️ 🕉️☸️✡️ 🔯🕎☯️ ☦️🛐 🆔⚛️🉑 ☢️☣️📴 📳🈶🈚 🈸🈺🈷️ ✴️🆚💮 🉐㊙️㊗️ 🈴🈵🈹 🈲🅰️🅱️ 🆎🆑🅾️ 🆘 🛑📛 🚫💯💢 ♨️🚷🚯 🚳🚱🔞 📵🚭 ‼️⁉️🔅 🔆〽️⚠️ 🚸🔱⚜️ 🔰♻️ 🈯💹❇️ ✳️🌐 💠Ⓜ️🌀 💤🏧🚾 🅿️🈳 🈂🛂🛃 🛄🛅🛗 🚀🛸🚁 🚉🚆🚅 ✈️🛫🛬 🛩️💺🛰️