夜雨聆风学习资料网

ARTICLE · 1241155

让 AI 助手像人一样用软件

让 AI 助手像人一样用软件

最近在 GitHub 上留意到一个项目,挺有意思。

它想解决一个问题:AI 助手很会思考,但不会用软件。你让 Claude 帮你做个 PPT,它只能给你一堆文字,因为它打不开 PowerPoint。你让它剪个视频,它只能给你 ffmpeg 命令,因为它点不了剪映的按钮。

现在有个思路:别教 AI 点鼠标,直接把软件变成命令行。

为什么是命令行

GUI 自动化听起来很自然——让 AI 看屏幕、点按钮。但这条路走不通。

屏幕截图会糊,像素坐标会飘,按钮位置会变。一个分辨率差异就能让自动化脚本跑飞。更麻烦的是,GUI 操作没有结构。AI 看到一堆像素,很难理解"这个对话框在问什么"。

API 呢?很多软件根本没有 API。就算有,每个软件的 API 长得不一样,AI 得学一套新的。

命令行刚好卡在中间。它是文本的,AI 看得懂;它是结构的,参数有名字有类型;它是通用的,几乎所有软件都有某种形式的命令行接口。

更关键的是,命令行可以组合。一条命令的输出可以接另一条命令的输入。这种可组合性让 AI 能把复杂任务拆成小步骤,一步步做。

一个坑:渲染鸿沟

但把软件变成命令行,有个很容易踩的坑。

假设你要给 GIMP 做个命令行。最直观的想法:用 Python 的 Pillow 库来画图。但 Pillow 不是 GIMP。GIMP 的滤镜、图层混合、色彩管理,Pillow 都做不了。你做出来的"命令行版 GIMP",其实是个玩具。

正确做法是:命令行只负责生成 GIMP 能理解的项目文件,然后调用真正的 GIMP 来渲染。

比如 LibreOffice。你想让 AI 帮你写文档、转 PDF。你不能自己写个 PDF 生成器。

你要做的是:生成 ODF 格式的文档。ODF 是 LibreOffice 的原生格式。然后调用 libreoffice --headless --convert-to pdf 来转换。

这样出来的 PDF,和你在 LibreOffice 里手动导出的一模一样。因为渲染的就是 LibreOffice 本身。

这个项目叫 CLI-Anything。它给 69 个软件做了命令行外壳。

GIMP、Blender、LibreOffice、Inkscape、Audacity、OBS Studio、FreeCAD、QGIS……从图像编辑到 3D 建模,从视频剪辑到地理信息系统。

每个命令行都遵循同一个原则:不重新实现软件,只调用软件。

七步流水线

给一个软件做命令行,不是一蹴而就的。CLI-Anything 有一套七步流程。

第一步,分析代码库。找到软件的核心引擎,搞清楚 GUI 操作对应哪些 API 调用,弄明白项目文件是什么格式。

第二步,设计命令行架构。决定用交互式 REPL 还是单次命令,或者两者都要。划分命令组:项目管理、核心操作、导入导出、配置、会话状态。

第三步,实现。先做数据层(操作项目文件),再加探测命令(让 AI 能查看状态),然后加修改命令,最后接后端(调用真正的软件)。

第四步,写测试计划。在写任何测试代码之前,先列出要测什么、怎么测、边界情况有哪些。

第五步,写测试。单元测试用假数据,端到端测试必须调用真正的软件,验证输出文件的格式是否正确(比如检查 PDF 的前五个字节是不是 %PDF-)。

第六步,生成 SKILL.md。这是一个给 AI 看的说明文件,告诉 AI 这个命令行能做什么、怎么用。

第七步,打包发布。用 pip 安装,放到 PATH 里,AI 就能直接调用。

这套流程写在 HARNESS.md 里,747 行。它是整个项目的操作手册。

不妥协的后端依赖

CLI-Anything 有一条铁律:软件必须装。没装就报错,不跳过,不降级。

比如 LibreOffice 的命令行。如果你没装 LibreOffice,测试会直接失败,不会用别的库凑合。因为用别的库做出来的东西,不是 LibreOffice 做出来的。

代码里有个细节。调用 LibreOffice 做格式转换时,要传一堆命令行参数:

--headless --nologo --nodefault --norestore --nolockcheck --nofirststartwizard

为什么这么多?

因为 macOS 上,如果 LibreOffice 上次崩溃留下了锁文件,或者启动中心没关掉,headless 模式会直接 SIGABRT。这六个参数,每个都是为了堵住一个坑。

这种细节,只有真正跑过才知道。

会话状态与撤销重做

AI 用命令行做事,不是一锤子买卖。它可能执行了一堆命令,然后发现某一步做错了,想撤销。

CLI-Anything 的每个命令行都有会话管理。它用 JSON 文件保存当前状态,每次修改前都会做一次快照,压进撤销栈。

代码里有个 Session 类,维护两个栈:_undo_stack 和 _redo_stack。每次修改前调用 snapshot(),把当前状态深拷贝一份压栈。撤销时从 undo 栈弹出,压进 redo 栈;重做时反过来。

栈的深度有限制,MAX_UNDO = 50。超过 50 步就丢弃最早的。

还有个细节:保存 JSON 时用文件锁。代码里有个 _locked_save_json 函数,先打开文件,用 fcntl.flock 加排他锁,然后 truncate 再写入。这是为了防止并发写坏文件。

这种设计让 AI 可以大胆尝试。做错了就撤销,不用从头来。

让 AI 看见自己在做什么

AI 用命令行做事,有个问题:它不知道自己做到哪了。

你让 AI 用 Blender 建个 3D 模型。它执行了一堆命令,加了立方体、改了材质、调了灯光。但它看不见渲染结果。它不知道模型长什么样。

CLI-Anything 加了预览机制。每个命令行都有 preview 命令。AI 可以调用 preview capture 生成一个预览包,里面是渲染出来的图片或模型快照。

更进一步,有 preview live 模式。AI 开始一个实时预览会话,每次执行命令都会自动推送一个新的预览包。AI 可以随时调用 preview live status 查看当前状态。

这些预览包不是假的。它们是用真正的软件渲染出来的。Blender 的预览就是 Blender 渲染的图,FreeCAD 的预览就是 FreeCAD 导出的快照。

还有个 trajectory.json 文件,记录了每一步命令和对应的预览包。AI 可以回溯整个操作历史,看看是哪一步出了问题。

这种设计让 AI 有了"眼睛"。它不再是盲操作,而是能看到自己的成果,及时调整。

一个命令行商店

69 个命令行,一个个装太麻烦。CLI-Anything 做了个包管理器,叫 CLI-Hub。

pip install cli-anything-hubcli-hub list          # 看有哪些命令行cli-hub install gimp  # 装 GIMP 的命令行cli-hub launch gimp   # 运行

CLI-Hub 背后有两个注册表:一个是 CLI-Anything 自己做的 69 个命令行,另一个是社区贡献的 24 个第三方命令行。两个注册表合并在一起,AI 可以统一搜索和安装。

注册表有缓存机制。代码里用 requests.get 拉取远程 JSON,缓存到 ~/.cli-hub/registry_cache.json,TTL 是一小时。这样不用每次都联网。

更妙的是,CLI-Hub 自己也是个 SKILL。AI 助手可以加载这个 SKILL,然后自己去 CLI-Hub 里找合适的命令行、安装、使用。整个过程不需要人干预。

比如你让 AI 帮你处理一个 Obsidian 笔记。AI 会去 CLI-Hub 搜一下,发现有 cli-anything-obsidian,装上,然后用命令行操作 Obsidian 的数据。

这种"AI 自己找工具"的能力,是 CLI-Anything 的终极目标。

SKILL.md:给 AI 看的说明书

每个命令行都带一个 SKILL.md 文件。这是给 AI 看的说明书,告诉 AI 这个命令行能做什么、怎么用。

SKILL.md 里有 YAML frontmatter,包含名字和描述,方便 AI 搜索和发现。正文里列出所有命令组、用法示例、JSON 输出格式、错误处理方式。

这个文件是工具自己吐出来的。代码里有个 skill_generator.py,从 Click 装饰器、setup.py、README 里提取元数据,用 Jinja2 模板生成 SKILL.md。

生成的 SKILL.md 放在两个地方:一个是仓库根目录的 skills/cli-anything-<software>/SKILL.md,这是规范位置;另一个是包内的 cli_anything/<software>/skills/SKILL.md,这是兼容位置。

AI 助手可以读这个文件,了解命令行的全部能力。这比读 README 高效得多,因为 SKILL.md 是专门为 AI 设计的,结构清晰,信息密度高。

不是什么都能做

CLI-Anything 有明确的限制。

它需要源代码。七步流程的第一步是分析代码库。如果软件只有编译好的二进制文件,没有源码,那命令行生成的质量会大打折扣。

它需要强力的基础模型。生成命令行不是一般的代码生成任务,需要 Claude Opus 4.6、GPT-5.4 这个级别的模型。用弱一点的模型,生成的命令行可能不完整,需要人工修正。

它可能需要迭代。一次 /cli-anything 不一定能覆盖所有功能。可能需要跑一次 /refine,针对某个功能领域再补充。

这些限制写在 README 的 Limitations 一节里,没有藏着。

结尾

CLI-Anything 的思路挺清晰:与其教 AI 用 GUI,不如把软件变成 AI 熟悉的命令行。

它不是在做 GUI 自动化的替代品,而是在重新定义 AI 和软件的关系。未来的软件可能天生就是为 AI 设计的,而不是为人设计的。

当然,这一天还远。但现在有 69 个软件,AI 可以像人一样用了。

相关学习资料