如何用 cli-anything-macrocli 编写宏 YAML 定义并运行参数化 GUI 工作流
MacroCLI 是 CLI-Anything 仓库中的一个分层 CLI 子系统,它把 GUI 操作流程固化成参数化、可被命令行调用的宏(YAML 文件)。你写好宏定义后,只需要执行一条 macro run <名称> --param k=v 命令,运行时会处理参数校验、前置条件检查、后端路由、步骤执行和后置条件验证,调用者不直接碰 GUI。本文的任务是:在 macrocli 包中新建一个宏 YAML、注册并验证它,然后用参数执行一条 GUI 工作流并核对结果。环境要求来自项目文档:Python 3.10+,依赖 PyYAML、click、prompt-toolkit;GUI 类步骤(semantic_ui、visual_anchor)需要可用的 X 显示环境,无头服务器可参考 DEMO.md 中基于 Xvfb 的虚拟桌面方案。
安装与依赖检查
进入 harness 目录并安装(可编辑安装):
cd macrocli/agent-harness
pip install -e .
按需安装可选扩展(见 MACROCLI.md):
pip install -e ".[visual]" # visual_anchor 后端(mss, Pillow, numpy, pynput)
pip install -e ".[gui_agent]" # gui_agent 后端(openai, mss, Pillow)
pip install -e ".[all]" # 全部
其他可选系统依赖:xdotool(Linux 上 semantic_ui 后端)、pyautogui(gui_macro 后端)、psutil(更可靠的 process_running 检查)。如果你的宏要走视觉自动化路线(visual_anchor),.[visual] 扩展是必需的;纯文件编辑(file_transform)或命令行(native_api)宏则不需要。
GUI 宏执行前确保环境变量指向一个真实显示,例如文档演示环境使用 export DISPLAY=:99。
宏 YAML 的结构与可用字段
宏是位于 cli_anything/macrocli/macro_definitions/ 下的 YAML 文件。SKILL.md 给出的最小 schema 如下,也是 macro define 脚手架生成的模板基础:
name: my_macro
version: "1.0"
description: What this macro does.
parameters:
output:
type: string
required: true
description: Where to write results.
example: /tmp/result.txt
preconditions:
- file_exists: /path/to/input
steps:
- id: step1
backend: native_api
action: run_command
params:
command: [my-app, --export, "${output}"]
timeout_ms: 30000
on_failure: fail # or: skip, continue
postconditions:
- file_exists: ${output}
- file_size_gt: [${output}, 100]
outputs:
- name: result_file
path: ${output}
agent_hints:
danger_level: safe # safe | moderate | dangerous
side_effects: [creates_file]
reversible: true
关键点:
${参数名}用于在 steps 中引用运行时传入的参数,参数值来自命令行的--param key=value。- 每个 step 用
backend字段声明执行后端。可用后端及优先级(见 MACROCLI.md):
| Backend | 优先级 | 触发方式 | 用途 |
|---|---|---|---|
native_api |
100 | backend: native_api |
子进程 / shell 命令 |
gui_macro |
80 | backend: gui_macro |
预编译坐标回放(pyautogui) |
visual_anchor |
75 | backend: visual_anchor |
模板匹配点击/输入(需 .[visual]) |
file_transform |
70 | backend: file_transform |
XML、JSON、文本文件编辑 |
gui_agent |
60 | backend: gui_agent |
视觉模型驱动的自动化(需 .[gui_agent]) |
semantic_ui |
50 | backend: semantic_ui |
无障碍 API + 键盘(xdotool) |
recovery |
10 | backend: recovery |
重试 + 回退编排 |
- 路由引擎遵循 step 声明的
backend:字段;若该后端在当前环境不可用,会沿优先级列表向下选择替代后端。 - 前后置条件支持的条件类型(同上来源):
file_exists(路径)、file_size_gt([路径, 最小字节数])、process_running(进程名)、env_var(变量名)、always(true/false)。 on_failure决定步骤失败时的行为:fail终止宏,skip/continue让宏继续——用于"可能出现的对话框确认"这类尽力而为的步骤。
仓库里的现成示例可以直接对照:export_file.yaml(native_api + file_transform 组合)、transform_json.yaml(file_transform 的 json_set)、以及 demo/ 下的 gedit GUI 宏,如 gedit_save_as.yaml。
编写并注册新宏
- 生成脚手架(会创建一个带注释占位的 YAML 文件,
--output指定写入路径):
cli-anything-macrocli macro define my_macro --output \
cli_anything/macrocli/macro_definitions/examples/my_macro.yaml
-
编辑该文件,把
parameters、steps等占位内容替换为你的实际工作流。参照仓库已有示例填写backend与action;写好后先用macro info检查 schema 能否被解析(见下节)。也可以完全手写文件,直接放入
cli_anything/macrocli/macro_definitions/下。 -
把新宏登记到 manifest.yaml。现有条目格式如下:
macros:
- name: export_file
path: examples/export_file.yaml
version: "1.0"
为你的宏追加一条同格式记录即可。注意:这一步只影响"按名称运行"——用 --macro-file 直接指定 YAML 路径运行时可以绕过注册表,无需改 manifest。
验证宏定义与后端可用性
# 结构校验(可省略名称校验全部宏)
cli-anything-macrocli macro validate my_macro --json
# 查看宏的完整 schema(参数、步骤、条件)
cli-anything-macrocli macro info my_macro --json
# 检查当前环境各后端的可用性与优先级
cli-anything-macrocli backends --json
backends --json 会对每个后端输出 available 与 priority 字段(DEMO.md 中展示了全部后端 available: true 时的文档示例输出)。如果你的步骤声明了 visual_anchor 而输出中该后端为 available: false,先确认已安装 .[visual] 扩展;否则运行时会回落到低优先级后端。
先 dry-run 再执行参数化工作流
对有副作用的宏,先用 dry-run 模拟执行,确认参数能通过与前置条件相关的检查,且不产生实际副作用(见 README.md):
cli-anything-macrocli --dry-run macro run my_macro \
--param output=/tmp/result.txt --json
dry-run 结果里 "dry_run": true 会出现在 telemetry 中。确认无误后正式执行:
cli-anything-macrocli macro run my_macro \
--param output=/tmp/result.txt --json
参数用 --param key=value 传递,多个参数重复该选项;未出现在 --param 中的必填参数或前置条件不满足都会导致失败。所有命令加 --json 后输出统一结构(结构示例来自 SKILL.md):
{
"success": true,
"macro_name": "export_file",
"output": { "exported_file": "/tmp/result.txt" },
"error": "",
"telemetry": {
"duration_ms": 312,
"steps_total": 2,
"steps_run": 2,
"backends_used": ["native_api"],
"dry_run": false
}
}
判断规则与文档一致:不要只看退出码,要检查 success 字段;success 为 false 时读取 error 字段定位原因;失败时进程退出码为 1。output 中返回的是宏 outputs 段声明的命名输出(例如 ${output} 对应的产物路径)。
用仓库内置的 GUI 宏走一遍完整流程
以 demo/ 中已注册的 gedit 宏为例(需 Linux 上运行 gedit 的显示环境)。前置条件 process_running: gedit 意味着宏执行前 gedit 必须在运行,可先用 gedit_new_window 宏启动它:
# 1. 查看已注册宏与 gedit_save_as 的参数
cli-anything-macrocli macro list --json
cli-anything-macrocli macro info gedit_save_as --json
# 2. 打开 gedit
cli-anything-macrocli --json macro run gedit_new_window
# 3. dry-run 检查参数
cli-anything-macrocli --dry-run macro run gedit_save_as \
--param output_path=/tmp/macrocli_demo.txt --json
# 4. 执行:另存为指定路径
cli-anything-macrocli --json macro run gedit_save_as \
--param output_path=/tmp/macrocli_demo.txt
# 5. 验证文件已创建
cat /tmp/macrocli_demo.txt
gedit_save_as 的内部步骤(见 gedit_save_as.yaml)是:聚焦 gedit 窗口(semantic_ui)→ Ctrl+Shift+S 打开另存为 → 等待 "Save As" 对话框 → Ctrl+L 打开路径框 → 清空 → 输入 ${output_path} → Enter 确认。执行成功的 JSON 输出形如(DEMO.md 文档示例):
{
"success": true,
"telemetry": { "duration_ms": 39, "backends_used": ["native_api", "semantic_ui"] }
}
backends_used 会列出实际参与执行的后端,可用于确认步骤确实走了预期的路由。
不注册 manifest 的替代运行方式
对临时宏、或录制器生成的宏,可以直接用 YAML 文件路径运行,绕过注册表(CLI 的 --macro-file 参数,DEMO.md 中演示了该用法):
cli-anything-macrocli --json macro run my_macro \
--macro-file /tmp/my_recording/my_macro.yaml \
--param output_path=/tmp/out.txt
宏名仍作为第一个位置参数传入,实际定义以文件为准。
常见问题与边界
run_command执行 GUI 应用超时 30 秒:run_command会等待进程退出,而 GUI 应用不会退出。文档给出的解法是改用start_processaction(后台启动、不等待)。这是 DEMO.md 中已修复的已知问题。wait_for_window找不到窗口:conda run会清除DISPLAY环境变量。改用conda activate激活环境后直接运行,不要用conda run包裹cli-anything-macrocli。visual_anchor回放点击位置不准:录制回放基于窗口相对百分比坐标,窗口大小与录制时不一致会偏移;确保回放时窗口大小一致,或调整宏里的x_pct/y_pct。- 条件不支持项:前后置条件仅支持上表列出的 5 种类型;
gui_agent后端需要.[gui_agent]扩展并通过MACROCLI_MODEL(必填)、MACROCLI_API_KEY、MACROCLI_BASE_URL(非 OpenAI 官方 host 时才需要)环境变量配置。
后续可用命令
- 用
cli-anything-macrocli session history查看本次会话的宏执行历史,session save落盘持久化。 - 不想手写 YAML 时,可以用
macro record <name>录制一次真实 GUI 操作自动生成宏包(需要 mss、Pillow、pynput),配合--parameterize把硬编码的输入值交互式地转成--param参数,或用--auto让 LLM 建议参数名。 - 完整测试可用:
python3 -m pytest cli_anything/macrocli/tests/ -v -s,文档记录的结果为 64 passed。
更多格式细节与后端说明见 MACROCLI.md 与 DEMO.md。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0631
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
HivisionIDPhotos⚡️HivisionIDPhotos: a lightweight and efficient AI ID photos tools. 一个轻量级的AI证件照制作算法。Python09
DragonOSDragonOS is an operating system developed from scratch using Rust, with Linux compatibility. It is designed for **Serverless** scenarios. 使用Rust从0自研内核,具有Linux兼容性的操作系统,面向云计算Serverless场景而设计。Rust00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00