讓你的 Agent 用 shot-scraper video 錄製工作成果的影片展示
原文由 Simon Willison 于 發布,訂閱此部落格
shot-scraper video 是今天釋出的 shot-scraper 1.10 中新增的指令,它會讀取一個定義了要在網頁應用程式上執行流程的 storyboard.yml 檔,並透過 Playwright 將整個流程錄製成影片。我之前寫過讓 Coding Agent 為自己的成果產出展示的重要性;這則是我為了讓它們做到這件事的最新嘗試。
以下是一段使用 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 副本中、於這個分支上執行的以下提示:
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 輸出本身就提供足夠詳細的資訊,讓 Coding Agent 能直接使用——有點像把 SKILL.md 檔直接打包進工具裡。我在 showboat 和 rodney 也用了同樣的模式。
我是怎麼做出這個功能的
shot-scraper video 一開始只是一個實驗性的原型。shot-scraper 是建構在 Playwright 之上的,而它需要的關鍵功能,是讓 Playwright 能夠以足夠精細的控制來錄製瀏覽器操作過程,以產出符合需求的展示影片。
我幾年前就試過一次,當時發現 Playwright 產出的影片會包含額外的瀏覽器外框,對於除錯測試失敗很有用,但作為產品展示就不適合了。
這個問題後來已經被修掉了,但仍有一些小障礙。特別是影片開頭會出現幾幀白畫面,因為錄製機制在瀏覽器載入第一個網址之前就已經啟動了。
Playwright 1.59 新增了screencast 機制,對影片錄製提供了更細緻的控制。這幾乎就是我需要的功能,但產出的影片寬度被固定在 800px。
我找到一個已經合併、修復這個問題的 PR,但當時還沒釋出。直到昨天,他們在 playwright-python 1.61.0 中釋出了這個修正,我才終於能掃除阻礙、完成這個功能!
程式碼本身完全是由在 Codex Desktop 上執行的 GPT-5.5 xhigh 所撰寫。我也讓它撰寫了文件,這為審視設計提供了非常有用的框架——這個功能的許多反覆調整,都是來自檢視那份文件,發現其中冗餘、不一致或令人困惑的地方,再要求(或直接指示)它提出更好的設計。
YAML 格式本身大多也是由 Coding Agent 定義的。我讓它使用 Pydantic 來定義並驗證格式,部分原因是這樣更容易審視設計。
這是一個很好的例子,說明如果沒有 Coding Agent 的協助,我幾乎可以肯定不會去著手開發這類功能。我在 2024 年 2 月就提出了最初的 issue,但在眾多其他專案之中,一直很難抽出時間來解決它。
隨機一篇部落格
留言
登入後參與討論