Have your agent record video demos of its work with shot-scraper video

Simon Willison

让你的智能体用 shot-scraper video 录制工作演示视频

原文由 Simon Willison 发布,订阅该博客

shot-scraper video 是今天发布的 shot-scraper 1.10 版本中新增的命令,它接受一个定义了针对 Web 应用执行流程的 storyboard.yml 文件,并使用 Playwright 来录制该流程的视频。我此前写过让编程智能体为自己的工作产出演示的重要性;这是我为实现这一目标的最新尝试。

下面是一段使用 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.2

video 命令的文档中包含了更简单的示例,但就本文而言,我想展示一个更完整的例子。

这个演示用的 YAML 故事板完全由运行在 Codex Desktop 上的 GPT-5.5 xhigh 构建,所使用的提示词是在我的 ~/dev/datasette 目录下检出的这个分支中运行的:

Review the changes on this branch.

cd to ~/dev/shot-scraper and run the command "uv run shot-scraper video --help"

Now use that new video command to record a video demo of the new features from this branch, including running a "uv run datasette -p 6419 --root --secret 1 /tmp/demo.db" development server so you can record the video against a demo DB that you first create.

现在该功能已经发布,提示词也可以改成“run uvx shot-scraper video --help”,效果应该是一样的。

我很喜欢这种模式:命令的 --help 输出提供了足够详细的信息,让编程智能体可以直接使用——这有点像把 SKILL.md 文件直接打包进了工具本身。我在showboat 和 rodney 中也用了同样的模式。

我是如何构建它的

shot-scraper video 最初只是一个实验性原型。shot-scraper 基于 Playwright 构建,它所需的关键能力是让 Playwright 能够以足够精细的控制来录制浏览器会话,从而制作出符合预期的演示视频。

几年前我第一次尝试时发现,Playwright 生成的视频中包含了额外的浏览器界面元素,这对调试测试失败很有用,但对于产品演示来说却是不必要的。

这个问题在一段时间前已经修复了,但仍有一些小障碍。特别是,我发现在视频开头会出现几帧白屏,因为录制机制在浏览器加载第一个 URL 之前就已经启动了。

Playwright 1.59 新增了一个截屏录制(screencast)机制,对视频录制提供了更精细的控制。这已经非常接近我的需求了,但生成视频的宽度被固定在了 800 像素。

我找到了一个已经合并、修复了该问题的 PR,但它还没有随版本发布。直到昨天,他们在 playwright-python 1.61.0 中发布了这一修复,我才终于得以完成这个功能的实现!

代码本身全部由 Codex Desktop 中的 GPT-5.5 xhigh 编写。我还让它编写了文档,这为我审视设计提供了一个非常有用的视角——该功能的许多迭代正是来自于对文档的审阅,发现其中冗余、不一致或令人困惑的地方,并据此要求(或直接指定)更优的设计。

YAML 格式本身也主要由编程智能体定义。我让它使用 Pydantic 来定义和校验该格式,部分原因是为了让设计更易于审阅。

这是一个很好的例子,说明如果没有编程智能体的帮助,我几乎肯定不会去着手做这类功能。我在 2024 年 2 月提交了最初的 issue,但在众多项目之中一直难以抽出时间来解决它。

本文章由 muse-spark-1.2-contributor 进行翻译

评论