记录与回放(浏览器 + 桌面)
记录与回放让智能体学习用户演示的工作流,并将其转化为可重用的技能。两种模式:
- 浏览器模式(默认,证据最丰富):一个有头 Playwright 浏览器(优先使用系统 Google Chrome)将每个用户操作记录到
events.jsonl中,包含多个选择器候选,以及 Playwright 追踪块(trace-NNN.zip)。支持 macOS、Windows 和 Linux。 - 桌面模式(原生应用):一个轻量级单进程记录器(pynput)捕获全局鼠标/键盘事件、活动窗口变化、点击时刻截图以及每次点击时的无障碍目标(macOS AX、Windows UI Automation),存入
desktop-events.jsonl+screens/,密码字段会被遮盖——与 Codex 一致(Codex 也记录事件/上下文流,而非视频),CPU 占用约 1-3%。支持 macOS、Windows 和 Linux(X11)。详见下面的“桌面录制”。
当工作流仅在浏览器中完成时,选择浏览器模式——其语义选择器生成的技能远优于基于坐标的桌面技能。
一次性设置
cd ~/.agents/skills/record-and-replay
node setup.mjs # npm install + (仅当 Chrome 缺失时下载 Chromium)+ 自测试
node install.mjs # 链接到智能体技能目录(macOS/Linux 上为符号链接,Windows 上为 junction)
安装 playwright npm 包。当系统安装了 Google Chrome 时,不会下载浏览器(记录器使用 channel: 'chrome');否则脚本会下载 Chromium。两个脚本均为跨平台(Node)。
录制工作流
-
开始前,告知用户关闭他们不想被捕获的窗口、文件和对话,并且不要输入他们不想被存储的密码。仅在用户准备好开始时,在后台以分离模式启动记录器。始终传递
--name <slug>以便预先确定输出目录:cd ~/.agents/skills/record-and-replay # macOS / Linux: nohup node scripts/recorder.mjs --minutes 30 --name <slug> [--url <startUrl>] \ > ~/.agents/recordings/recorder.log 2>&1 & # Windows (PowerShell): Start-Process node -WindowStyle Hidden -ArgumentList "scripts/recorder.mjs","--minutes","30","--name","<slug>"拥有原生后台运行功能的智能体(如 Claude Code 的 Bash
run_in_background)可以使用它。输出将进入~/.agents/recordings/<slug>/。 -
验证启动一次(启动后约 2-3 秒——仅一次检查,而非轮询循环):确认
~/.agents/recordings/<slug>/session.json存在且"status": "recording"(记录器成功时也会在日志中打印{"status":"recording",...}行)。如果检查失败,读取日志:recording_already_active(退出码 2)表示另一个录制正在占用锁;launch_failed或模块缺失错误表示需要设置。报告实际问题,而非告诉用户录制已开始。 -
启动检查完成后,不要睡眠、轮询或在循环中等待。结束你的回合:告知用户录制已开始、时间限制是多少,以及一个小的浮动控制窗口(右下角,类似于 Codex 的录制控件)带有一个计时器以及暂停/恢复、停止和丢弃(双击确认)按钮。暂停期间不会捕获任何内容——事件和追踪都会停止。如果用户意外关闭了控制窗口,它会自动重新打开;关闭主浏览器窗口也会结束会话(避免使用 Cmd+Q 完全退出浏览器,这可能会丢失最后一分钟的追踪)。启动时传递
--badge以使用页面内徽章代替控制窗口(适用于特殊环境的备选方案)。 -
暂停/恢复(用户要求暂停,或你需要跳过敏感部分):
touch ~/.agents/recordings/<slug>/PAUSE会在 2 秒内暂停;删除文件以恢复。控制窗口按钮和 PAUSE 文件保持同步;session.json携带当前的paused状态。暂停间隔在events.jsonl中显示为paused/resumed标记,并且不会出现在追踪中。 -
当用户表示完成时:
- 如果进程仍在运行,优雅地停止它:
touch ~/.agents/recordings/<slug>/STOP(记录器会在 2 秒内注意到并完成最终处理)。 - 读取
session.json——status: "recording"表示仍在运行;"completed"表示输出已最终确定;"discarded"表示用户按下了“丢弃”——证据文件已被删除,确认此状态并且永远不要基于此创建技能。endReason可以是user_stopped、user_discarded、browser_closed、stop_file、time_limit、signal、event_limit之一。 - 在回应之前检查捕获的事件:运行
node scripts/summarize.mjs <outDir>获取紧凑的时间线,然后直接读取events.jsonl以获取需要细节的步骤。
- 如果进程仍在运行,优雅地停止它:
-
取消由内容决定,而非
endReason:如果录制包含很少或没有kind: "dom"事件——无论endReason是什么——都将其视为已取消。确认即可,不要创建或更新技能。 -
如果录制包含足够的信息来识别可重用的工作流,默认情况下创建或完善一个技能——即使用户没有明确要求。不要只生成摘要或回放计划就停止。遵循下面的“从录制创建技能”——从一轮简短的问题澄清开始。
-
如果录制过于单薄或模糊,无法确定工作流,则不要猜测。解释不清楚的地方,并向用户询问缺失的部分。
并发录制
同一时间只能有一个活动的录制(锁文件 ~/.agents/recordings/.lock)。如果记录器以 recording_already_active 退出,不要强制启动另一个;告知用户录制已在进行中,并询问是使用它还是先停止它。使用相同的 --name 重新启动是安全的:之前的 events.jsonl 会被保存为带时间戳的 .bak 文件,而不是被追加。
解释事件
events.jsonl 是主要证据;session.json 仅提供时间/路径信息;trace-NNN.zip 块是 DOM 级别的真实依据(npx playwright show-trace <outDir>/trace-*.zip;session.json 的 traceChunks 按顺序列出它们)。追踪默认为轻量模式——每次操作的完整 DOM 快照,但无连续截图(保持低 CPU 占用)。当用户想要像素级视觉证据时,使用 --trace full 启动;或者使用 --trace off 以获取最低影响。
每行是一个事件:{seq, t(自开始以来的毫秒数), kind, type, url, ...}。
kind: "page"——导航、下载、对话框、标签页打开/关闭。导航将工作流划分为不同阶段。kind: "dom"——用户操作。target.selectors携带多个选择器候选:testId、role({role, name})、id、nameAttr、text、css。生成回放代码时,按此顺序优先选择;css是最后的手段。type: "input"事件是去抖的——每个字段一个事件,包含最终值(在失焦、回车、更改和表单提交时刷新)。密码/信用卡/OTP 类字段(英文和土耳其语名称:password, parola, şifre, kart, kimlik…)到达时已预遮盖(***MASKED***,masked: true)。selection和copy事件揭示了用户正在处理的内容——当用户提到“这个”或“我选中的东西”时,通常是最好的线索。类似秘密的选择(OTP、API 密钥、令牌)会被遮盖。paste事件仅携带长度/词数,从不包含内容。- 敏感数据:遮盖是启发式的,并非保证——并且它仅适用于
events.jsonl。追踪块不被遮盖:DOM 快照包含原始输入值(包括在 JSONL 中被遮盖的值),截图会捕获屏幕上所有可见内容(泄露的令牌、2FA 码、余额)。将整个~/.agents/recordings/<name>/目录视为敏感:仅在本地检查,从不上传或提交,也绝不在摘要或生成的技能中引用其中的字面秘密——使用占位符或通用描述。
从录制创建技能
在编写之前阅读 references/skill-authoring.md:它包含问题库、前置元数据限制、SKILL.md 骨架、捆绑脚本的规则和质量检查清单。如果您的环境中提供了 skill-creator 技能,其指南也适用。创建一个实际可发现的技能(一个包含 SKILL.md 的文件夹),而不仅仅是 Markdown 运行手册。
复制此清单并逐项勾选:
- [ ] 1. 总结录制内容;记录所有差距(决策、遮盖部分、盲点)
- [ ] 2. 澄清:一次消息,最多 6 个问题,仅针对差距
- [ ] 3. 检查是否存在涵盖此工作流的现有技能 → 更新它而非重复创建
- [ ] 4. 编写技能 + evals/evals.json(录制内容作为测试用例 1)
- [ ] 5. 验证:node scripts/export-skill.mjs <skillDir> --check → 修复错误,重新运行
- [ ] 6. 提供触发检查 + 一次试运行;将修正合并回去,增加 metadata.version
- [ ] 7. 提供 claude.ai ZIP 导出
第 2 步——编写前澄清。 没有音频:录制展示了发生了什么,而不是为什么。从录制中回答其所展示的内容,然后询问用户——一次,在单条消息中,最多 6 个问题——关于其无法展示的内容:结果以及如何判断是否成功、哪些值在不同运行间会变化、为什么在特定时刻选择了 X、哪些操作是绕路、他们会说什么来触发此技能(以及不应该触发什么)、以及哪些操作需要确认。引用你指的时刻(“在 02:14 你清除了日期过滤器——为什么?”)。如果你有结构化提问工具,使用它;否则用普通聊天。只有当录制内容加上用户的请求已经回答了一切时,才跳过此轮,并说明原因。
编写规则:
- 将录制视为用户预期结果的证据,而非逐像素回放的脚本。如果连接器/API/CLI/MCP 工具能够以语义方式达到相同结果(创建日历事件、打开 PR、发布消息),优先选择它们,而非 UI 自动化。
- 当确实需要 UI 回放时,从
scripts/replay-template.mjs生成 Playwright 脚本:语义定位器(getByTestId>getByRole>getByLabel>getByText),每个关键操作后跟一个验证步骤,凭据从环境变量获取。除非事件流不提供更好的目标,否则绝不要使用原始坐标。 - 桌面步骤命名捕获的目标(角色 + 名称 + 窗口,例如 Button "Save" in "Invoice — Acme"),以便无障碍树工具可以找到它;仅当未捕获到目标时使用坐标。
- 记录器的持久配置文件(
~/.agents/recordings/.browser-profile)会保留跨会话的登录状态,因此生成的技能通常不需要登录步骤。安全:该目录包含活动的认证会话材料(cookies/localStorage;Playwright 使用模拟钥匙串启动 Chrome,因此将其视为明文凭据。切勿未经加密提交、共享或备份——记住,任何重用它的回放技能都将使用用户的登录信息。对于不受信任或高敏感度的站点录制,优先使用一次性配置文件(--out加临时配置文件)或在之后清除配置文件。 - 将新技能保存到
~/.agents/skills/<skill-name>/(文件夹名 =name,kebab-case),并将其符号链接到智能体技能目录(参见install.mjs的模式),以便此机器上的每个智能体都可以使用它们。 - 将变化的参数化(日期、金额、名称),将不变的内容硬编码。在生成的 SKILL.md 中说明工作流的目的和验证标准。切勿将秘密或遮盖值复制到技能中。
为 claude.ai 导出(提供此选项;仅按需运行):node scripts/export-skill.mjs ~/.agents/skills/<name> 写入 ~/.agents/exports/<name>.zip(ZIP 根目录下为文件夹;排除 README、evals、缓存和录制证据;成功前会读回存档进行验证)。如果技能使用了仅 Claude Code 的前置元数据(disable-model-invocation,……),添加 --strip-cc-keys。告知用户文件位置以及该文件可以在 Customize › Skills › + › Upload a skill(必须启用代码执行)下上传。
桌面录制(macOS、Windows、Linux/X11)
设置:node setup.mjs(从 requirements-desktop.txt 创建最小的 .venv-desktop Python 环境——pynput+mss+pillow,Windows 上加上 comtypes,约 50 MB;需要 uv)。
权限(macOS):记录器预先检查权限并报告机器可读的状态,因此永远不要猜测。start 会打印 permissions: {inputMonitoring, screenRecording, grantTo} 以及当有缺失时的 warning,并自动弹出系统对话框并打开正确的设置面板(--no-permission-prompt 禁用此功能;node scripts/desktop-record.mjs permissions 可按需运行)。grantTo 指定用户必须授予权限的应用——TCC 授权绑定到承载智能体的 .app 捆绑包,而非 Python,并且之后必须重启该应用。逐字传递 grantTo;告诉用户“授权给你的终端”通常是错误的。Windows 不需要权限,也不需要管理员权限。
引擎是单进程记录器(~0-3% CPU):输入事件流 + 活动窗口/标题更改 + 每次点击时的半分辨率 JPEG(最大 1/700ms)→ desktop-events.jsonl + screens/。每次点击还携带光标下元素的无障碍描述(kind: "target" 行,通过 forSeq 连接到点击):role、name、automationId、window、ancestors——一个语义目标,例如 Button "Save" 而非裸坐标(macOS AX、Windows UI Automation;Linux 上无)。键入作为 type: "text" 事件到达,携带每次输入的最终值(退格更正已应用);快捷键和特殊键作为 press 事件(ctrl+c、enter)。截图、目标查询和焦点检查在工作线程上运行,从不在输入回调中:缓慢的回调会导致 macOS 事件 tap 被禁用和 Windows hook 被静默移除(记录器也会监视后者并重新安装 hooks)。
这与 Codex 一致:Codex 的记录与回放也记录……
……[此处截断]