news 2026/9/14 14:18:50

qwen-code Cua Driver 会话轨迹录制与回放实战指南:RECORDING 技能深度解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
qwen-code Cua Driver 会话轨迹录制与回放实战指南:RECORDING 技能深度解析

qwen-code Cua Driver 会话轨迹录制与回放实战指南:RECORDING 技能深度解析

【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code

本文围绕 qwen-code 仓库中 cua-driver(Rust 实现)的 RECORDING.md 技能文档展开,系统讲解会话级「操作轨迹录制 + 回放」机制:它如何在 macOS / Windows / Linux 上采集动作序列与前/后状态,如何产出可供演示、回归比对和训练数据使用的 turn 目录产物,以及replay_trajectory回放的边界与最佳实践。读完本文,你将掌握qwen-cua-driver recording start|status|stop与 MCP 录制工具族的完整用法,并理解其底层实现原理(源自 recording.rs 等源码)。

一、功能定位:会话级的轨迹录制器

start_recording是一个会话作用域(session-scoped)的轨迹录制器。启用后,每次动作类工具调用(clickright_clickscrolltype_textpress_keyhotkeyset_value)都会在调用方指定的输出目录下写入一个带编号的 turn 文件夹,同时采集动作前后的应用可访问性状态与窗口截图。该能力适合三类典型用途:

  • 演示与录屏:把 turn 文件夹回放给观众,精确展示 Agent 看到了什么、做了什么;
  • 回归比对:把同一序列在未来的构建上重跑,将新轨迹与保存的旧轨迹做 diff;
  • 训练数据采集:每个 turn 都是一个现成的(state, action, next_state)三元组,可直接用于离线学习。

值得强调的是:只有动作类工具会被记录。只读工具(get_window_statelist_windowsscreenshotlist_apps、权限探测类工具、Agent 光标 getter/setter,以及录制控制工具自身)不写入轨迹,因此录制不会因为感知类调用而产生噪音。

录制是显式开启的:该技能不会自动启用录制,必须由客户端在用户提出「记录本次会话」等需求时显式调用start_recording({output_dir: …}),并在结束时调用stop_recording({})。若用户要求录屏但不需要视频,可传入record_video: false关闭视频采集。

二、跨平台视频采集后端:原生 SCKit 与 ffmpeg 子进程

start_recording在录制逐 turn 证据的同时,还会把主显示器画面采集为<output_dir>/recording.mp4(H.264 / 30 fps),视频在stop_recording时完成收尾(finalize)。视频采集的后端按平台分流:

平台视频后端前置依赖说明
macOS原生 ScreenCaptureKit(SCStream+SCRecordingOutput无(无需 ffmpeg)要求 macOS 15.0+(SCRecordingOutput于 macOS 15 引入);录制进程继承 daemon 的「屏幕录制」授权,不会出现额外的子进程 TCC 弹窗、快速失败或第二次授权交互
Windowsffmpeg 子进程(gdigrab采集整块虚拟桌面)ffmpeg 需在 PATH(winget install Gyan.FFmpeg缺 ffmpeg 时逐 turn 采集继续运行,last_error携带安装提示
Linuxffmpeg 子进程(x11grab$DISPLAY环境变量,缺省:0.0ffmpeg 需在 PATH(apt install ffmpeg同上;可用CUA_DRIVER_RS_DRAW_SYSTEM_CURSOR=0隐藏真实系统指针,让画面只保留合成 Agent 光标

ffmpeg 后端的具体编码参数见 video_ffmpeg.rs:统一使用libx264 -preset ultrafast -pix_fmt yuv420p,并带-movflags +faststart(便于边录边播);由于 yuv420p 要求偶数尺寸,采集管线会先用pad=ceil(iw/2)*2:ceil(ih/2)*2补齐奇数分辨率(例如 1512×949 的 Win11 屏幕)。ffmpeg 的优雅关闭方式是向其 stdin 发送q\n以收尾 moov atom,若 3 秒内未退出则强制 kill(此时 mp4 不可播放,finalized: false会明确告知调用方);启动时还有 1.5 秒的快速失败探测,ffmpeg 一旦启动即崩溃,错误信息会携带 stderr 尾部。

macOS 侧的实现见 video_sckit.rs:进程内SCStream+SCRecordingOutput以 H.264 / MP4 编码写入输出路径,stop_capture()会同步收尾 moov atom;启动时若发现残留的旧recording.mp4会先行清理,避免追加写入。

视频默认开关的细节:RECORDING 文档以 CLI 视角描述「Video on by default」——CLIrecording start路径确实强制开启视频(见 recording.rs 中configure()的注释)。但 MCP 的start_recording工具在 recording_tools.rs 中默认record_video: false(显式传true才录视频)。因此实际行为取决于调用入口:CLI 默认带视频,MCP 默认不带。另外,即使 ffmpeg 缺失或启动失败,逐 turn 的截图 + JSON 采集不受影响,last_error会携带诊断信息。

三、开始 / 停止录制:两套等价入口

录制有两个等价的操作面:MCP 工具start_recording/stop_recording/get_recording_state/replay_trajectory)和更友好的CLI 子命令组qwen-cua-driver recording start|stop|status(对工具做了人性化输出包装)。

CLI 子命令方式

qwen-cua-driver recording start ~/cua-trajectories/run-1 # … 运行工作流 … qwen-cua-driver recording status # -> enabled / disabled, next_turn, output_dir qwen-cua-driver recording stop # -> "Recording stopped. (video → recording.mp4)"

原始 MCP 工具方式

qwen-cua-driver start_recording '{"output_dir":"~/cua-trajectories/run-1"}' qwen-cua-driver get_recording_state qwen-cua-driver stop_recording '{}'

关于这两种方式,有几条关键语义(可从 cli.rs 的run_recording_cmd与 recording_tools.rs 的invoke实现得到印证):

  • 需要运行中的 daemonrecording子命令要求先启动qwen-cua-driver serve &,因为录制状态是**进程内(per-process)**的。daemon 未运行时会提示Start it first with: qwen-cua-driver serve并退出;唯一的例外是recording render子命令(纯文件到文件的渲染,无需 daemon,见下文第七节)。
  • 路径处理output_dir支持~展开(代码中手动替换HOME),目录不存在时连同中间层级一起创建。
  • turn 编号:每次(重新)启用录制,turn 编号都从1重新开始,与目录中已有内容无关;编号为五位零填充(turn-00001/)。
  • 状态仅存内存:daemon 重启后录制状态重置为 disabled,磁盘上不会残留“启用”标记。
  • 停止的幂等性stop_recording对已停止的会话是无操作(no-op),不会报错;带视频时返回last_video_path指向已收尾的 mp4。
  • 手动停止是无条件的:无论录制由哪个会话开启,手动stop_recording都会停掉当前激活的录制;而「某客户端断开连接只能回收自己发起的录制」这一按会话归属的回收逻辑,由 daemon 的session_end生命周期钩子调用stop_owner(sid)完成,而不是由该工具承担(防止会话 A 断开时误停会话 B 后来开启的录制)。

四、每个 turn 文件夹的产物结构

每次动作调用都会产生一个turn-NNNNN/文件夹(五位零填充计数器),其中包含以下文件:

文件含义
before_state.json/after_state.json动作执行前后、目标应用的可访问性状态快照;字段形态与get_window_statetree_markdownelement_count一致
before.png/after.png动作执行前后目标窗口的图像;即使窗口被其他窗口遮挡,窗口级采集仍限定在目标窗口范围内
evidence.json每个阶段(before/after/click)的采集状态清单;期望的采集缺失时会有明确的分类而不是从 turn 中消失(详见下文)
app_state.json/screenshot.png兼容别名:分别等价于after_state.jsonafter.png,供旧版轨迹读取器使用
action.json动作核心记录:工具名、完整输入参数、结果摘要、结果错误标志、pid、点击点(如适用)、ISO-8601 时间戳
click.png仅 click 家族动作(clickdouble_clickright_click)产生:在before.png副本上用红色标记绘制点击点

click.png 的两种寻址模式

click.png对两种寻址模式都做了覆盖(这是文档强调的实现细节):

  • 显式x, y像素点击:直接使用调用传入的坐标;
  • element_index寻址点击:通过实时的 AX/UIA 缓存把元素索引解析为元素中心点,再换算为窗口局部截图像素(resolve_click_point的实现见 recording.rs,其坐标空间与get_window_state返回的 PNG 完全一致)。

此外有两个「负向」分类需要理解:当 driver 在目标解析前拒绝了一次点击(没有对准任何输入),click.png不生成,并在evidence.json中显式分类为not_applicableaction_refused_before_target_resolution);而一次已派发的点击若无法解析或渲染标记,则会被计为证据失败(evidence failure),两者语义严格区分。

evidence.json:采集状态的显式分类

evidence.json使用cua-turn-evidence/v1schema(见 recording.rs 的write_evidence_manifest),对 before/after 的 state 与 screenshot、以及 click 分别给出captured/unavailable/not_applicable三种状态:

  • captured:期望的产物已成功采集;
  • unavailable:采集失败或回调未注册,携带classification(如capture_failedcapture_hook_unavailableprivacy_suppressed);
  • not_applicable:本就不该采集(如无目标 pid、非点击动作、目标解析前被拒绝的点击)。

这一设计让「缺失」成为可审计的分类事件,而不是从轨迹中悄悄消失。

五、action.json 字段与底层写入路径

action.json是回放的核心输入,其 schema(与 Swift/Windows 参考实现保持一致)如下:

{ "tool": "click", "arguments": { "pid": 844, "window_id": 10725, "element_index": 14 }, "result_summary": "…", "result_error": false, "timestamp": "1789000000.123", "t_ms_from_session_start": 12345, "t_start_ms_from_session_start": 12340, "click_point": { "x": 320.0, "y": 240.0 } }

字段说明:tool为工具名;arguments为完整输入参数(内部注入的下划线前缀键会被剥离——例如 daemon 注入的_session_id绝不会泄漏进持久化轨迹,见strip_internal_keys);result_summary为结果摘要;result_error为结果错误标志;timestamp为 ISO-8601 时间戳(实现上输出为带毫秒的小数 Unix 秒);t_ms_from_session_startt_start_ms_from_session_start为会话起点锚定的毫秒时间,供回放与渲染对齐时序;click_point在点击类动作适用时写入。

录制器的工作方式是先保留、后落盘的两阶段模型:begin_turn(在工具派发前立即预留 turn 目录并采集 before 阶段)→ 工具执行 →finish_turn(派发后采集 after 阶段并一次性写入全部产物)。这样即使调用乱序完成,before/after 也共享同一个稳定的turn-NNNNN目录。每个会话还共享一个单调时钟锚点(session_monotonic_start),让视频、光标采样与action.json的毫秒时间线彼此对齐。

此外,录制会话会在输出目录额外生成两个代码级产物(文档未展开但源码可证):

  • session.json:启动时写入(含schema_versionstarted_at_monotonic_ms、视频块、光标块),停止时重写为最终形态(视频present/path/duration_ms/finalized与光标sample_count);
  • cursor.jsonl:后台光标采样线程以约 30 Hz 轮询记录光标位置,为渲染器提供逐帧光标坐标(见 recording.rs 的CursorSampler启动逻辑)。

六、轨迹回放:replay_trajectory

replay_trajectory({dir})按字典序遍历<dir>/turn-NNNNN/文件夹,读取每个action.json,并以记录的arguments重新调用对应的工具(经由与 MCP/CLI 相同的派发路径,见 recording_tools.rs 的ReplayTrajectoryTool)。

参数说明

参数类型默认值说明
dirstring必填此前由start_recording写出的轨迹目录(支持绝对路径或~开头路径);目录必须存在且至少含一个turn-文件夹
delay_msinteger500每个 turn 之间的间隔毫秒数,用于人类可观察的节奏;schema 上限 10000
stop_on_errorbooleantrue遇到首个工具调用错误是否停止;设为false可尽力跑完整个轨迹

典型用法:

qwen-cua-driver recording start ~/cua-trajectories/demo1 # … 运行工作流 … qwen-cua-driver recording stop # 之后针对新构建回放: qwen-cua-driver replay_trajectory '{"dir":"~/cua-trajectories/demo1","delay_ms":500}'

回放完成后的结构化结果包含attempted/succeeded/failed计数、stop_on_error、每个 turn 的okresult_summary,以及首个失败点(first_failure.turn/first_failure.tool/first_failure.error)。

回放即回归:录制期间的再录制语义

如果回放时录制仍然处于启用状态,回放本身也会被录进当前输出目录——这正是文档明确设计的回归-diff 工作流:在新构建上录制一次回放,然后把两条轨迹做比对。若单个turn-NNNNN/action.json缺失或解析失败,回放会将其记为失败并(在stop_on_error: true时)中断。

七、回放的边界与注意事项:element_index 无法跨会话存活

这是回放最重要的 caveat:element_index不跨会话存活。索引在每次get_window_state快照时都会重新分配,并以(pid, window_id)为键;昨天录制的click({pid, window_id, element_index: 14})今天无法解析——pid 通常不同,window_id 则总是不同。调用会返回Invalid element_indexNo cached AX state

与之相对,像素点击click({pid, x, y}))与键盘类工具press_keyhotkey、不含element_indextype_text)可以干净地回放。element-indexed 动作需要一次实时快照,而回放目前不会重新产出快照(只读工具如get_window_state本身不被录制,recording_tools.rs 的工具描述也明确指出回放不会重新填充按(pid, window_id)键控的元素缓存)。

因此,可靠的回放策略是二选一:

  1. 用像素 + 键盘原语组合轨迹(保证可重放性);
  2. 把轨迹当作回归产物(对比不同构建之间的成功/失败模式),而不是当作可反复驱动的脚本。

另外注意,delay_ms存在上限(schema 中maximum: 10000,invoke 中.min(10_000)二次兜底)。

八、配套:轨迹渲染与 ffmpeg 安装工具

除录制/回放外,还有两个相关的辅助能力:

  • qwen-cua-driver recording render:纯文件到文件的渲染子命令(cli.rs 在 daemon 检查之前先行派发),不需要运行中的 daemon。其加载逻辑见 recording_loader.rs:读取session.json(必需)、recording.mp4(必需,缺失则硬错误VideoMissing)、cursor.jsonl(可选,缺失退化为空向量)与各 turn 的action.json,产出SessionMetadata、按时间排序的ClickEvent/CursorSample/ActionSpan。点击坐标的恢复按优先级依次取arguments.{x,y}click_point→ 从result_summary文本中解析(screen (X,Y))模式(保证 element_index 工作流下缩放渲染仍可用)。
  • install_ffmpeg:确认门控的 ffmpeg 安装工具(见 recording_tools.rs)。不带confirm时只报告将执行的安装命令(只读预览);confirm: true才真正执行;ffmpeg 已在 PATH 时直接提示无需安装。它被标记为destructive + open_world,符合规范的 MCP 客户端也会把它放在人工审批之后。Linux 下支持 apt/dnf/pacman/zypper/apk/snap 等包管理器,macOS 建议brew install ffmpeg,Windows 用winget install Gyan.FFmpeg(ffmpeg 以独立进程方式被调用,从不链接进 driver)。

九、源码导航

若想深入机制,以下文件是直接的阅读入口:

  • 技能文档本体:RECORDING.md(本文主题),其上层使用规范见同目录 SKILL.md
  • 录制会话核心状态机(start/stop/owner、turn 预留与落盘、evidence 清单、session.json 写入):recording.rs
  • 四个录制/回放工具的定义与参数 schema(start_recording/stop_recording/get_recording_state/replay_trajectory/install_ffmpeg):recording_tools.rs
  • 轨迹目录读取与渲染输入装配(session.json/cursor.jsonl/ turn 解析):recording_loader.rs
  • Windows/Linux ffmpeg 子进程后端(gdigrab / x11grab / libx264 参数与优雅关闭):video_ffmpeg.rs
  • macOS 原生 ScreenCaptureKit 后端(SCStream + SCRecordingOutput):video_sckit.rs
  • CLIrecording start|stop|status|render子命令实现:cli.rs

十、小结:何时用、怎么用

一句话总结录制能力的使用决策:

  • 要演示/录屏:CLIrecording start <dir>默认带视频 → 跑工作流 →recording stop,turn 文件夹与 mp4 一起交付;
  • 要做回归:录制一条基线轨迹,换构建后开启录制再replay_trajectory,两条轨迹 diff 即回归结果(回放会被再录制正是为此设计);
  • 要采集训练数据:每个 turn 都是天然的(state, action, next_state)三元组,action.json+before/after状态与图像就是完整样本;
  • 要可靠重放:轨迹尽量由像素点击 + 键盘原语构成,避免 element-indexed 动作;涉及敏感内容(如已登录浏览器配置)时,代码还提供了抑制视觉/可访问性采集的私有 turn 路径(privacy_suppressed分类),保证动作元数据与结构化结果可审计、而页面或对话框内容不被持久化。

无论从哪个入口启用,请记住三条不变式:录制必须显式开启、output_dir~展开并自动创建、录制状态只存活于 daemon 进程内——重启即回到 disabled。

【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/14 14:17:48

AI编程助手选型避坑指南:真实开发场景下的工具决策地图

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/14 14:16:05

Vue3 + Element-Plus 图书管理系统开发实战:从工程化到组件复用

简介&#xff1a;基于Vue3与Element-Plus构建的图书管理系统源码&#xff0c;面向中高级前端开发者或需要快速搭建管理后台的工程师&#xff0c;旨在提供一套完整可用的图书信息增删改查、借阅管理以及用户登录验证的解决方案。压缩包共33个文件&#xff0c;含14个Vue组件、10个…

作者头像 李华
网站建设 2026/9/14 14:13:45

SpringBoot+Vue美食评测系统全栈实践指南

简介&#xff1a;本资源是一套面向Java全栈开发初学者与课程设计者的美食评测系统完整实践方案&#xff0c;聚焦人工智能在信息化管理中的落地应用&#xff0c;解决餐饮领域用户评价、菜品检索与个性化推荐等典型业务问题。压缩包共667个文件&#xff0c;含190个Java后端逻辑代…

作者头像 李华