关于 visual-feedback-loop
Visual Feedback Loop 是用于开发迭代的网页应用视觉检查技能,通过服务器和浏览器协作捕获页面截图。它还可保存截图元数据,并用像素差异比较不同代码状态的渲染结果。
主要功能
- 01通过浏览器捕获页面截图
- 02保存带时间戳的截图和元数据
- 03使用像素差异比较截图
- 04记录代码提交与页面参数
- 05通过 SSE 协调截图请求
适用场景
- 01检查网页应用当前渲染
- 02比较代码修改前后的页面
- 03追踪截图对应的代码状态
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ vladmdgolam/ agent-skills --skill visual-feedback-loop安装后在 Claude Code 中输入/visual-feedback-loop确认已加载。
附带文件references/errors.mdreferences/setup-nextjs.md
详细介绍
视觉反馈循环
在迭代开发期间,捕获、检查并比较运行中的 Web 应用的视觉输出。
工作原理
Agent (CLI) Server Browser
|--- GET /api/dev-screenshot -->|--- SSE "capture" ----------->|
| ?param=value | |-- capture canvas
| |<-- POST { dataUrl } ---------|
| | writes:
| | .screenshots/{UTC}.webp
| | .screenshots/{UTC}.json (metadata)
| | .screenshots/latest.webp (convenience copy)
|<-- { ok, path, latest } ------|
Agent 无法直接访问浏览器。服务端负责中继:GET 触发请求 → SSE 通知浏览器 → 浏览器捕获并 POST 回传 → GET 返回结果。
用法
捕获当前视图:
curl http://localhost:3000/api/dev-screenshot
带参数捕获(因应用而异,浏览器客户端会解析这些参数):
curl 'http://localhost:3000/api/dev-screenshot?component=header&theme=dark'
curl 'http://localhost:3000/api/dev-screenshot?letter=б&depth=0.8'
然后读取结果。响应包含 path(带时间戳的文件)和 latest(便捷副本):
Read .screenshots/latest.webp
视觉回归(像素差异)
使用 ImageMagick 与基准截图进行比较:
magick compare -metric RMSE .screenshots/ground-truth.webp .screenshots/latest.webp .screenshots/diff.webp
RMSE 输出:0.01 = 差异约为 1%(渲染噪声),0.03+ = 可见变化。保存差异图像以供检查。
元数据 Sidecar
每张截图都会生成一个带有相同 UTC 时间戳的 JSON Sidecar:
{
"timestamp": "2026-02-25T08:22:12.655Z",
"git": { "commit": "0a5726f", "dirty": true },
"params": { "letter": "о", "chamferModel": "membrane", "cameraView": "front" },
"format": "webp",
"file": "2026-02-25T08-22-12-655Z.webp"
}
使用它追踪生成截图时对应的代码状态和参数——在多次代码更改间迭代时至关重要。
A/B 比较工作流
- 捕获基准截图:
curl '...?letter=о'→ 记下{UTC}.webp文件名 - 修改代码,刷新浏览器
- 再次捕获:
curl '...?letter=о' - 进行差异比较:
magick compare -metric RMSE .screenshots/{ground-truth}.webp .screenshots/latest.webp .screenshots/diff.webp - 读取差异图像并检查 RMSE 值
控制台备用方案:await window.__takeDevScreenshot()
规则
- 每次捕获后都要
Read .screenshots/latest.webp。 切勿假定渲染结果正确。 - 应用 URL 对应的浏览器标签页必须处于打开状态。 超时 = 没有 SSE 连接 = 请用户刷新。
- 一次只处理一个请求。 第二个 GET 会返回 409。等待第一个请求返回(成功/错误/10 秒超时)。
- 错误会立即返回,不会以超时的形式返回。客户端会 POST 错误信息:
{ ok: false, error: "..." }。 - HMR 弹性。 将服务端 SSE 状态存储在
globalThis上,使其在模块重新加载后仍然有效。EventSource 会在客户端自动重新连接。如果代码更改后截图仍然失败,请用户刷新。 - HMR 不会更新屏幕外渲染路径。
useEffect中的闭包会捕获过时的模块引用。更改渲染逻辑后,务必请用户强制刷新(macOS 上按 Cmd+Shift+R,Windows/Linux 上按 Ctrl+Shift+R)。
故障排除
| 现象 | 修复方法 |
|---|---|
| 超时:浏览器未响应 | 在浏览器中打开/刷新应用 |
| 409:已有请求正在处理中 | 等待超时(10 秒) |
| 黑屏/空白图像 | 刷新浏览器标签页 |
| 首次正常,之后超时 | HMR 破坏了 SSE——刷新标签页(使用 globalThis 模式时很少发生) |
| 截图未反映代码更改 | HMR 不会更新屏幕外渲染器——强制刷新(macOS 上按 Cmd+Shift+R,Windows/Linux 上按 Ctrl+Shift+R) |
| 比较不同代码状态下的截图 | 检查 JSON Sidecar 中的 git 提交和 dirty 标记 |
完整错误参考请参阅 references/errors.md。
设置
此模式与框架无关——只需要支持 GET/POST 路由和 SSE 的 HTTP 服务。参考实现使用 Next.js,但同样的方法也适用于 Express、Fastify、Hono、Vite 开发服务插件或任何 Node.js HTTP 服务。
完整的 Next.js 实现(API 路由、SSE 监听器、WebMCP 注册)请参阅 references/setup-nextjs.md。根据所用框架调整路由处理程序——无论服务端使用何种框架,客户端的 SSE 监听器和捕获逻辑都相同。