CLI-Anything 技术解析:如何把 GUI 软件抽象成 Agent-Friendly CLI

很多软件其实早就“能做事”了。

问题不在能力不够,而在接口不够适合 Agent。

对人类来说,GUI 没什么问题。窗口、按钮、菜单、拖拽,这些都是天然的人类交互方式。但对 AI Agent 来说,GUI 往往是最脆弱的一层:依赖视觉定位,依赖窗口状态,依赖页面结构,还容易因为一个按钮位置变化就让自动化流程失效。

CLI-Anything 想解决的,正是这层断点。

它的核心思路不是去模拟鼠标键盘,也不是把一个现成软件推倒重写,而是先分析目标软件已经具备的真实后端能力,再把这些能力包装成一层 Agent 可稳定调用的命令行接口。

说白了,这个项目做的不是 GUI 自动化,而是 Agent-friendly CLI 抽象层

CLI-Anything 在做什么

如果只用一句话描述,CLI-Anything 做的是:

把原本主要面向人类操作的软件,抽象成 Agent 可调用的 CLI Harness。

这里最关键的,不是 CLI 这三个字,而是 Harness。

它不是一个随手拼出来的脚本集合,也不是对原项目的侵入式魔改。更准确地说,它会先分析目标软件的结构、接口和能力边界,然后在软件外部新增一层适配层,让 Agent 能用命令、参数、状态和结构化输出去调用软件能力。

这个方向很有价值。

因为大量成熟软件本来就不是真的只能“点按钮”。很多桌面软件、服务软件,背后早就已经有:

  • 脚本接口
  • batch mode
  • headless 模式
  • CLI
  • REST API
  • 可复用的数据模型和内部调用路径

CLI-Anything 做的,就是优先去找到这些入口,而不是停留在屏幕层做脆弱的操作模拟。

这条路线为什么比 GUI 自动化更稳

GUI 自动化不是不能做,而是天然不稳定。

它更像是在操作“表面现象”:

  • 按钮有没有变位置
  • 页面有没有改样式
  • 窗口是不是被遮挡
  • 分辨率是不是变了
  • 当前焦点是不是还在正确控件上

这些问题,对人来说不难,对 Agent 来说却很容易变成灾难。

CLI 和 API 就不一样了。

它们天然具备几种更适合 Agent 的特征:

  • 输入参数明确
  • 输出可结构化
  • 状态更容易建模
  • 流程更容易测试
  • 自动化更容易复现

所以 CLI-Anything 的判断非常务实:

  • 优先包装真实 backend
  • 优先复用已有能力
  • 优先在外部补一层 CLI
  • 尽量避免直接重写原软件

这不是“为了优雅而优雅”,而是很典型的工程取舍。只要原软件已经暴露了足够多的后端能力,这条路线的稳定性、维护性和扩展性,通常都比 GUI 自动化更好。

项目的技术架构,可以拆成四层

CLI-Anything 最值得看的地方,是它不是简单生成一个命令,而是背后有一套比较完整的分层设计。

1. 方法论层:先分析,再抽象

项目里用 HARNESS.md 这样的约定去定义 SOP。

这一层的重点不是“立刻生成代码”,而是先回答几个关键问题:

  • 目标软件的结构是什么
  • 哪些 GUI 行为背后有真实 API 或脚本入口
  • 数据模型怎样组织
  • 有没有现成的 CLI、batch mode、headless 模式
  • 命令模型和状态模型应该怎么设计
  • 测试边界在哪里
  • 最终该如何打包和发布

这一步决定了 CLI-Anything 更像一套适配方法,而不是一个大号 prompt 模板。

2. CLI 运行时层:用 Python + Click 做统一接口

原文里提到,CLI-Anything 生成的运行时通常基于 Python + Click。

这套组合其实很合理。

Python 适合做胶水层,Click 适合组织命令体系,生态也成熟。对于一个需要快速把软件能力封装成命令接口的项目来说,这是一种非常实用的选择。

更重要的是,这个运行时不是只支持一次性子命令。它通常同时具备:

  • one-shot subcommands
  • 默认 REPL
  • --json 输出
  • 会话状态持久化
  • 在合适场景下提供 undo/redo

这些设计说明,它面向的不是传统命令行用户,而是需要稳定驱动工具的 Agent。

Agent 最怕的是状态不可见、输出不可解析、命令行为不稳定。CLI-Anything 的运行时设计,基本就是围绕这几个问题来的。

3. 后端适配层:优先对接真实软件能力

CLI-Anything 有一个非常明确的原则:优先包装真实 backend,而不是重写软件本身。

原文里给出的例子很典型:

  • Blender:blender --background --python
  • LibreOffice:--headless
  • GIMP:gimp -i -b batch mode
  • ComfyUI、Ollama、AdGuardHome:REST API

这些例子说明,CLI-Anything 不是只适合一种软件类型。

只要目标软件存在某种“非人工交互入口”,不管这个入口是脚本、CLI、headless 模式还是 HTTP API,都有机会被映射进统一的 Agent CLI 模型中。

这个思路很像给软件做一层 Agent API,只不过最后落地的载体不是 Web API,而是 CLI。

4. 平台接入层:面向不同 Agent 生态分发

CLI-Anything 最后并不止步于“本地多了一个命令”。

它还会按不同 Agent 平台提供不同入口,比如:

  • Claude Code 插件
  • OpenClaw skill
  • Codex skill
  • OpenCode commands
  • Qoder 插件

这一层很重要。

因为它说明项目的目标不是单点工具,而是接入 Agent 工作流。底层方法论可以统一,但不同平台的分发方式、调用方式和交互形态不一样,所以入口层必须做适配。

这是一个很典型的工程分层:能力层统一,接入层适配。

它最终会生成什么

CLI-Anything 的产物,通常不是在原项目目录里到处插改动,而是在旁边生成一层相对独立的 harness 结构。

类似这样:

<software>/agent-harness/
├── setup.py
├── cli_anything/
│   └── <software>/
│       ├── <software>_cli.py
│       ├── core/
│       └── utils/
└── tests/

这个结构其实已经说明很多问题。

第一,它是 可安装 的。 第二,它是 可测试 的。 第三,它是 可维护 的。

很多 Agent 相关项目停留在“能跑”的层面:脚本能执行,prompt 能生成,流程能走通,但维护起来很痛苦。CLI-Anything 的方向明显更工程化,它希望把最终产物收敛成一个标准的软件接口层。

这意味着它不是一次性实验,而是在尝试建立长期可复用的适配方式。

它和“魔改原项目”不是一回事

从表面上看,CLI-Anything 很像是在给软件“补一个命令行版本”。

但更准确的描述应该是:它优先通过外部包装,把原软件抽象成一个 Agent 可调用的 CLI 壳;只有在目标软件缺少足够后端接口时,才会在 harness 内补做部分能力。

这和直接改原项目不是一个思路。

前者强调的是:

  • 复用已有 backend
  • 维持原项目边界
  • 降低侵入性
  • 提高适配层独立性

后者则更容易把问题带向另一个方向:耦合越来越重,升级越来越难,维护边界越来越模糊。

所以从工程角度看,CLI-Anything 更像是给软件外接一个 Agent Gateway,只不过这个 Gateway 采用 CLI 形式交付。

在 Claude Code 里怎么用:以 GIMP 为例

原文用 GIMP 做了一个比较完整的说明,这个例子很适合帮助理解 CLI-Anything 的实际工作流。

首先,添加 CLI-Anything 插件市场:

/plugin marketplace add HKUDS/CLI-Anything

然后安装插件:

/plugin install cli-anything

接着,在 Claude Code 会话中对目标目录执行:

/cli-anything:cli-anything ./gimp

这个命令背后不是单步脚本,而是一条完整流水线。原文提到的阶段包括:

  1. 分析
  2. 设计
  3. 实现
  4. 测试规划
  5. 写测试
  6. 补文档
  7. 生成 setup.py 并安装到 PATH

流程跑完之后,通常会得到一个类似 cli-anything-gimp 的命令。

例如:

cli-anything-gimp --help

如果想进入交互模式,可以直接运行:

cli-anything-gimp

如果希望 Agent 稳定解析输出,则可以使用 JSON 模式:

cli-anything-gimp --json ...

如果后续想扩展更多能力覆盖范围,还可以继续 refine:

/cli-anything:refine ./gimp

也可以直接附带额外需求,比如增加更多图像批处理或滤镜相关命令。

这个项目真正有意思的地方

CLI-Anything 的价值,不只是“多了一个插件”,也不只是“能多生成几个命令”。

它真正踩中的,是当前 Agent 落地中的一个现实问题:模型越来越强,但软件接口并没有同步变得更适合模型。

今天的大量软件仍然主要面向人类设计:

  • 用按钮表达功能
  • 用界面承载状态
  • 用菜单组织能力
  • 用视觉反馈帮助理解

这些设计对人非常友好,但对 Agent 不够友好。

Agent 更需要的是另一套东西:

  • 明确命令
  • 稳定参数
  • 可预测状态
  • 结构化输出
  • 可测试流程

CLI-Anything 做的,就是在传统软件和 Agent 之间补上一层工程化接口。

从这个角度看,它做的不是单纯的“命令行化”,而是在尝试建立一种新的软件适配范式:不改变软件核心能力,而是改变软件被 Agent 使用的方式。

这件事一旦跑通,意义会比一个单点工具大得多。很多原本只能靠人来操作的软件,都可能被重新纳入 Agent 工作流,变成更稳定的自动化组件。

最后

CLI-Anything 的本质,可以概括成一句话:

它用统一方法,把 GUI、桌面软件或服务软件背后的真实能力,抽象成 Python + Click 的 stateful CLI Harness,再通过 JSON 输出、REPL、测试体系和多平台接入,让这些能力可以被 LLM Agent 稳定驱动。

这条路线的价值,不在于“把 GUI 变成命令行”本身。

真正的价值在于,它为 Agent 和传统软件之间,补上了一层可维护、可测试、可扩展的接口桥梁。

很多时候,问题不是软件能力不够,而是接口还不适合 Agent。CLI-Anything 解决的,正是这层问题。