Vercel Labs 开源 fx0:超快的 HTML 工件构建器

fx0 主打快速生成与局部修改:高速模型、紧凑 HTML、精确替换和流式预览怎样配合?附三个真实可玩案例与完整提示词。

作者:Vercel Labs10-21 · 约 10 分钟

Vercel Labs 开源了一个叫 fx0 的网页设计 Agent,主打快速生成、快速修改:你描述想做的页面,它就写出一份可以在浏览器直接运行的单文件 HTML,让想法尽快变成能操作的首稿。

它同时是底层 Agent 库 libfx 的应用示例,用来展示这套运行机制的速度与持久性。主要特点包括:

  • 尽快出首稿,局部修改少重写。 默认使用高速模型,并要求 Agent 减少步骤,简单改色、改文案时直接修改对应代码。
  • 生成时就能先看预览。 HTML 还没全部写完,页面结构与样式就可以陆续出现;完整提交后再运行交互脚本。
  • 带着风格和参考继续做。 支持十种预设或自上传 design.md,也能搜索、抓取参考网页,在制作途中补充文字要求。
  • 一个文件交付,逐轮保留版本。 HTML 可以复制、下载,旧版也能重新打开;执行中的步骤会保存,处理中断后可以接续。

快在哪里,又是怎样实现的?

fx0 把速度放进了模型选择、生成步骤、修改方式和预览过程。首稿少生成一些不必要的内容,微调少重写一些已有代码,用户也能更早看见画面。本次没有做端到端计时或同条件产品对照,能核对的是这些具体设计。

首稿:高速模型、少步骤、紧凑文件

默认模型是 claude-opus-5.5-fast。访客试用固定使用 low effort(低思考强度)与 Fast 模式;登录后的聊天可以分别选择模型、推理强度和 Fast 设置。

系统指令也在减少等待:需求已经明确时,Agent 选择合理默认值直接开做;修改颜色或文案时,思考量要与改动规模相称;同一个请求里的多处修改,应合在一次工具调用里完成。

首次制作页面,指令要求用一次 publish_design 提交完整 HTML,正常首稿尽量控制在 12 KiB 以内。设计 Agent 没有文件系统、shell 或部署环境;它直接交付 HTML,不需要先搭一个多文件工程、安装依赖再构建,产物本身就能由浏览器打开。代码写得紧凑,也就少了一部分需要模型生成的文本。

本次 ORBIT / FORM 原件为 10,854 字节,约 10.6 KiB;CHROMA FLOW 原件为 9,028 字节,约 8.8 KiB。这两个数是文件大小,不是生成用时。12 KiB 是给模型的首稿建议,最终验证器执行的体积硬上限则是 512 KiB。

修改:只传需要替换的片段

如果要把 FORM 海报的大字换成蓝色,同时把随机按钮改名为“SHUFFLE POSTER”,系统指令要求优先调用 edit_design,传入对应的旧文本与新文本,而不是重新输出整份 HTML。已知要改哪段时,也不必先把全文再读一遍。

一次调用可带 1–20 项精确替换:每段旧文本都必须唯一匹配,按顺序应用后,一起校验并提交成一个新版本;其中一项失败,整批不会成为新版本。这样既能把同一轮要求一起落实,也减少了模型反复输出已有代码和来回调用工具的次数。

操作 交给工具的内容 提交结果
首稿或整体重做 publish_design 接收完整 HTML 校验后生成完整设计
局部修改 edit_design 接收旧文本、新文本的替换数组 整批修改提交为一个版本

预览:代码还在写,页面先出现

模型调用 publish_design 时,HTML 放在工具参数的 html 字段里。fx0 的传输层会观察模型返回的 tool-input-delta 事件,逐段解码这个字段,把已经收到的 HTML 经 Redis 频道推到浏览器。它不用等工具参数全部传完,才开始显示页面。

未完成的代码不能直接当成品运行。前端会先移除脚本、事件属性、嵌套页面和外部资源,并用 script-src 'none' 禁止执行脚本。所以生成途中能先看文字、布局与样式,Canvas 动画和按钮交互要等完整提交后再运行。

预览更新也不是每收到一段代码就重建整页。draft-preview.ts 会比较并修补已有 DOM,保留未变的节点和滚动位置;最终 HTML 校验完成后,才切换到可执行 JavaScript 的沙箱。

这里同时改善了两种等待:少生成、少重写,是减少完成任务所需的工作;流式预览则让用户更早看见进度,不能把两者都当作总耗时的缩短。正常提示词还会由接收请求的函数直接开始执行,不先经过一次队列投递;请求模型前,读取计费身份、准备草稿观察器和预留本轮步数也会并行进行。Vercel Queues 负责后备接管、长任务接续,以及运行中引导等跨请求工作。

两次输入,做出三个可玩的场景

这次直接在 fx0 线上服务 使用访客试用:第一轮生成 ORBIT / FORM 双展厅,第二轮生成 CHROMA FLOW 粒子画布。界面显示的模型为 claude-opus-5.5,每轮只发送一次,未追加模型追问。

主视觉、画布算法和控件来自 fx0。文章里的演示是展示适配副本:修正了海报文字出界、轨道显示比例、部分触控尺寸和“减少动态”设置。未经修改的 HTML 原件也保留下来,可以在每个案例旁下载。

01 ORBIT:把网页变成轨道控制台

深黑星空、青色轨道、橙色太阳,再加上任务读数,组成一个太空控制台。点击 EARTH、MARS 或 SATURN,选中行星及其轨道会高亮,左侧的任务、目标半径、公转周期等读数同步变化。三条轨道和土星环本来就在画面里,切换改变的是强调对象。

可以拖动时间倍率滑块,在 0.1× 到 5.0× 之间以 0.1 为步长调节运动速度;点 PAUSE 暂停,按钮随之变成 RESUME。这是艺术化模拟,轨道比例、运动和遥测读数不能当作科学计算。

实跑案例 01

ORBIT 轨道任务控制台

操作观察:可在画面底部切换 EARTH、MARS、SATURN 任务(联动切换轨道高亮与模拟读数),或拖动时间流速滑块。默认为静态截图,点击“启动可玩演示”按需挂载沙箱。

ORBIT 轨道控制台界面截图

02 FORM:拖动滑块,重排一张动态海报

同一份 HTML 切到 FORM,画风换成了暖白底、黑橙大字和密集波纹。“MAKE SOME NOISE”三个单词压在波浪线条上,画面本身就是可调整的海报。

拉高波浪频率,线条起伏更密;改变密度,画面里的线条数量随之变化。橙、黑、蓝、红四种墨水可以直接切换。点击 RANDOMIZE COMPOSITION,会重新组合频率、密度、颜色、相位和文字偏移。

原件的随机偏移有时会把首字母挤出画面,展示副本限制了偏移并调整字号。这也说明,生成出一个有风格的页面之后,仍要亲自试试控件的极端状态。

实跑案例 02

FORM 动态字体海报工作室

操作观察:与案例 01 产自同一次生成。拖动波浪频率、密度滑块,切换橙/黑/蓝/红 4 种墨水,或点击“RANDOMIZE COMPOSITION”重新随机版面。适配版限定了文字偏移边界,保证小屏不裁切字母。

FORM 动态字体海报界面截图

ORBIT 和 FORM 来自同一次生成。第一轮提示词同时说明了两个场景的视觉方向、具体控件,以及“操作必须改变画面”的要求。

第一轮完整提示词:英文原件与中文译文,任选一种发送

英文为本次实际发送的原件;中文为对应译文。

Create a spectacular interactive exhibition called ORBIT / FORM with TWO distinct full-screen exhibits accessible through clear persistent tabs and URL hashes #orbit and #form. Exhibit 1 ORBIT: a cinematic orbital mission-control scene, near-black space, glowing cyan orbital trajectories and a vivid orange sun rendered with Canvas/SVG/CSS (no external assets). Hundreds of subtle animated stars, planet orbit paths, small telemetry panels with clearly labelled SIMULATED data. Visitors can pause/resume motion, adjust time speed, and switch between Earth/Mars/Saturn missions; selection must visibly change orbit and readouts. Exhibit 2 FORM: a completely different Swiss editorial generative kinetic typography poster studio, warm ivory background, huge black/orange type saying MAKE SOME NOISE, sculptural parametric ribbon or moire geometry, controls for wave frequency, density and ink color, plus a randomize composition button; all controls must change the live artwork. Polished art direction, intentional typography, no generic SaaS cards. Both scenes need distinct strong composition, responsive layout that works on a 390px phone, keyboard-accessible real controls, prefers-reduced-motion support, and a small plain-language instruction visible on each scene. All content and code in one self-contained HTML, no CDN, no external network requests, no mock buttons. This is a design exploration: use only fictional/simulated data, no real account or backend. Make it beautiful and publish the finished design.
创建一个名为 ORBIT / FORM 的精彩交互式展览,包含两个完全独立的全屏展厅,通过清晰的常驻标签页和 URL 哈希(#orbit 与 #form)进行访问。展厅 1 ORBIT:电影级的轨道任务控制中心场景,近乎纯黑的太空背景,使用 Canvas/SVG/CSS 渲染出发光青色轨道轨迹与明亮的橙色太阳(无外部资源)。数百颗微妙闪烁的动态恒星、行星运行轨道,以及带有明确“SIMULATED(模拟)”标注的遥测数据面板。访客可以暂停/恢复运动、调节时间流速,并在地球/火星/土星任务之间切换;切换选项必须能够直观改变轨道高亮与读数。展厅 2 FORM:完全不同的瑞士平面设计流派动态字体海报工作室,暖象牙白背景,巨大的黑橙双色大字呈现“MAKE SOME NOISE”,雕塑般的参数化飘带或莫尔几何波纹,提供波浪频率、线条密度和墨水颜色的控制项,以及一个随机版面按钮;所有控件必须能实时改变画面。要求考究的艺术指导与排版意图,不要通用的 SaaS 卡片。两个场景都需要鲜明的构图、能在 390px 手机上自适应的响应式布局、支持键盘访问的真实控件、支持系统偏好减少动态(prefers-reduced-motion),并在每个场景中显示简短易懂的文字说明。全部内容和代码整合在一个完全自包含的单文件 HTML 中,不使用 CDN,不发出外部网络请求,不包含无效假按钮。这是一次设计探索:仅使用虚构/模拟数据,无需真实账号或后端。请打造出优雅视觉并发布最终设计。

03 CHROMA FLOW:用鼠标搅动一片发光粒子

第二轮换成一件暗色的生成艺术作品:品红、青色和荧光黄绿的光点,在黑色画布上形成光带或线网。鼠标移入、拖动或触碰画布,会扰动图形。

三个模式的区别可以直接看出来:

  • VORTEX(漩涡):粒子围绕三个移动中心流动,留下拖尾;指针进入后增加一个旋转扰动中心。
  • WAVES(波阵):一行行曲线叠加正弦起伏,指针附近出现扩散、衰减的波纹。
  • CONSTELLATION(星群):点缓慢移动,距离足够近的点之间画线,形成不断变化的网络。

TURBULENCE 调节扰动强度,FREEZE / RESUME 冻结或恢复画面,RESEED 重新生成初始分布。也能用左右方向键换模式、空格键暂停。它是生成艺术,没有求解真实的流体物理方程。

原件在系统开启“减少动态”时仍会持续运行,只减慢时间参数、调低初始扰动。展示副本改成默认显示静止星群,用户需要时再手动恢复动画。

实跑案例 03

CHROMA FLOW 粒子艺术仪

操作观察:第二轮生成产物。底部可切换 01 Vortex(三中心旋涡带)、02 Waves(多层正弦波干涉)、03 Constellation(邻近动态连线星网);画面支持光标拖拽扰动,可调节湍流滑块或按空格定格。

CHROMA FLOW 粒子艺术仪界面截图
第二轮完整提示词:英文原件与中文译文,任选一种发送

英文为本次实际发送的原件;中文为对应译文。

Build CHROMA FLOW, an extraordinary interactive liquid-light instrument, as one complete self-contained HTML file. Make it look like a physical creative instrument / experimental museum exhibit: almost-black background, enormous vivid magenta/cyan/acid-lime luminous flowing particle ribbons or fluid-like interference field on Canvas, editorial condensed CHROMA FLOW headline, delicate numbered scales, small generous controls. The artwork must fill most of the page and react to pointer/touch movement with attractive ripples or swirls. Provide three visually very different working modes (VORTEX, WAVES, CONSTELLATION), a turbulence/intensity slider, a real freeze/resume toggle, and an actual reset/reseed button. Each mode should change the algorithm/composition, not only color. Keep readable visible instructions and mode description, do not overclaim physical fluid simulation; label it generative art. Ensure attractive initial composition without interaction. No external assets, libraries, fonts, CDN or network. Use Canvas and inline JS/CSS only. Make it responsive at 390px width and large desktop with all controls readable, no clipped headline or overlapping instructions, min 44px touch targets, keyboard-accessible controls and prefers-reduced-motion support. Respect safe particle counts for mobile. Strong composition, bold visual identity, no SaaS cards. This is fictional artwork, no backend. Publish the completed design.
构建一个名为 CHROMA FLOW 的非凡交互式液体光影艺术仪,输出为一个完全自包含的单文件 HTML。将其打造成类似实体创意乐器或实验博物馆展品的外观:近乎纯黑的背景,Canvas 上呈现出巨大且鲜艳的品红/青色/亮酸橙色发光流体粒子光带或干涉场,搭配排版紧凑的 CHROMA FLOW 大标题、精致的数字刻度尺与小巧克制的控件。艺术画面必须占据页面主体,并对指针/触控移动产生引人入胜的涟漪或旋涡响应。提供三种视觉差异显著的运行模式(VORTEX 涡流、WAVES 波阵、CONSTELLATION 星座)、一个湍流/强度滑块、一个真实的定格/恢复开关,以及一个真实的重置/重新播种按钮。每种模式都应改变底层的生成算法和构图,而不仅仅是改变颜色。保持清晰可见的说明文字和模式描述,不要夸大声称为真实的物理流体模拟,应标注为生成艺术。确保即使无交互时也具备赏心悦目的初始构图。不使用任何外部资源、库、字体、CDN 或网络请求。仅使用 Canvas 以及内联的 JS/CSS。适配 390px 手机屏与大屏桌面端,所有控件保持清晰可读,标题不被截断,说明不发生重叠,触控目标最小 44px,支持键盘访问控件并适配偏好减少动态设置。在移动端遵循安全粒子数量限制。强调构图与大胆的视觉识别度,不使用 SaaS 模版卡片。这是虚构的艺术作品,无需后端支持。请发布完整设计。

怎样复现,并把网页带走?

  1. 打开 fx0,在输入框粘贴一轮完整提示词,中文译文和英文原件任选一种。
  2. 发送后等待预览完成,测试任务切换、滑块和随机按钮,确认画面确实响应。
  3. 从顶部菜单选择 copy HTML 或 download HTML,保存单文件。打开下载后的 HTML 就能在本地浏览器查看,无需先部署完整 fx0 服务,也无需使用 publish with Drop。
  4. 想继续调整,可以在同一会话提出具体修改,例如只调整颜色或控件位置。fx0 的局部修改工具会在现有文档上做文本替换;每轮设计都有自己的版本,能重新打开并导出。

生成具有随机性,同一提示词不保证得到同样的构图。本次两个完整输入是供复现和改造的起点。

仓库可选开启的访客试用功能是每个 IP 共五次输入,没有周期补充;本次进入时只显示剩余两次,用完后提示登录。这个剩余数不是新用户的默认额度。登录后,模型调用通过 AI Gateway 计入用户自己的 Vercel 团队,费用随所选模型和用量变化。

模型设置、运行中引导和版本记录,让后续调整有了更细的控制。

模型、推理强度与 Fast 分别可选。 简单改色与复杂逻辑不必使用同样的思考设置,可以按任务调整。Fast 是速度选项,不表示免费;实际费用仍随模型和使用量变化。

生成途中可以补方向。 在付费纯文字对话中,Agent 还在工作时就能追发补充要求,例如“保留构图,只调整颜色”。libfx 会在当前工具结束后把引导交给模型,不必总等整轮结束再提要求。含图片的消息会作为下一轮处理,免费试用中的每次输入也各自成为一轮。

每轮版本都能取回。 可以从对应轮次的版本入口重新打开旧设计,对比改动,再复制或下载那一版 HTML。比如一轮调色不理想,旧版文件仍然可取,不用靠记忆重新描述原来的样子。

一个 HTML,为什么能做出动画?

以 FORM 海报为例,一份 HTML 里同时放了三部分:页面结构提供滑块和按钮,CSS 决定颜色、字号与位置,JavaScript 接收操作并重新画图。

当你把密度滑块从 44 调到 80,脚本读到新数值,画布在下一次重绘时就画出更多线条;选择蓝色,则改变画线时使用的颜色。持续动画会通过浏览器的 requestAnimationFrame 逐帧更新角度、粒子坐标或波纹相位。模型负责写代码,打开成品后的操作和绘图由浏览器执行,不需要每拖一次滑块就再问模型。

本次三个场景都只用了浏览器原生能力。fx0 的约束并不是“禁止某个前端框架”,而是要求交付一个完整、自包含的文件:CSS 和脚本内联,图片等素材也要嵌入文件,不能从外部 CDN 加载资源。

从请求到成品,Agent 怎样工作?

网页里的滑块由浏览器执行,写出这些代码的过程则由后台 Agent 负责。具体调用链是:

  1. 前端向 Next.js 的 POST /api/prompt 发送需求;fx0 保存消息,并记录这一轮使用的试用或付费身份。
  2. libfx 会话通过 AI Gateway 请求模型,把模型回复中的工具调用交给 fx0 执行,得到结果后继续这一轮任务。
  3. 首稿由 publish_design 交完整 HTML,局部修改由 edit_design 交精确替换。完整产物进入验证器,检查文档结构、资源限制与 512 KiB 体积上限。
  4. 校验通过后更新当前设计,前端将成品载入隔离的 iframe,交给浏览器执行脚本;完成轮次的记录与设计版本再由投影层写入 Neon。

在每个服务进程里,fx0 通过 createFxAgent() 创建并复用 Agent 实例,不同聊天各有自己的会话。需要派发独立子任务时,工具内部再用 createFxEngine() 启动内存子引擎。两者负责的范围不同:前者提供会话与持久任务运行,后者执行这一项子任务。

// 简化示意:配置对象由 fx0 提供,不是可直接复制运行的完整程序。
const agent = createFxAgent(agentOptions)
const session = agent.session(sessionId, sessionOptions)
session.prompt(message, { messageId })
const engine = await createFxEngine(subtaskOptions)

方便带走,也带来了取舍

后端验证器把单个设计文件限制在 512 KiB 以内,并限制外部资源、表单和嵌套页面。fx0 还把生成页放进沙箱 iframe,用浏览器的内容安全策略限制网络请求,避免它直接访问应用的 Cookie、存储和凭证。

因此,Agent 制作页面时可以查网页,生成页在 fx0 预览里却不能调用业务 API、读取外部数据库或加载网络字体。普通 HTTPS 参考链接仍可由用户另行打开。

这些是浏览器执行的隔离措施,不等于页面永远无漏洞或无错误。单文件方便离线打开,但换到不同屏幕、浏览器和设备后,排版、交互和性能仍要检查。

生成中断了,后台怎样接着做?

假设 Agent 正在写粒子画布,负责处理这次请求的云函数突然停止。只保留聊天记录还不够:系统还需要知道哪些步骤已经完成、现有设计是什么,以及后续该从哪里继续。

fx0 把这些工作分开:自己负责聊天、预览、账号与设计版本;libfx 负责模型调用、工具执行、重试和每一轮任务。Redis 保存聊天与实时设计,Neon 保存账号、归属、完成的轮次及版本;执行中的逐步记录存进 Workflow World。需要接续时,Vercel Queues 唤醒新的函数,让 libfx 从已保存的步骤继续。

fx0 官方架构图:聊天和API连接Redis、Neon与libfx,libfx连接模型网关、步骤存储和恢复队列
官方架构图。fx0 管界面与设计,libfx 跑任务,World 保存步骤,Queues 负责唤醒接续。

用户提交的消息先存入 Redis,libfx 接受后才确认;执行结果流式返回,完成的一轮再留下设计版本。恢复任务也保留原来的计费身份,避免把试用请求转成某个付费账号的账单。

fx0 官方消息流程图:保存消息、封存计费身份、逐步执行、流式返回,以及故障后的接续路径
官方消息流程图。虚线路径表示函数停止后由新函数接续;图中未标出恢复等待时间。

恢复也不意味着把所有工具调用再执行一遍。读取设计、抓取网页等安全可重复操作可以重跑;编辑、提问和子 Agent 不会被盲目重放,模型会收到中断提示,再检查该怎样继续,减少重复改动。

为什么有时要等到发送后约 13 分钟?

在 Vercel 上,libfx 无法立即判断原请求是崩溃了,还是仍在缓慢工作。为避免两个执行者同时修改同一会话,原请求继续持有会话,直到 800 秒的时限结束;后备队列在再过 5 秒后接管。

所以,初始请求若意外崩溃,恢复时点可能在首次发送提示词后约 805 秒,不是每次崩溃后另等 13 分钟。正常运行但耗时较长的任务,会在时限前 30 秒保存并交接,不必额外等到这个后备时点。

每轮父 Agent 与子 Agent 合计最多 64 个模型步骤,用来限制失控循环;它不是费用封顶。聊天历史也不会被裁剪,轮次很长时打开会变慢。本次实际测试覆盖了页面生成和交互,没有主动制造云端崩溃,也没有测试真实账单。

用风格规范约束设计,用适合的任务开始

fx0 内置十种 design.md,包括以 Apple、Vercel、Stripe、Linear 等命名的风格,也可以上传自己的文本文件。这些预设来自 VoltAgent 对品牌公开官网的分析,不是各品牌官方发布的规范。

风格文件约束后续每一轮修改。 文件用文字说明主色、字阶、间距和组件规则,整份内容会进入该聊天后续的模型请求。比如希望连续做几张同风格的页面,可以把这些要求写进自己的 design.md,不必每次重述。上传上限为 100 KB,超限会拒绝,不会自动压缩。

参考网页可以交给 Agent 读取。 它能用 web_search 搜索,也能用 web_fetch 抓取公开页面。抓取工具移除脚本、样式与 HTML 标签,把文字内容交给模型参考。这条路径取回的是文字参考,不是把原网站的图片、字体和框架整套搬进成品;生成页仍要遵守单文件资源规则。

子任务可以交给子 Agent。 例如单独提炼一份参考资料,或整理样式要求。子 Agent 使用同类设计工具,但不能继续派生下级 Agent;它与主 Agent 共用本轮 64 个模型步骤,分派任务不会绕过这个预算。已有的持久化与恢复机制,则负责在执行中断后保留并接续这些工作。

从本次结果看,fx0 很适合探索交互展品、单页视觉作品、动效原型和教学小工具:生成后就能操作,下载后还能查看和修改代码。它的预览环境无法直接承接需要登录、实时数据库和业务接口的完整应用;如果要把导出的页面发展成业务项目,这些部分仍需另行搭建。512 KiB 的限制也不适合装入大量高清图片、视频或重型三维素材。

打开成品很轻,完整自部署有门槛

在浏览器打开下载的 HTML,与在自己的服务器上运行整套 fx0,是两个不同任务。后者需要 Node.js 24,以及 Vercel 登录应用、Neon Postgres 和 Upstash Redis 三项服务。

完整自部署的准备与仓库启动命令

先准备 Sign in with Vercel 应用:作用域为 openid profile email offline_access,权限为 AI Gateway: Use 与 Team: Read Only,回调地址包含 http://localhost:3000/api/auth/callback。offline_access 用于获得刷新令牌,不能省略。

克隆并进入仓库,把 .env.example 复制为 .env.local,填入登录应用、Neon 和 Upstash 的配置;SESSION_SECRET 使用至少 32 字符的随机字符串。若本地与已有部署共用 Redis,应设置独立的 FX0_REDIS_PREFIX,避免会话混在一起。

git clone https://github.com/vercel-labs/fx0.git
cd fx0
cp .env.example .env.local

填好配置后执行:

npm ci
npm run db:migrate
npm run dev

数据库迁移需要显式执行,应用不会自动完成。本次未运行这套完整后端;具体环境变量与部署设置以仓库说明为准。

这三个案例最有价值的地方,是把一句设计要求里的动作变成了可以检查的反馈:换任务是否联动读数,调密度是否真的多画线,切模式是否换了一套图形规则。用这些具体变化去判断成品,比只看首屏是否漂亮更可靠。

↑ 正文结束
✓ 本篇全文免费开放

会员可复制、下载全文 Markdown,还能让你的 AI 订阅和提问。

阅读原文 ↗
📮 新解读第一时间进邮箱

读完觉得有用?留个邮箱,每篇新解读发布就送达,随时退订。