CLI-Anything 技术解析:把 GUI 软件改造成 Agent 可用的 CLI Harness

CLI-Anything 技术解析:把 GUI 软件改造成 Agent 可用的 CLI Harness

很多软件其实早就能干活了。

问题往往不在能力,而在接口。

我这几年看各种 Agent 落地项目,最常见的翻车点不是模型不够强,而是软件边界太人类化了。人类喜欢窗口、按钮、菜单、拖拽。Agent 不一样。它更喜欢命令、参数、状态和结构化输出。

所以我看到 CLI-Anything 这个项目时,第一反应不是“又一个自动化工具”,而是:这个方向挺对。

它没有去模拟鼠标乱点,也没有一上来就想着把原软件推倒重写。它做的事更克制,也更像工程师会选的方案:先找到目标软件已经存在的 backend 能力、脚本入口或 API,再在外面包一层 Agent-friendly CLI。

说白了,它不是在做 GUI 自动化。

它是在给传统软件补一层 Agent 能用的命令行外壳。

我为什么觉得这条路更靠谱

很多人一提 Agent 操作软件,脑子里先冒出来的是视觉识别、按钮定位、自动点击。

这条路不是不能走。

但我踩过类似的坑,知道它有多脆。按钮位置一变,脚本就挂;窗口被遮一下,流程就断;分辨率、焦点、主题样式一改,整个自动化像纸糊的一样。

GUI 自动化更像在摸软件的表皮。

它能跑,但通常不稳。

CLI-Anything 的思路刚好相反。它不去碰最脆的那层,而是优先找软件内部更稳定的能力入口,比如:

  • 原生 CLI
  • batch mode
  • headless 模式
  • 脚本接口
  • REST API
  • 内部可复用的数据模型

这就很关键。

因为 Agent 真正需要的,不是“看起来像人在用”,而是“稳定地把事做完”。从工程角度看,后者比前者重要太多了。

真正适合 Agent 的接口,不是更像人类,而是更像机器。

CLI-Anything 到底在做什么

如果只用一句话概括,我会这样说:

CLI-Anything 在把原本主要服务人类操作的软件,抽象成 Agent 可以稳定调用的 CLI Harness。

这里最重要的词其实不是 CLI,而是 Harness。

我为什么反复强调这个词?因为它不是随手拼几个脚本就完事了。

一个像样的 harness,至少得回答这些问题:

  • 哪些能力值得暴露成命令
  • 命令参数怎么设计才稳定
  • 状态怎么保存
  • 输出怎么做成可解析格式
  • 出错时怎么返回
  • 测试边界怎么划
  • 后续怎么扩展

这套东西做好了,Agent 调用软件时才不会像在拆盲盒。

所以 CLI-Anything 真正做的是一层适配层。它站在原软件外面,把原本零散、隐藏、偏人类化的能力,整理成 Agent 能理解的一套接口模型。

这件事为什么比“写个脚本”难,也更有价值

很多人会觉得,不就是包一层命令吗?

真做过就知道,远没这么简单。

脚本和接口层不是一个东西。脚本解决的是“这次能跑”,接口层解决的是“以后都能跑,而且别人也能调用”。

这两者差很多。

一个能长期维护的 Agent CLI,至少要满足几件事:

  • 输入边界清楚
  • 输出格式稳定
  • 状态可观察
  • 错误能定位
  • 命令语义一致
  • 测试可以自动化

我发现很多 Agent 项目停在“演示可用”这一步。demo 很亮眼,录屏很好看,真接进工作流就开始冒烟。CLI-Anything 比较难得的一点,是它明显在往“工程化可交付”那个方向靠,而不是停在 prompt 工程层。

我会怎么拆 CLI-Anything 的架构

这个项目最值得看的地方,不是它最后产出一个命令,而是它背后有一套比较完整的分层。

1. 方法论层:先分析软件,再决定怎么包

CLI-Anything 不是上来就生成代码。

它会先分析目标软件。

比如:

  • 这个软件本身是什么结构
  • GUI 背后有没有真实可调用能力
  • 有没有现成脚本入口
  • 有无 batch mode 或 headless 模式
  • 数据模型和状态模型应该怎么抽
  • 测试怎么设计才有意义

我很认同这种顺序。

很多自动化项目死得快,就是因为一开始没建模,直接开干。最后表面上跑通了,底层却是一团线团。

先抽象,再实现。这个顺序看起来慢,实际最省时间。

2. 运行时层:用 Python + Click 做统一命令界面

根据项目说明,CLI-Anything 生成的运行时通常基于 Python + Click。

这套组合挺务实。

Python 适合做胶水层,拿来连 API、脚本和各种第三方工具都很顺手。Click 适合组织命令体系,做子命令、参数、帮助文档这些都很成熟。

更重要的是,它不是只生成一个一次性命令。

它通常还会配这些能力:

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

这就不是传统 CLI 用户导向了,而是明显在照着 Agent 的使用方式设计。

Agent 最怕三件事:

  • 看不见状态
  • 读不懂输出
  • 遇错不知道怎么收场

CLI-Anything 的运行时设计,基本都在解决这三件事。

3. 后端适配层:优先复用真实 backend

我最喜欢这个项目的一点,就是它不执着于“重写”。

它优先包装真实 backend。

README 里提到的例子就很典型:

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

这些例子背后其实说明了一件事:很多看起来只有 GUI 的软件,底层根本不只有 GUI。

只是平时普通用户用不到那些入口。

CLI-Anything 做的,是把这些入口翻出来,整理好,再统一映射成 Agent 能理解的命令模型。

这比“模拟用户点按钮”要高一个层级。

前者是在调用能力。

后者是在模仿动作。

我一般都会优先选前者。

4. 平台接入层:把同一套能力分发到不同 Agent 生态

CLI-Anything 最后也不只是生成一个本地命令。

它还会往不同 Agent 平台去接,比如:

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

这一层很重要。

因为这说明它不是单点工具,而是在做“统一能力,多端接入”。底层 harness 保持一致,上层根据不同 Agent 生态去适配入口和交互方式。

这就是典型的平台化思路。

它最终生成的东西,为什么像一个正经软件组件

CLI-Anything 的产物通常不是把原项目改得满地都是补丁,而是在旁边生成一层相对独立的结构。

大致像这样:

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

这个目录一摆出来,我基本就知道它在追求什么了:

  • 能安装
  • 能测试
  • 能维护
  • 能继续扩

很多所谓“Agent 集成”最后只有一堆 prompt 和脚本,能跑一次,不太能交付。CLI-Anything 至少从结构上看,是在试图把结果收敛成一个像样的软件接口层。

这点我很看重。

因为真正进生产环境时,最贵的从来不是第一次做出来,而是后面改不改得动。

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

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

但我觉得更准确的说法是:它优先通过外部包装,把原软件变成一个 Agent 可调用的能力提供者。

这个思路和直接改原项目差很多。

前者的特点是:

  • 复用已有 backend
  • 尽量不碰核心代码
  • 降低侵入性
  • 让适配层可独立演进

后者就容易走向另一个极端:

  • 耦合越来越重
  • 升级越来越麻烦
  • 边界越来越模糊
  • 出问题很难定位是原软件还是适配层

这么多年下来,我越来越倾向这种“外挂式工程化”的路线。不是因为它最优雅,而是因为它在大多数真实项目里,成本收益比更高。

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

项目里拿 GIMP 举了个完整例子,这个例子挺好,因为它能把工作流讲清楚。

先加 marketplace:

/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

我觉得这套流程最有意思的地方,不是“自动生成”本身,而是它把生成、测试、安装、后续迭代都串起来了。这样出来的东西,才比较像能长期使用的工具链,而不是一次性 demo。

这个项目真正踩中的问题

CLI-Anything 真正有意思的地方,不只是多了一个插件。

它踩中的是 Agent 落地里一个很现实的问题:模型能力涨得很快,软件接口演进却慢得多。

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

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

这对人很友好。

对 Agent 就未必。

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

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

所以我会把 CLI-Anything 看成一个“接口再设计”项目。它不是在改变软件本身的核心能力,而是在改变软件被 Agent 使用的方式。

这件事一旦做顺了,意义其实不小。

很多原本只能靠人点来点去的软件,就有机会重新进入自动化工作流,变成 Agent 可以稳定编排的组件。

我最后的判断

如果你问我,这个项目最有价值的点是什么。

我会说,不是 CLI,也不是插件市场。

而是它把一个很多人都意识到、但很少有人认真工程化的问题,做成了一套可复制的方法:

不去硬控 GUI,而是优先复用真实 backend,把软件能力封装成 Agent 能稳定调用的 stateful CLI Harness。

这条路线不性感。

但很对。

因为真正能落地的 Agent 系统,最后拼的从来不是“看起来像人”,而是“能不能长期稳定做事”。CLI-Anything 解决的,正是这里最容易被忽略的一层。