screenshot-to-code 如何为 screenshot_preview 工具接入自定义渲染后端?
2026/9/9 22:46:18 网站建设 项目流程

screenshot-to-code 如何为 screenshot_preview 工具接入自定义渲染后端?

【免费下载链接】screenshot-to-codeDrop in a screenshot and convert it to clean code (HTML/Tailwind/React/Vue)项目地址: https://gitcode.com/GitHub_Trending/sc/screenshot-to-code

screenshot-to-code 的 agent 有一个screenshot_preview工具:它把当前生成的 HTML 渲染成桌面端和移动端的整页截图,让模型"看到"自己写的页面来验证效果。默认渲染走本地无头 Chromium(Playwright 驱动)。如果你的部署环境跑不了本地浏览器,或者想把渲染统一交给自己的渲染服务(文档注释中给出的示例场景就是"an external rendering API"),你不需要改screenshot_preview工具本身——项目把它设计成了一个可插拔接口,实现ScreenshotBackend并在启动探测之前注册即可。

这篇文章基于 backend/preview_screenshot/ 模块的真实代码,给出实现、注册和验证的完整路径。

先看清调用链:工具只对接一个接口

整条链路是单向的:

  1. 工具执行入口 run_screenshot_preview 遍历("desktop", "mobile")两个视口,对每个视口调用capture_preview_screenshot(html, device=viewport, full_page=True)
  2. registry.py 中的capture_preview_screenshot先对 HTML 做 Babel CDN 归一化(normalize_babel_cdn,保证生成的 React 页面真正挂载后再截图),然后转交给当前激活的后端
  3. 后端的选择对调用方完全不可见。main.py 在启动时运行probe_screenshot_preview_on_startup(),调用probe_screenshot_preview()探测后端是否可用。

preview_screenshot/__init__.py对外导出七个名称:ScreenshotBackendVIEWPORT_SIZESPlaywrightBackendcapture_preview_screenshotis_screenshot_preview_availableprobe_screenshot_previewset_screenshot_backend。接入自定义后端你只需要用到前者和set_screenshot_backend

接口定义:两个方法、两种视口

接口定义在 base.py,是一个typing.Protocol

class ScreenshotBackend(Protocol): async def capture(self, html: str, device: str, full_page: bool) -> bytes: """Render ``html`` to PNG bytes at the given device viewport.""" ... async def available(self) -> bool: """Whether this backend can run here (warming it up if needed).""" ...

两个方法的职责:

  • capture(html, device, full_page) -> bytes:把 HTML 渲染成 PNG 字节返回。device只会是"desktop""mobile",对应共享视口常量VIEWPORT_SIZES

    device视口尺寸(宽 × 高,像素)
    desktop1280 × 832
    mobile342 × 684
  • available() -> bool:探测当前环境能否渲染,必要时顺手预热(warm up)。这个结果会被启动探测缓存一次,并用于决定是否向模型暴露该工具——registry 中的注释原文是 "Used to gate the tool so it isn't offered when it can't"。

默认实现 PlaywrightBackend 的关键参数可供参考:页面加载超时PAGE_LOAD_TIMEOUT_MS = 15000、渲染稳定等待RENDER_SETTLE_MS = 250,截图固定type="png"。它的 docstring 同时解释了为什么默认要本地渲染:本地页面可以加载来自 localhost 的资源(例如/local-assets/这类 URL),而外部截图 API 是够不到的——如果你的生成页面依赖本地资产 URL,切换外部渲染前先确认这一点。

实现你的自定义后端

接口没有规定实现方式,下面是一个针对"外部渲染服务"的骨架示例。其中对渲染服务的实际请求由你的服务接口决定,示例中标注了需要替换的位置:

class ExternalRenderBackend: """示例骨架:把 HTML 交给外部渲染服务,取回 PNG 字节。 实际 HTTP 请求细节按你的渲染服务接口自行实现; 返回值必须是 PNG 字节(bytes)。 """ async def available(self) -> bool: # 检查渲染服务是否可用(例如做一次健康检查); # 也可以在这里完成预热。返回 False 时工具将不会暴露给模型。 return True async def capture(self, html: str, device: str, full_page: bool) -> bytes: # 将 html 连同 device / full_page 参数发给你的渲染服务, # 返回渲染结果的 PNG 字节 raise NotImplementedError("替换为对渲染服务的真实调用")

两点来自源文档的约束:

  • device只有"desktop""mobile"两个取值,full_page在工具调用链中固定为True,你的实现只需覆盖这两个组合;
  • 传给capturehtml已经被normalize_babel_cdn处理过,后端拿到的是可直接挂载的页面,不要重复做 CDN 归一化。

注册后端:只调用一次,且在启动探测之前

替换动作只有一行,入口在 registry.py:

from preview_screenshot import set_screenshot_backend set_screenshot_backend(ExternalRenderBackend())

registry 的 docstring 对调用时机有明确要求:"Install the screenshot backend (call once, before the startup probe)"——只安装一次,且必须发生在启动探测之前。对照 main.py:服务启动时会执行probe_screenshot_preview_on_startup(),它调用probe_screenshot_preview()对当前后端做一次探测并缓存结果。所以自定义后端的安装必须排在这个启动探测运行之前,否则被探测、被缓存下来的仍是默认PlaywrightBackend

理解探测的缓存行为对验证很有用:

  • probe_screenshot_preview()只在第一次调用时执行available(),之后直接返回缓存值;
  • is_screenshot_preview_available()在探测尚未运行时默认返回True(避免启动检查完成前误隐藏工具),探测完成后返回缓存结果。

也就是说available()的结果在整个进程生命周期内只算一次,你的实现要能如实反映"此刻能否渲染",而不是临时状态。

验证接入是否生效

文档给出的验证依据集中在探测结果对工具的 gating 上,可按以下顺序确认:

  1. 看探测日志。默认后端的available()会打印明确的状态行(以下均为源码中的日志原文,此处作为文档示例展示):
    • 可用:[screenshot_preview] Chromium available — tool enabled.
    • 不可用:[screenshot_preview] Chromium unavailable — tool disabled. Install it withplaywright install chromium. Cause: {exc}换成自定义后端后,建议在自己的available()里打印同样清晰的状态行,方便在启动日志中确认被调用的是你的实现。
  2. 确认工具暴露。探测失败(available()返回False)时,screenshot_preview不会提供给模型——反过来,你的后端返回True后,模型在生成流程中可以正常调用该工具。
  3. 跑一次真实生成。工具成功时的行为在 screenshot_preview.py 中有明确描述:对当前 HTML 输出桌面端和移动端两张整页 PNG(preview_desktop.pngpreview_mobile.png),作为多模态图片附给模型查看。这些预览只用于模型验证工作结果,不会作为资产持久化,UI 仅内联 data URL 展示缩略图。如果你想核对图片确实来自你的后端,可以在capture()中记录收到的device/full_page参数或返回的字节长度(工具结果image_bytes字段会透出大小)。

相关消费点可以顺带查看:backend/routes/capabilities.py 引用了 screenshot preview 的可用状态;工具行为测试见 backend/tests/test_agent_tools.py。

限制与边界

  • 一次安装、一次探测。set_screenshot_backend与启动探测都只生效一次,不支持运行中热切换后端;探测缓存意味着服务中途不可用不会被自动感知,只能靠调用时的容错(工具侧会把渲染异常包装成Screenshot failed错误返回)。
  • 本地资源可达性。如前所述,PlaywrightBackend的默认理由之一就是能访问 localhost 资产;外部渲染服务天然够不到这类 URL,切换前确认你的页面不依赖它们。
  • 不切换时的默认依赖。若仍用默认后端,Chromium 缺失时按文档日志提示安装:playwright install chromium

完成上述接入后,可核对的最终结果是:启动日志显示你的后端通过了available()探测,screenshot_preview工具对模型可见,且一次生成流程中返回的桌面/移动端预览 PNG 出自你的渲染服务。

【免费下载链接】screenshot-to-codeDrop in a screenshot and convert it to clean code (HTML/Tailwind/React/Vue)项目地址: https://gitcode.com/GitHub_Trending/sc/screenshot-to-code

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询