今天的软件为人而生,明天的软件为 Agent 而造。
AI Agent 的推理能力日益强大,却始终迈不过一道坎------操控真实的专业软件。GIMP、Blender、LibreOffice,这些为人类精心设计的 GUI 应用,对 Agent 而言如同一堵高墙。
CLI-Anything 要做的事情很简单:一行命令,把任何软件变成 Agent 的原生工具。
本文是我对这个来自香港大学数据科学实验室(HKUDS)开源项目的深度学习笔记,从设计哲学到实现细节,从方法论到真实案例,完整拆解这个项目的核心思想。
一句话说清楚
CLI-Anything 是一个 AI Agent 驱动的自动化工具。你给它一个软件的源码,它自动生成一套完整的命令行接口,让 Agent 通过 --help 发现功能、通过 --json 获取结构化输出,像人类点击菜单一样操控专业软件------但全程只用命令行。
它的产出物不是文档,不是配置,而是一个真正能跑的 Python CLI 包。
为什么需要它?
Agent 与软件之间的鸿沟
现有的方案要么是脆弱的 GUI 自动化(截图、点像素、RPA),要么是覆盖面有限的 API 封装,要么干脆重新实现一个阉割版。每一种都不够好。
| 痛点 | CLI-Anything 的解法 |
|---|---|
| Agent 用不了专业工具 | 直接对接真实软件后端,完整能力,零妥协 |
| GUI 自动化三天两头崩 | 纯命令行操控,结构化接口 |
| Agent 需要结构化数据 | 内置 JSON 输出,同时保留人类可读格式 |
| 定制集成成本高 | 一条命令自动生成,7 阶段流水线全自动 |
| 原型到生产差十万八千里 | 1,508 项测试全部通过,11 款软件实测验证 |
为什么是 CLI?
CLI 是人类和 AI Agent 共通的万能接口。这个选择并非偶然:
- 天然匹配 LLM --- 文本命令就是 LLM 最擅长的输入输出格式,可自由组合成复杂工作流
- 自描述 --- 一个
--help就能让 Agent 自动发现全部功能 - 确定且可靠 --- 输出稳定一致,Agent 行为可预测
- 轻量通用 --- 几乎零开销,跨平台运行
Claude Code 每天通过 CLI 执行数以千计的真实任务,这本身就是最好的验证。
它是怎么工作的?
七阶段流水线
把一个软件的源码扔给 CLI-Anything,它会自动走完七个阶段:
| 阶段 | 做什么 |
|---|---|
| 分析 | 扫描源码,找到后端引擎,将 GUI 操作映射到 API |
| 设计 | 规划命令分组、状态模型、输出格式 |
| 实现 | 生成 Click CLI,包含 REPL、JSON 输出、撤销/重做 |
| 规划测试 | 先写 TEST.md 测试计划,再动手写代码 |
| 编写测试 | 实现四层测试套件 |
| 文档 | 更新测试结果 |
| 发布 | 生成 setup.py,pip install 即可使用 |
三层架构
每个生成的 CLI 都遵循同一套分层设计:
| 层级 | 职责 | 技术实现 |
|---|---|---|
| 指令层 | 解析命令、参数校验、格式化输出 | Python Click 框架 |
| 核心层 | 业务逻辑、状态管理、撤销/重做 | 纯 Python,状态持久化为 JSON |
| 后端层 | 调用真实软件执行渲染和处理 | 软件原生 API 或 headless 模式 |
关键在于后端层------CLI-Anything 生成的是合法的中间文件(ODF、MLT XML、SVG),然后交给真实软件去渲染。它做的是软件的结构化接口,而不是替代品。
从 GUI 到 CLI 的映射
以 GIMP 为例,Agent 在分析阶段完成的映射:
css
GUI 操作 → CLI 命令
─────────────────────────────────────────────
文件 > 新建画布 → project new --width 1920 --height 1080
图层 > 新建图层 → layer add -n "Background"
滤镜 > 模糊 > 高斯模糊 → filter blur --type gaussian --radius 5
文件 > 导出为 PNG → export render output.png -p png
Agent 扫描源码识别出软件暴露的 API(GIMP 的 Script-Fu、Blender 的 bpy),按功能域分组,设计成层次化的命令结构。
核心机制:AI Agent 如何把软件变成 CLI
不是编译器,是 AI Agent
CLI-Anything 没有传统意义上的代码生成器或编译器。它的"转换引擎"就是 AI 编程 Agent 本身------Claude Code、OpenCode、Codex 这些工具。
工作流程是这样的:
bash
你(人类) AI 编程工具 产出物
─────────────────────────────────────────────────────────────────
执行 /cli-anything ./gimp → Agent 加载 HARNESS.md 方法论 → 一个完整的
→ Agent 阅读 gimp/ 源码 → Python CLI 包
→ Agent 按七阶段流水线生成代码 → pip install 即用
换句话说,HARNESS.md 是写给 AI Agent 看的"施工图纸",Agent 是"施工队",源码是"原材料",产出物是一个可安装的 CLI 包。
Agent 在分析阶段做了什么
当 Agent 拿到一个软件的源码后,它会按 HARNESS.md 的指引完成五步分析:
-
找到真正干活的后端 --- GUI 应用通常是"表现层 + 逻辑层"分离的。Agent 要穿透 GUI 外壳,找到核心引擎。比如 Shotcut 的界面是 Qt,但真正做视频处理的是 MLT 框架;GIMP 的滤镜背后是 GEGL 库。
-
建立 GUI → API 的映射表 --- Agent 逐一分析菜单项、按钮、对话框,找到每个操作对应的底层函数调用。这张映射表就是 CLI 命令的来源。
-
理解数据模型 --- 项目文件用什么格式?LibreOffice 用 ODF(本质是 ZIP 包裹的 XML),Kdenlive 用 MLT XML,Blender 用 .blend 二进制。Agent 需要知道怎么读写这些格式。
-
盘点已有的 CLI 工具 --- 很多后端自带命令行入口:
libreoffice --headless、blender --background、melt、sox。这些是现成的积木,Agent 会优先复用而非重新实现。 -
识别命令模式 --- 如果软件支持撤销/重做,它大概率实现了命令模式(Command Pattern)。这些命令天然对应 CLI 操作。
从分析到代码:Agent 的生成策略
分析完成后,Agent 不是简单地"翻译"API,而是遵循一套严格的生成策略:
css
源码中的发现 → 生成的 CLI 代码
──────────────────────────────────────────────────────────
Pillow 的 Image.filter() → filter blur --type gaussian --radius 5
LibreOffice 的 headless 转换模式 → export render output.pdf -p pdf
Blender 的 bpy.ops.mesh.primitive_* → object add-mesh --type cube
MLT 的 XML 项目格式 → 直接操作 XML,再调 melt 渲染
Zoom 的 REST API → 封装为 zoom_backend.py,核心层调用
关键原则是:生成合法的中间文件,交给真实软件处理。Agent 不会试图自己实现图像滤镜或视频渲染------它生成 ODF 文件让 LibreOffice 转 PDF,生成 MLT XML 让 melt 渲染视频,生成 SVG 让 Inkscape 导出 PNG。
为什么这个方案能成立
你可能会问:让 AI Agent 读源码、写代码,靠谱吗?
CLI-Anything 的巧妙之处在于它把"不确定性"控制在了极小的范围内:
- HARNESS.md 提供了极其详细的规范 --- 不是"请生成一个 CLI"这种模糊指令,而是精确到文件命名、目录结构、代码模式、测试标准的完整施工手册
- 三层架构约束了代码结构 --- Agent 不需要做架构决策,只需要填充每一层的具体实现
- 四层测试验证产出质量 --- 1,508 项测试不是摆设,Agent 生成的代码必须全部通过
- 所有平台共享同一份方法论 --- 无论用 Claude Code 还是 Codex,产出的 CLI 结构一致
本质上,CLI-Anything 把"让 AI 写代码"这件高度不确定的事,通过方法论约束变成了一个可重复、可验证的工程流程。
不是一锤子买卖:refine 迭代改进
一次生成不可能覆盖软件的全部能力。CLI-Anything 提供了 refine 命令,支持增量式改进:
bash
# 宽泛改进------Agent 自动做 gap analysis,找出未覆盖的功能
/cli-anything:refine ./gimp
# 定向改进------指定你关心的功能域
/cli-anything:refine ./gimp "batch processing and filters"
refine 的工作方式是:Agent 对比软件的完整能力和当前 CLI 的覆盖范围,识别出缺口,然后针对性地补充新命令、新测试、新文档。每次 refine 都是增量的、非破坏性的------可以反复执行,逐步扩大覆盖面。
这个设计很务实:复杂软件的功能成百上千,一次性全部生成既不现实也没必要。先跑通核心流程,再按需迭代,才是工程上可行的路径。
两种交互模式
子命令模式:适合脚本和流水线
bash
# 创建文档 → 添加内容 → 导出 PDF,一气呵成
cli-anything-libreoffice document new -o report.json --type writer
cli-anything-libreoffice --project report.json writer add-heading -t "Q1 Report" --level 1
cli-anything-libreoffice --project report.json export render output.pdf -p pdf --overwrite
# Agent 用 --json 获取结构化输出
cli-anything-libreoffice --json document info --project report.json
REPL 模式:适合多步交互
REPL(Read-Eval-Print Loop)是有状态的交互环境,会记住当前项目、操作历史,支持撤销/重做。直接运行命令即进入:
sql
$ cli-anything-blender
blender> scene new --name ProductShot
✓ Created scene: ProductShot
blender[ProductShot]> object add-mesh --type cube --location 0 0 1
✓ Added mesh: Cube at (0, 0, 1)
blender[ProductShot]*> render execute --output render.png --engine CYCLES
✓ Rendered: render.png (1920×1080, 2.3 MB)
提示符自带上下文:blender[ProductShot]> 表示当前项目,* 表示有未保存的修改。所有 CLI 共享统一的 REPL 界面(repl_skin.py),不管操作哪个软件,交互体验都一致。
实测:11 款软件,1,508 项测试
CLI-Anything 不是纸上谈兵。它在 11 款复杂应用上完成了实测,涵盖创意、办公、通信、图表和 AI 内容生成------这些软件此前对 Agent 几乎不可触及。
| 软件 | 领域 | 后端技术 | 测试 |
|---|---|---|---|
| GIMP | 图像编辑 | Pillow + GEGL/Script-Fu | 107 ✅ |
| Blender | 3D 建模 | bpy (Python scripting) | 208 ✅ |
| Inkscape | 矢量图形 | Direct SVG/XML | 202 ✅ |
| Audacity | 音频制作 | Python wave + sox | 161 ✅ |
| LibreOffice | 办公套件 | ODF + headless LO | 158 ✅ |
| OBS Studio | 直播录制 | JSON scene + obs-websocket | 153 ✅ |
| Kdenlive | 视频剪辑 | MLT XML + melt | 155 ✅ |
| Shotcut | 视频剪辑 | Direct MLT XML + melt | 154 ✅ |
| Zoom | 视频会议 | Zoom REST API (OAuth2) | 22 ✅ |
| Draw.io | 图表绘制 | mxGraph XML + draw.io CLI | 138 ✅ |
| AnyGen | AI 内容生成 | AnyGen REST API | 50 ✅ |
1,508 项测试,100% 通过。 其中 1,073 项单元测试,435 项端到端测试。
深入方法论:HARNESS.md
HARNESS.md 是整个项目的灵魂------一份写给 AI Agent 看的标准操作手册。所有平台(Claude Code、OpenCode、Codex)都引用同一份文件,确保无论在哪个 AI 编程工具上运行,产出的 CLI 结构和质量都一致。
贯穿全文的核心模式只有一个:构建数据 → 调用真实软件 → 验证输出。
分析阶段:五步理解一个软件
- 识别后端引擎 --- GUI 应用通常将表现层和逻辑层分离,找到核心库(Shotcut 的 MLT、GIMP 的 ImageMagick)
- 映射 GUI 到 API --- 每个按钮、菜单项背后都有一个函数调用
- 识别数据模型 --- 项目状态用什么格式存储?XML、JSON、还是二进制?
- 发现已有 CLI --- 很多后端自带命令行工具(
melt、ffmpeg、sox),这些是现成的积木 - 梳理命令模式 --- 如果应用有撤销/重做,它大概率使用了命令模式,这些命令就是 CLI 操作的来源
设计阶段:统一的命令分组
bash
├── project # 项目管理(new, open, save, close)
├── <核心域> # 应用的主要功能(因软件而异)
├── export # 导入/导出、格式转换
├── config # 设置与偏好
└── session # 状态管理(undo, redo, history, status)
HARNESS.md 规定了七步实现顺序,不能跳跃:
- 数据层(XML/JSON 操作项目文件)
- 探查命令(
info、list、status--- 让 Agent 先看再改) - 变更命令(每个逻辑操作一个命令)
- 后端集成(
utils/<software>_backend.py封装真实软件调用) - 渲染/导出(生成中间文件 → 调用真实软件转换)
- 会话管理(状态持久化、撤销/重做)
- REPL 界面(用统一的
repl_skin.py包装)
后端集成的代码模式值得一看:
python
def find_libreoffice():
path = shutil.which("libreoffice")
if path:
return path
raise RuntimeError(
"LibreOffice is not installed. Install it with:\n"
" apt install libreoffice # Debian/Ubuntu\n"
" brew install libreoffice # macOS"
)
没装就报错,给出清晰的安装指引。不降级,不跳过,不模拟。
测试阶段:四层验证体系
HARNESS.md 要求先写测试计划(TEST.md),再写代码。测试分四层,层层递进:
| 层级 | 验证什么 | 示例 |
|---|---|---|
| 单元测试 | 每个函数的隔离验证 | 合成数据,无外部依赖 |
| E2E 原生测试 | 中间文件的结构正确性 | ODF ZIP 合法性、XML 格式 |
| E2E 真实后端测试 | 调用真实软件产出真实文件 | PDF 魔术字节 %PDF-、文件大小 |
| CLI 子进程测试 | 模拟真实用户/Agent 调用 | subprocess.run 执行已安装命令 |
"运行没报错"不等于"输出正确"------必须用魔术字节、ZIP 结构、像素分析等方式验证输出。
发布阶段:PEP 420 命名空间包
bash
cli_anything/ # 无 __init__.py(命名空间包)
├── gimp/ # 有 __init__.py(常规子包)
├── blender/
└── libreoffice/
多个 CLI 共存于同一个 Python 环境,互不冲突,通过 pip install -e . 独立安装卸载。
十条核心原则
| 原则 | 含义 |
|---|---|
| 使用真实软件 | 生成合法中间文件,交给真实软件渲染 |
| 软件是硬依赖 | 没装就报错,不降级、不模拟 |
| 操作原生格式 | 直接解析应用的原生项目文件 |
| 复用已有 CLI | libreoffice --headless、blender --background、melt |
| 验证渲染输出 | 魔术字节、ZIP 结构、像素分析 |
| 产出真实产物 | PDF、渲染图片、视频,打印路径供人工检查 |
| 失败要大声 | Agent 需要明确的错误信息来自我纠正 |
| 尽量幂等 | 同一命令执行两次应该是安全的 |
| 提供自省能力 | info、list、status 让 Agent 先了解状态再行动 |
| JSON 输出 | 每个命令都支持 --json |
案例剖析:以 Zoom CLI 为例
以 cli-anything-zoom 为例,看看产出物长什么样。
文件结构
bash
zoom/agent-harness/
├── setup.py # pip install -e . 即可安装
├── cli_anything/ # 命名空间包(无 __init__.py)
│ └── zoom/
│ ├── zoom_cli.py # CLI 入口(Click + REPL)
│ ├── core/ # 业务逻辑层
│ │ ├── auth.py # OAuth2 认证
│ │ ├── meetings.py # 会议 CRUD
│ │ ├── participants.py # 参会人管理
│ │ └── recordings.py # 录制管理
│ ├── utils/ # 工具层
│ │ ├── zoom_backend.py # Zoom REST API 封装
│ │ └── repl_skin.py # 统一 REPL 界面
│ └── tests/ # 测试层
│ ├── TEST.md
│ ├── test_core.py # 22 项单元测试
│ └── test_full_e2e.py
三层架构的体现
Zoom 的特殊之处在于"后端"是云端 REST API 而非本地软件。但架构模式完全一致------zoom_backend.py 是唯一与外部通信的模块,核心层只关心业务逻辑。
源码一瞥
入口文件遵循统一模式------无子命令时自动进入 REPL:
python
@click.group(invoke_without_command=True)
@click.option("--json", "use_json", is_flag=True)
@click.pass_context
def cli(ctx, use_json):
if ctx.invoked_subcommand is None:
ctx.invoke(repl)
核心层只关心业务,不碰 HTTP:
python
from cli_anything.zoom.utils.zoom_backend import api_post
def create_meeting(topic, duration=60, ...):
body = {"topic": topic, "duration": duration, "settings": {...}}
return _format_meeting(api_post("/users/me/meetings", body))
Agent 的使用流程
bash
# 一次性配置
cli-anything-zoom auth setup --client-id <ID> --client-secret <SECRET>
cli-anything-zoom auth login
# 日常操作------全部用 --json
cli-anything-zoom --json meeting create --topic "周会" --duration 30
# → {"id": 123456, "topic": "周会", "join_url": "https://zoom.us/j/..."}
cli-anything-zoom --json meeting list
cli-anything-zoom --json participant add --meeting-id 123456 --email "user@example.com"
cli-anything-zoom recording download --meeting-id 123456 --output ./recordings/
适用场景
| 领域 | 典型软件 |
|---|---|
| 创意与媒体 | Blender、GIMP、OBS Studio、Audacity、Krita、Inkscape |
| AI/ML 平台 | Stable Diffusion WebUI、ComfyUI、Open WebUI |
| 数据与分析 | JupyterLab、Superset、Metabase、Redash |
| 开发工具 | Jenkins、Gitea、Portainer、SonarQube |
| 科学计算 | ImageJ、FreeCAD、QGIS、ParaView |
| 企业与办公 | NextCloud、GitLab、Grafana、LibreOffice |
| 图表与可视化 | Draw.io、Mermaid、PlantUML、Excalidraw |
规律很简单:只要有源码,就能生成 CLI。
快速上手
以 Claude Code 为例,三步搞定:
bash
# 1. 添加插件市场
/plugin marketplace add HKUDS/CLI-Anything
# 2. 安装插件
/plugin install cli-anything
# 3. 为任意软件生成 CLI
/cli-anything:cli-anything ./gimp
也支持 OpenCode、Codex、Qodercli 等平台,详见项目 README。
写在最后
CLI-Anything 给我最大的启发不是某个技术细节,而是一个思维方式的转变:
与其让 Agent 学会操作 GUI,不如为软件生成一层结构化的 CLI 接口。
CLI 是人类和 Agent 共通的语言。--help 自描述,--json 结构化输出,which 发现工具------这套机制已经被验证了几十年,天然适合 Agent 使用。
当 AI Agent 逐渐成为软件的主要用户时,CLI-Anything 提供的不只是一个工具,而是一条从"人用软件"到"Agent 用软件"的标准化升级路径。
值得持续关注。