让你的代理使用 shot-scraper video 记录其工作视频演示Have your agent record video demos of its work with shot-scraper video
shot-scraper 1.10 版本引入了全新的 `shot-scraper video` 命令,专为自动化记录 Web 应用操作而设计。该功能通过解析 `storyboard.yml` 配置文件来定义交互流程,并利用 Playwright 引擎精准执行并录制整个操作过程。这为 AI 代理提供了一种标准化的方式,能够轻松为其自动化的工作成果生成直观的视频演示。
Simon Willison
2026年6月30日
shot-scraper video 是在今天发布的 shot-scraper 1.10 版本中引入的一项新命令,它接收一个定义了针对 Web 应用程序运行例程的 storyboard.yml 文件,并使用 Playwright 来记录该例程的视频。我之前曾撰文探讨过让编程智能体(coding agents)展示其工作成果的重要性;这是我为了帮助它们实现这一目标而做出的最新尝试。
这是一个使用 shot-scraper video 创建的示例视频,它演示了一个仍在开发中的功能,即添加通过粘贴 CSV、TSV 或 JSON 数据在 Datasette 中创建新表的能力:
该视频是通过运行以下命令创建的:
shot-scraper video datasette-bulk-insert-storyboard.yml \
--auth datasette-demo-auth.json --mp4(该 --auth JSON 文件包含一个 cookie,如文档中此处所述。)
这是 datasette-bulk-insert-storyboard.yml 文件:
output: /tmp/datasette-bulk-insert-demo.webm
server:
- uv
- --directory
- /Users/simon/Dropbox/dev/datasette
- run
- datasette
- -p
- 6419
- --root
- --secret
- "1"
- /tmp/demo.db
url: http://127.0.0.1:6419/demo/tasks
viewport:
width: 1280
height: 720
cursor: true
wait_for: 'button[data-table-action="insert-row"]'
javascript: |
(() => {
let clipboardText = "";
Object.defineProperty(navigator, "clipboard", {
configurable: true,
get: () => ({
writeText: async (text) => {
clipboardText = String(text);
},
readText: async () => clipboardText,
}),
});
})();
scenes:
- name: Bulk insert existing table rows
do:
- pause: 0.8
- click: 'button[data-table-action="insert-row"]'
- wait_for: "#row-edit-dialog[open]"
- pause: 0.5
- click: ".row-edit-bulk-insert"
- wait_for: ".row-edit-bulk-textarea"
- pause: 0.5
- click: ".row-edit-copy-template"
- wait_for: "text=Copied"
- pause: 0.8
- fill:
into: ".row-edit-bulk-textarea"
text: |
title,owner,status,priority,notes
Prepare release video,Ana,doing,1,Recorded with shot-scraper
Check pasted CSV import,Ben,review,3,Previewed before inserting
Share the branch demo,Chen,queued,2,Bulk insert creates three rows
- pause: 0.8
- click: ".row-edit-save"
- wait_for: "text=Previewing 3 rows."
- pause: 1.2
- click: ".row-edit-save"
- wait_for: "text=3 rows inserted."
- pause: 1.0
- click: ".row-edit-cancel"
- wait_for: "text=Prepare release video"
- pause: 1.0
- name: Create a table from pasted CSV
open: http://127.0.0.1:6419/demo
wait_for: 'details.actions-menu-links summary'
do:
- pause: 0.8
- click: 'details.actions-menu-links summary'
- click: 'button[data-database-action="create-table"]'
- wait_for: "#table-create-dialog[open]"
- pause: 0.5
- fill:
into: ".table-create-table-name"
text: "launch_metrics"
- click: ".table-create-from-data"
- wait_for: ".table-create-data-textarea"
- pause: 0.5
- fill:
into: ".table-create-data-textarea"
text: |
metric_id,name,score,recorded_on
m001,Activation rate,87.5,2026-06-29
m002,Retention check,72.25,2026-06-30
m003,CSV import health,95,2026-07-01
- pause: 0.8
- click: ".table-create-save"
- wait_for: "text=Previewing 3 rows."
- pause: 1.2
- click: ".table-create-save"
- wait_for_url: "**/demo/launch_metrics"
- wait_for: "text=Activation rate"
- pause: 1.2video 命令文档中包含了更简单的示例,但出于本文的目的,我想不妨采用一个更全面的示例。
那个用于演示的 YAML storyboard 完全是由在 Codex Desktop 中运行的 GPT-5.5 xhigh 构建的,使用的是在我的 ~/dev/datasette 该分支检出目录下运行的以下提示词:
审查此分支上的更改。 cd 到 ~/dev/shot-scraper 并运行命令 "uv run shot-scraper video --help" 现在使用那个新的 video 命令,录制此分支中新功能的视频演示,包括运行 "uv run datasette -p 6419 --root --secret 1 /tmp/demo.db" 开发服务器,以便您可以针对您首先创建的演示数据库录制视频。
既然我已经发布了该功能,现在的提示词可以改为“运行 uvx shot-scraper video --help”,并且应该能达到相同的效果。
我非常喜欢这种模式:命令的 --help 输出提供了足够详细的细节,使得编程智能体可以直接使用它——这有点像在工具内部直接捆绑了一个 SKILL.md 文件。我在 showboat 和 rodney 中也使用了相同的模式。
我是如何构建它的
shot-scraper video 最初是一个实验性原型。shot-scraper 是基于 Playwright 构建的,而它需要的一个关键特性是,Playwright 必须能够记录浏览器会话的视频,并提供足够的控制力来创建所需的演示。
我在几年前第一次尝试这个时,发现 Playwright 生成的视频包含了额外的浏览器外壳界面(chrome),这对于调试测试失败很有用,但对于产品演示来说是不需要的。
他们在一段时间前修复了这个问题,但仍然存在一些小障碍。特别是,我在视频开头会得到几帧白屏,因为录制机制在浏览器加载第一个 URL 之前就启动了。
Playwright 1.59 添加了一种新的屏幕录制机制,为视频录制提供了更精细的控制。这几乎正是我所需要的,但生成的视频宽度被固定在了 800px。
我找到了一个已合并的 PR 修复了这个问题,但它还没有发布。然后昨天他们在 playwright-python 1.61.0 中发布了它,我终于扫清了障碍,可以完成该功能的实现了!
代码本身完全是由 Codex Desktop 中的 GPT-5.5 xhigh 编写的。我还让它编写了文档,这为我在审查设计时提供了一个非常有用的框架——该功能的许多迭代都来自于对该文档的审查,发现冗余、不一致或令人困惑的地方,并要求(或指定)一个更好的设计。
YAML 格式本身主要由编程智能体定义。我让它使用 Pydantic 来定义和验证该格式,部分原因是为了让设计更容易审查。
这是一个绝佳的例子,如果没有编程智能体的辅助,我几乎肯定不会着手去开发这类功能。我在 2024 年 2 月就提交了最初的 issue,但在我的其他所有项目之间,我一直很难抽出必要的时间来解决这个问题。
需要完整排版与评论请前往来源站点阅读。