CLI-Anything 深度拆解:香港大学如何用 7 阶段流水线把任何软件变成 AI Agent 原生工具——从 Agent Harness 架构到 CLI-Hub 生态的全栈工程哲学
引言:AI Agent 的「最后一公里」困境
2026 年,AI Agent 已经不再是概念。Claude Code 能写代码、Codex 能做重构、OpenClaw 能管理你的日常——它们的推理能力已经强到可以处理复杂的多步骤任务。但有一个问题始终困扰着所有 AI Agent 开发者:
当 Agent 需要操作桌面软件时,它们无能为力。
想象一个场景:你让 Claude Code 帮你画一张 draw.io 架构图。Claude 理解你的需求,知道什么是架构图,甚至能写出 Mermaid 语法。但 draw.io 是一个 GUI 软件,它没有 AI 可以调用的接口,只有一堆按钮和菜单。Claude Code 只能「望洋兴叹」。
这个问题不只存在于 draw.io。GIMP、Blender、LibreOffice、QGIS、Obsidian、Audacity——几乎所有专业桌面软件都面临同样的困境:它们是为人类设计的图形界面,不是为 AI 设计的程序接口。
传统解决方案有两条路,但都有致命缺陷:
方案一:GUI 自动化(截图+点击)
让 AI 实时截屏,识别界面元素位置,模拟鼠标点击。这种方式不仅慢(每一步都要截图、识别、计算坐标),而且极其消耗 Token,更重要的是——脆弱。窗口大小变了、分辨率不同、主题换了,整个流程就崩了。
方案二:手动封装 API
找到软件的脚本接口(如 LibreOffice 的宏、Blender 的 Python API),手动编写 CLI 工具。这需要对每款软件都吃得很透,写起来繁琐,而且不是每款软件都有现成的 API——draw.io 就没有。
CLI-Anything 换了个思路:它不造新轮子,而是分析现有软件的源码,搞清楚 GUI 背后实际在调用哪些函数,然后自动生成一套命令行接口来对接这些函数。
Claude Code 发命令,draw.io 在后台干活,结果和你手动操作完全一样——因为调用的就是同一套引擎。
这个项目来自香港大学数据智能实验室(HKUDS),2026 年 3 月 9 日开源,到 3 月 27 日就拿到了两万多 Star。截至 2026 年 8 月,GitHub Star 数已突破 5 万,成为 AI Agent 工具链领域增长最快的开源项目之一。
今天这篇文章,我们就来深度拆解 CLI-Anything 的架构设计、7 阶段流水线、Agent Harness 概念,以及它如何重新定义「AI Agent 能控制什么」。
一、核心概念:Agent Harness 是什么?
在深入 CLI-Anything 之前,我们需要先理解一个关键概念:Agent Harness。
1.1 从 Agent 到 Agent Harness
AI Agent 本身只是一套推理系统——它能思考、能规划、能决定下一步做什么。但要真正执行任务,Agent 需要一个「执行层」。这个执行层就是 Agent Harness。
用一个类比来说明:
- Agent = 一个经验丰富的项目经理
- Agent Harness = 项目经理手下的执行团队 + 项目管理工具
- 底层软件 = 实际干活的工程师
项目经理再厉害,也需要有人帮他干活。Agent 再聪明,也需要 Harness 帮它把意图转化为具体操作。
Agent Harness 的核心职责包括:
- 任务生命周期管理:创建、执行、监控、重试、清理
- 状态追踪:记录当前执行到了哪一步,有没有出错
- 输出标准化:把各种软件的输出格式统一成 JSON,方便 Agent 解析
- 错误恢复:出错时自动重试或回滚
- 资源管理:文件、进程、网络连接等的分配和回收
1.2 为什么需要 Agent Harness?
你可能会问:Claude Code 已经有工具调用能力了,为什么还需要 Harness?
答案是:可靠性。
普通的工具调用是「单步」的——Agent 调用一次工具,拿到结果,再决定下一步。但真实任务往往是「多步」的——你让 Agent 用 GIMP 打开一张图片、调整亮度、添加文字、导出为 PNG,这中间有 4 个步骤,任何一个步骤出错都可能导致整个任务失败。
Agent Harness 就是为了解决这种多步任务的可靠性问题。它提供:
- 事务性操作:要么全部成功,要么全部回滚
- 中间状态持久化:即使 Agent 断连,任务也能从断点恢复
- 幂等性保证:同一个操作执行多次,结果一致
- 超时和资源限制:防止 Agent 陷入死循环或耗尽资源
二、CLI-Anything 架构全景
CLI-Anything 的架构可以分为三层:
┌─────────────────────────────────────────────────────┐
│ AI Agent 层 │
│ Claude Code / Codex / OpenClaw / Hermes Agent │
├─────────────────────────────────────────────────────┤
│ Agent Harness 层 │
│ CLI-Anything 自动生成的命令行接口 │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Blender │ │ GIMP │ │ draw.io │ ... │
│ │ CLI │ │ CLI │ │ CLI │ │
│ └──────────┘ └──────────┘ └──────────┘ │
├─────────────────────────────────────────────────────┤
│ 底层软件层 │
│ Blender (Python API) / GIMP (Script-Fu) / ... │
└─────────────────────────────────────────────────────┘
顶层是各种 AI Agent,它们不需要知道底层软件的具体实现细节,只需要调用统一的 CLI 命令。
中间层是 CLI-Anything 自动生成的 Agent Harness——每个软件对应一套 CLI 工具,负责将 Agent 的命令转化为软件的原生操作。
底层是实际的桌面软件,通过它们的原生 API(Python 脚本、宏、插件接口等)被 Harness 调用。
2.1 为什么是 CLI 而不是 API?
这是一个关键的设计决策。CLI-Anything 选择了 CLI 作为统一接口,而不是为每款软件封装 REST API。原因有三:
CLI 是人和 AI 都能用的接口。 人类开发者可以通过命令行直接调试,AI Agent 可以通过工具调用执行。不需要两套不同的接口。
--help 让 AI 自己探索工具能力。 Agent 不需要提前知道所有命令,它可以通过 --help 动态发现可用的操作。这比固定 API 更灵活。
--json 输出方便 AI 解析。 所有 CLI 命令都支持 --json 参数,输出结构化的 JSON 数据,Agent 可以直接解析,不需要处理各种格式的文本输出。
工作流可以随意组合。 CLI 命令天然支持管道、重定向、条件执行。Agent 可以像人类开发者一样,把多个命令组合成复杂的工作流。
三、7 阶段流水线:从源码到可执行 CLI
CLI-Anything 最核心的技术创新是它的 7 阶段自动化流水线。你把一个本地代码仓库或 GitHub 仓库路径交给它,它会按固定流程自动生成一套完整的 CLI 工具。
阶段 1:源码分析(Source Analysis)
流水线的第一步是对软件源码进行深度分析。这不是简单的文件扫描,而是理解软件的架构和能力。
# 源码分析阶段的伪代码
def analyze_source(repo_path):
# 1. 识别项目语言和构建系统
project_info = detect_project(repo_path)
# 2. 扫描入口点(main 函数、脚本入口)
entry_points = find_entry_points(project_info)
# 3. 分析 GUI 组件到后端逻辑的映射
gui_mappings = trace_gui_to_backend(project_info)
# 4. 提取可操作对象(文件、图层、节点等)
operable_objects = extract_operable_objects(project_info)
# 5. 识别原生 API 和脚本接口
native_apis = discover_native_apis(project_info)
return SourceAnalysis(
entry_points=entry_points,
gui_mappings=gui_mappings,
operable_objects=operable_objects,
native_apis=native_apis
)
以 draw.io 为例,分析阶段会发现:
- 它是一个基于 Electron 的桌面应用
- 核心引擎在
src/main/webapp/js/目录下 - 有 XML 格式的图形描述语言
- 有
mxGraphJavaScript API 可以操作图形元素 - 文件格式是
.drawio(本质是 XML)
阶段 2:命令设计(Command Design)
基于源码分析的结果,设计 CLI 命令的结构。这一步需要决定:
- 哪些操作应该暴露为命令
- 每个命令需要哪些参数
- 命令的层次结构(子命令 vs 参数)
- 输出格式(JSON schema)
# 命令设计阶段
def design_commands(source_analysis):
commands = []
# 为每个可操作对象设计命令
for obj in source_analysis.operable_objects:
cmd = Command(
name=f"{obj.type}-{obj.action}",
description=f"操作 {obj.type} 的 {obj.action} 方法",
params=[
Param("input", type="file", required=True),
Param("output", type="file", required=False),
*obj.parameters
],
output_schema=obj.output_format
)
commands.append(cmd)
# 设计工作流命令(组合多个原子操作)
workflows = design_workflows(commands)
return CommandDesign(commands=commands, workflows=workflows)
阶段 3:CLI 生成(CLI Generation)
这是最关键的阶段。流水线会自动生成完整的 CLI 代码,包括:
# 自动生成的 Blender CLI 示例
#!/usr/bin/env python3
"""Auto-generated CLI harness for Blender"""
import argparse
import json
import subprocess
import sys
def cmd_render(args):
"""渲染 3D 场景"""
# 生成 Blender Python 脚本
script = f"""
import bpy
import json
# 加载场景
bpy.ops.wm.open_mainfile(filepath='{args.input}')
# 设置渲染参数
bpy.context.scene.render.resolution_x = {args.width}
bpy.context.scene.render.resolution_y = {args.height}
bpy.context.scene.render.resolution_percentage = {args.quality}
# 执行渲染
bpy.ops.render.render(write_still=True)
# 输出结果
result = {{
"status": "success",
"output": "{args.output}",
"resolution": f"{args.width}x{args.height}",
"render_time": bpy.context.scene.render.timestamp
}}
print(json.dumps(result))
"""
# 写入临时脚本并执行
with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False) as f:
f.write(script)
script_path = f.name
result = subprocess.run(
[args.blender_path, '--background', '--python', script_path],
capture_output=True,
text=True
)
if result.returncode != 0:
print(json.dumps({"status": "error", "error": result.stderr}))
sys.exit(1)
print(result.stdout)
def cmd_create_mesh(args):
"""创建网格物体"""
script = f"""
import bpy
import json
import math
# 清空场景
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete()
# 创建网格
bpy.ops.mesh.primitive_{args.primitive}_add(
radius={args.radius},
location=({args.x}, {args.y}, {args.z})
)
# 输出结果
obj = bpy.context.active_object
result = {{
"status": "success",
"object": obj.name,
"vertices": len(obj.data.vertices),
"faces": len(obj.data.polygons)
}}
print(json.dumps(result))
"""
# ... 执行逻辑类似
def main():
parser = argparse.ArgumentParser(
description='Blender Agent Harness - AI 可调用的 Blender CLI',
formatter_class=argparse.RawDescriptionHelpFormatter
)
subparsers = parser.add_subparsers(dest='command', help='可用命令')
# render 命令
render_parser = subparsers.add_parser('render', help='渲染 3D 场景')
render_parser.add_argument('--input', required=True, help='输入 .blend 文件')
render_parser.add_argument('--output', required=True, help='输出图片路径')
render_parser.add_argument('--width', type=int, default=1920)
render_parser.add_argument('--height', type=int, default=1080)
render_parser.add_argument('--quality', type=int, default=100)
# create-mesh 命令
mesh_parser = subparsers.add_parser('create-mesh', help='创建网格物体')
mesh_parser.add_argument('--primitive', choices=['cube', 'sphere', 'cylinder', 'plane'])
mesh_parser.add_argument('--radius', type=float, default=1.0)
mesh_parser.add_argument('--x', type=float, default=0.0)
mesh_parser.add_argument('--y', type=float, default=0.0)
mesh_parser.add_argument('--z', type=float, default=0.0)
# export 命令
export_parser = subparsers.add_parser('export', help='导出场景')
export_parser.add_argument('--input', required=True, help='输入 .blend 文件')
export_parser.add_argument('--format', choices=['obj', 'fbx', 'gltf', 'stl'])
export_parser.add_argument('--output', required=True, help='输出路径')
args = parser.parse_args()
if args.command == 'render':
cmd_render(args)
elif args.command == 'create-mesh':
cmd_create_mesh(args)
elif args.command == 'export':
cmd_export(args)
else:
parser.print_help()
if __name__ == '__main__':
main()
阶段 4:交互式 REPL(Interactive REPL)
除了标准 CLI,流水线还会生成一个交互式 REPL(Read-Eval-Print Loop),方便 Agent 在对话模式下使用:
# REPL 模式示例
def blender_repl():
"""Blender 交互式 REPL"""
context = {"scene": None, "objects": []}
while True:
try:
line = input("blender> ")
if line.strip() in ('exit', 'quit'):
break
# 解析命令
cmd, args = parse_command(line)
# 在 Blender 中执行
result = execute_in_blender(cmd, args, context)
# 更新上下文
update_context(context, result)
# 输出结果
print(json.dumps(result, ensure_ascii=False))
except Exception as e:
print(json.dumps({"status": "error", "error": str(e)}))
REPL 的优势在于:
- 状态保持:不需要每次都重新加载场景
- 增量操作:可以逐步构建复杂场景
- 错误恢复:出错时可以从当前状态重试
阶段 5:测试规划(Test Planning)
流水线会自动规划测试用例,覆盖:
- 单个命令的正确性
- 命令组合的工作流
- 边界条件(空文件、超大文件、特殊字符)
- 错误处理(文件不存在、参数无效)
阶段 6:测试生成与执行(Test Generation)
# 自动生成的测试示例
import pytest
import subprocess
import json
class TestBlenderCLI:
def test_render_creates_output(self, tmp_path):
"""测试渲染命令能正确生成输出文件"""
input_file = create_test_blend_file(tmp_path)
output_file = tmp_path / "render_output.png"
result = subprocess.run(
["cli-anything-blender", "render",
"--input", str(input_file),
"--output", str(output_file),
"--width", "800", "--height", "600"],
capture_output=True, text=True
)
assert result.returncode == 0
assert output_file.exists()
output = json.loads(result.stdout)
assert output["status"] == "success"
assert output["resolution"] == "800x600"
def test_render_invalid_input_returns_error(self, tmp_path):
"""测试无效输入返回错误"""
result = subprocess.run(
["cli-anything-blender", "render",
"--input", "/nonexistent/file.blend",
"--output", str(tmp_path / "out.png")],
capture_output=True, text=True
)
assert result.returncode != 0
output = json.loads(result.stdout)
assert output["status"] == "error"
def test_create_mesh_default_values(self, tmp_path):
"""测试创建网格的默认参数"""
result = subprocess.run(
["cli-anything-blender", "create-mesh",
"--primitive", "cube"],
capture_output=True, text=True
)
assert result.returncode == 0
output = json.loads(result.stdout)
assert output["status"] == "success"
assert output["vertices"] == 8 # 立方体有 8 个顶点
阶段 7:文档生成与打包(Documentation & Packaging)
最后一步是生成完整的文档和打包:
- README.md:包含安装说明、命令列表、示例用法
- setup.py / pyproject.toml:Python 包管理
- CLI-Hub 注册:自动注册到 CLI-Hub 生态
- Agent 适配文件:为 Claude Code、Codex 等生成适配配置
四、CLI-Hub 生态:从工具到平台
CLI-Anything 不仅仅是一个工具,它正在构建一个生态系统——CLI-Hub。
4.1 CLI-Hub 是什么?
CLI-Hub 是一个 CLI 工具的注册表和分发平台,类似于 npm 之于 Node.js。开发者可以:
- 浏览:在 clianything.cc 上查看所有可用的 CLI 工具
- 安装:一键安装到本地
- 贡献:为新软件生成 CLI harness 并提交
- 评分:对已有工具的质量和实用性打分
截至 2026 年 8 月,CLI-Hub 已经收录了超过 100 个 CLI 工具,覆盖以下类别:
| 类别 | 代表工具 | 说明 |
|---|---|---|
| 图形编辑 | GIMP, Inkscape, Krita | 图像处理和矢量绘图 |
| 3D 建模 | Blender, FreeCAD, Godot | 3D 建模和游戏引擎 |
| 办公套件 | LibreOffice, Joplin, Obsidian | 文档编辑和知识管理 |
| 开发工具 | LLDB, iTerm2, QGIS | 调试、终端、地理信息 |
| 音视频 | Audacity, Kdenlive, OBS Studio | 音频编辑、视频编辑、直播 |
| 网络工具 | AdGuard Home, JumpServer | 网络安全和运维 |
| 数据分析 | ChromaDB, Exa | 向量数据库和搜索 |
| 工作流 | N8N, Dify, Mermaid | 自动化和可视化 |
4.2 多 Agent 平台支持
CLI-Anything 的一大优势是它支持多种 AI Agent 平台。同一个 CLI 工具可以同时被 Claude Code、Codex、OpenClaw、Hermes Agent 调用。
# Claude Code 安装
/plugin marketplace add HKUDS/CLI-Anything
# Codex 安装
/install-skill HKUDS/CLI-Anything
# OpenClaw 安装
openclaw skill install CLI-Anything
# Hermes Agent 安装
hermes skill add CLI-Anything
每个平台都有对应的适配层(adapter),负责将平台的工具调用格式转换为 CLI 命令:
# Claude Code 适配器
class ClaudeCodeAdapter:
def to_tool_definition(self, cli_command):
return {
"name": f"cli_anything_{cli_command.name}",
"description": cli_command.description,
"input_schema": cli_command.params_to_json_schema()
}
def execute(self, tool_name, params):
# 将 Claude Code 的工具调用转换为 CLI 命令
cmd = self.parse_tool_name(tool_name)
args = self.params_to_args(params)
return subprocess.run(
["cli-anything", cmd, *args, "--json"],
capture_output=True, text=True
)
# Codex 适配器
class CodexAdapter:
def to_skill_definition(self, cli_command):
return {
"name": cli_command.name,
"description": cli_command.description,
"parameters": cli_command.params_to_codex_schema()
}
五、实战:用 CLI-Anything 让 AI 画架构图
让我们通过一个完整的实战案例,展示 CLI-Anything 的实际效果。
5.1 需求
你需要让 Claude Code 帮你画一个微服务架构图,包括:
- API Gateway
- 3 个微服务(用户服务、订单服务、支付服务)
- 1 个数据库集群
- 服务之间的调用关系
5.2 传统方式(没有 CLI-Anything)
# Claude Code 只能输出 Mermaid 代码
# 你需要手动打开 draw.io,导入,调整格式...
# 或者接受一个不太精确的 ASCII 艺术图
5.3 使用 CLI-Anything
# 第一步:安装 CLI-Anything
/plugin marketplace add HKUDS/CLI-Anything
# 第二步:Claude Code 自动发现 draw.io CLI
claude> 用 draw.io 画一个微服务架构图
# Claude Code 自动调用以下命令序列:
$ cli-anything-drawio create --output microservices.drawio
$ cli-anything-drawio add-shape --input microservices.drawio --type rectangle \
--label "API Gateway" --x 400 --y 50 --width 200 --height 60
$ cli-anything-drawio add-shape --input microservices.drawio --type rectangle \
--label "用户服务" --x 150 --y 200 --width 150 --height 60
$ cli-anything-drawio add-shape --input microservices.drawio --type rectangle \
--label "订单服务" --x 400 --y 200 --width 150 --height 60
$ cli-anything-drawio add-shape --input microservices.drawio --type rectangle \
--label "支付服务" --x 650 --y 200 --width 150 --height 60
$ cli-anything-drawio add-shape --input microservices.drawio --type cylinder \
--label "MySQL 集群" --x 400 --y 350 --width 150 --height 80
$ cli-anything-drawio add-edge --input microservices.drawio \
--from "API Gateway" --to "用户服务" --label "REST"
$ cli-anything-drawio add-edge --input microservices.drawio \
--from "API Gateway" --to "订单服务" --label "REST"
$ cli-anything-drawio add-edge --input microservices.drawio \
--from "API Gateway" --to "支付服务" --label "REST"
$ cli-anything-drawio add-edge --input microservices.drawio \
--from "用户服务" --to "MySQL 集群" --label "SQL"
$ cli-anything-drawio add-edge --input microservices.drawio \
--from "订单服务" --to "MySQL 集群" --label "SQL"
$ cli-anything-drawio add-edge --input microservices.drawio \
--from "支付服务" --to "MySQL 集群" --label "SQL"
# 最终输出:microservices.drawio(可直接在 draw.io 中打开编辑)
5.4 效果对比
| 维度 | 传统方式 | CLI-Anything |
|---|---|---|
| 操作方式 | 手动点击 GUI | CLI 命令序列 |
| 精确度 | 依赖鼠标操作 | 像素级精确 |
| 可复现 | 每次手动操作 | 同一命令同一结果 |
| 可编程 | 不支持 | 支持脚本化 |
| Agent 友好 | 不友好 | 天然友好 |
| 速度 | 10-30 分钟 | 10-30 秒 |
六、Agent Harness 的设计哲学
CLI-Anything 的 Agent Harness 设计遵循几个核心哲学:
6.1 「不做假设」原则
Harness 不假设 Agent 知道底层软件的任何细节。每个命令都自带完整的 --help 文档,Agent 可以动态发现能力:
$ cli-anything-blender --help
用法: cli-anything-blender [命令] [选项]
Blender Agent Harness - AI 可调用的 Blender CLI
可用命令:
render 渲染 3D 场景
create-mesh 创建网格物体
export 导出场景
list-objects 列出场景中的所有物体
modify 修改物体属性
全局选项:
--json 以 JSON 格式输出
--verbose 输出详细日志
--timeout 超时时间(秒)
运行 'cli-anything-blender [命令] --help' 查看命令详情
6.2 「防御性输出」原则
所有输出都经过防御性处理:
def safe_output(data):
"""确保输出总是合法的 JSON"""
try:
return json.dumps(data, ensure_ascii=False)
except (TypeError, ValueError) as e:
return json.dumps({
"status": "error",
"error": str(e),
"raw": str(data)
})
6.3 「幂等性」原则
同一个命令执行多次,结果一致。这对于 Agent 的重试机制至关重要:
def cmd_export(args):
"""导出命令 - 幂等设计"""
# 检查输出文件是否已存在
if os.path.exists(args.output):
if args.force:
os.remove(args.output)
else:
# 已存在则直接返回成功
print(json.dumps({
"status": "success",
"output": args.output,
"skipped": True,
"message": "文件已存在,跳过导出"
}))
return
# 执行导出
do_export(args)
6.4 「渐进式复杂度」原则
简单的任务用简单命令,复杂的任务用组合命令:
# 简单任务:一行命令
$ cli-anything-gimp rotate-image --input photo.jpg --angle 90 --output rotated.jpg
# 中等任务:组合命令
$ cli-anything-gimp batch-process --input ./photos/ --output ./processed/ \
--operations "resize:800x600|sharpen|watermark:logo.png"
# 复杂任务:REPL 交互模式
$ cli-anything-gimp repl
gimp> load "photo.jpg"
gimp> select-rect 100 100 200 200
gimp> apply-filter blur:5
gimp> add-text "Hello World" --x 50 --y 50 --font "Arial:24"
gimp> export "output.jpg"
gimp> exit
七、性能优化与工程实践
7.1 进程池管理
频繁创建和销毁 Blender/GIMP 进程非常耗时。CLI-Anything 使用进程池来优化:
import multiprocessing
from concurrent.futures import ProcessPoolExecutor
class BlenderProcessPool:
def __init__(self, pool_size=4):
self.pool = ProcessPoolExecutor(max_workers=pool_size)
self.processes = {}
def execute(self, script, timeout=30):
"""在 Blender 进程池中执行脚本"""
future = self.pool.submit(
self._run_blender,
script,
timeout
)
return future.result(timeout=timeout + 5)
def _run_blender(self, script, timeout):
"""实际执行 Blender 脚本"""
with tempfile.NamedTemporaryFile(mode='w', suffix='.py') as f:
f.write(script)
f.flush()
result = subprocess.run(
[BLENDER_PATH, '--background', '--python', f.name],
capture_output=True,
text=True,
timeout=timeout
)
return json.loads(result.stdout)
7.2 缓存机制
对于重复的查询操作(如列出场景物体),CLI-Anything 使用缓存:
from functools import lru_cache
import hashlib
class SceneCache:
def __init__(self, ttl=60):
self.cache = {}
self.ttl = ttl
def get_or_compute(self, key, compute_fn):
now = time.time()
if key in self.cache:
value, timestamp = self.cache[key]
if now - timestamp < self.ttl:
return value
value = compute_fn()
self.cache[key] = (value, now)
return value
def invalidate(self, key=None):
if key:
self.cache.pop(key, None)
else:
self.cache.clear()
7.3 错误处理策略
CLI-Anything 采用「不崩溃」原则——即使底层软件出错,Harness 也能优雅地返回错误信息:
def robust_execute(blender_path, script, timeout=30):
"""健壮的 Blender 执行"""
try:
result = subprocess.run(
[blender_path, '--background', '--python', '-'],
input=script,
capture_output=True,
text=True,
timeout=timeout
)
if result.returncode != 0:
# Blender 报错,但我们不崩溃
return {
"status": "error",
"error": result.stderr,
"exit_code": result.returncode
}
# 尝试解析 JSON 输出
try:
return json.loads(result.stdout)
except json.JSONDecodeError:
return {
"status": "success",
"raw_output": result.stdout
}
except subprocess.TimeoutExpired:
return {
"status": "error",
"error": f"执行超时({timeout}秒)",
"suggestion": "尝试增加 --timeout 参数"
}
except FileNotFoundError:
return {
"status": "error",
"error": f"找不到 Blender: {blender_path}",
"suggestion": "请检查 Blender 安装路径"
}
八、与其他方案的对比
8.1 CLI-Anything vs 浏览器自动化(Playwright/Puppeteer)
| 维度 | CLI-Anything | 浏览器自动化 |
|---|---|---|
| 稳定性 | ⭐⭐⭐⭐⭐ 调用原生 API | ⭐⭐ 依赖 UI 元素定位 |
| 速度 | ⭐⭐⭐⭐⭐ 直接调用 | ⭐⭐ 截图+识别+点击 |
| Token 消耗 | ⭐⭐⭐⭐⭐ 极低 | ⭐ 截图消耗大量 Token |
| 覆盖范围 | ⭐⭐⭐ 需要源码 | ⭐⭐⭐⭐⭐ 任何浏览器应用 |
| 精确度 | ⭐⭐⭐⭐⭐ 像素级精确 | ⭐⭐⭐ 受渲染影响 |
8.2 CLI-Anything vs MCP(Model Context Protocol)
| 维度 | CLI-Anything | MCP |
|---|---|---|
| 抽象层级 | 命令行接口 | 工具调用协议 |
| 实现方式 | 自动生成 | 手动编写 |
| 覆盖范围 | 桌面软件 | 外部服务 |
| 生态 | CLI-Hub | MCP Registry |
| 适用场景 | 操作复杂 GUI 软件 | 调用外部 API |
CLI-Anything 和 MCP 是互补的,不是竞争关系。MCP 适合调用外部服务(搜索引擎、数据库、API),CLI-Anything 适合操作桌面软件。
九、未来展望:Agent-Native 软件时代
CLI-Anything 正在推动一个新趋势:Agent-Native 软件。
9.1 从 GUI-First 到 Agent-Native
过去 40 年,软件的设计范式是 GUI-First——为人类设计图形界面。未来的软件可能需要同时为人类和 AI 设计接口:
传统软件:用户 → GUI → 核心逻辑
Agent-Native 软件:用户 → GUI → 核心逻辑 ← CLI/API ← AI Agent
9.2 软件可组合性
当所有软件都有 CLI 接口时,Agent 可以自由组合不同软件的能力:
# 这个工作流在 CLI-Anything 生态中已经可行
$ cli-anything-gimp resize --input photo.jpg --output resized.jpg --width 800
$ cli-anything-mermaid generate --input architecture.mmd --output diagram.svg
$ cli-anything-libreoffice create-doc --title "技术方案" --template proposal.docx
$ cli-anything-drawio import --input diagram.svg --output arch.drawio
Agent 可以像人类开发者一样,把多个工具串联成复杂的工作流。
9.3 开发者的新角色
CLI-Anything 正在改变开发者的工作方式。未来的开发者可能不只是写代码,还需要:
- 为软件编写 Agent Harness
- 设计 Agent 友好的命令行接口
- 在 CLI-Hub 上发布和维护工具
- 评估和优化 Agent 工作流的效率
十、总结
CLI-Anything 解决了一个关键问题:如何让 AI Agent 操作复杂的桌面软件。
它的核心创新在于:
- Agent Harness 概念:为软件创建可靠的执行层,而不是脆弱的 GUI 自动化
- 7 阶段自动化流水线:从源码分析到 CLI 打包,全自动完成
- CLI 统一接口:人和 AI 都能用的接口,
--help发现能力,--json结构化输出 - CLI-Hub 生态:100+ 工具,多 Agent 平台支持
- 防御性设计:幂等性、错误恢复、超时控制,确保长时间任务的可靠性
这个项目来自香港大学数据智能实验室(HKUDS),是 2026 年 AI Agent 工具链领域最重要的开源项目之一。
如果你是 AI Agent 开发者,CLI-Anything 值得深入研究。它不仅提供了现成的工具,更重要的是提供了一种设计思路——如何让软件真正变得 Agent-Native。
项目信息
- GitHub:https://github.com/HKUDS/CLI-Anything
- CLI-Hub:https://clianything.cc
- 开源协议:MIT
- 主要语言:Python
- 支持平台:Claude Code, Codex, OpenClaw, Hermes Agent