Vision2Web: A Hierarchical Benchmark for Visual Website Development with Agent Verification

Paper: arXiv:2603.26648 Code: zai-org/Vision2Web Code reference: main @ 3111cc31 (2026-05-02)

1. Motivation (研究动机)

现有 coding-agent benchmark 很难真正回答“一个多模态 Agent 能不能从视觉稿 + 需求文档做出可运行网站”这个问题。SWE-Bench Multimodal 更偏 issue fixing,Design2Code 主要是单页静态 UI-to-Code,WebGenBench 虽然评估 website generation 但不是多模态视觉开发;这些任务覆盖了局部代码编辑、单页视觉还原或文本式网站生成,却没有把响应式 UI、跨页交互、后端状态、部署与自动化验证放在同一个递进体系里。

Vision2Web 要解决的具体问题是:构造一个分层、真实、可复现的 visual website development benchmark,让模型从 Level 1 的静态响应式网页,到 Level 2 的多页交互前端,再到 Level 3 的 full-stack website delivery,逐层暴露视觉理解、跨页规划、状态管理和系统交付能力。论文用 193 个真实网站任务、918 张 prototype images、1,255 个 test cases,以及 workflow-based agent verification,把“做得像不像”和“功能能不能跑通”同时纳入评估。

这个问题值得研究,因为 website development 是一个很典型的 end-to-end agent 场景:输入不是单一自然语言,而是 UI prototypes、需求文本、多媒体资源、交互逻辑和运行环境;输出也不是一个函数,而是可部署的系统。如果 benchmark 只看单页截图或局部 issue,就会高估模型在真实工程任务中的可用性。Vision2Web 的实验显示,即使最强模型在 static webpage 上能取得较高视觉分,在 full-stack tasks 上也会明显掉分,这正是传统 benchmark 不容易暴露的能力断层。

2. Idea (核心思想)

核心 insight 是:visual website development 应该被拆成一个层级任务族,而不是被压成“给一张图生成一页 HTML”。Vision2Web 用 Static Webpage → Interactive Frontend → Full-Stack Website 三层任务,把视觉还原、跨页交互和系统级功能逐层叠加;再用 GUI agent verifier 与 VLM judge 组成 workflow-based verification,把实现多样性留给被测 agent,同时把评测路径和判据约束住。

它的关键创新不在于提出新的模型,而在于 benchmark design + verification design:数据来自 C4 validation set 的真实网页,经结构筛选、VLM 内容筛选和人工复核;评测不依赖 brittle pixel matching 或固定单元测试,而是把测试流程建模成有依赖的 workflow graph。与 Design2Code 相比,Vision2Web 不只测单页视觉相似度;与 SWE-Bench Multimodal 相比,它不是让 Agent 修已有 repo 的局部 issue,而是要求从 prototype/spec/resource library 交付完整前端或 full-stack 项目。

3. Method (方法)

3.1 整体框架:三层任务 + 双验证器

Figure 1 解读:图中左侧是输入材料,包括 visual prototypes、文本需求和资源库;中间是三层任务,从 static webpage 的单页响应式还原,到 interactive frontend 的多页导航,再到 full-stack website 的状态、后端与调试;右侧是 evaluation pipeline,用 GUI agent verifier 执行 workflow 中的功能测试节点,用 VLM judge 对 prototype 与实际页面做视觉一致性评分。因此 Vision2Web 的“层级”不是简单按数据规模排序,而是按软件工程能力递进:视觉感知 → 交互建模 → 系统交付。

直觉上,这种设计把 Agent 的失败位置显式化。若一个模型在 Level 1 已失败,问题多半是视觉 grounding、布局和 CSS;若 Level 1 可以但 Level 2 掉分,瓶颈转向跨页面状态和导航;若 Level 3 掉分,则通常是需求分解、长期规划、后端数据流和自我验证不足。这个拆分让 benchmark 不只是给出一个总分,而能告诉研究者下一步应该改进哪个能力层。

3.2 三层任务定义

  • Level 1: Static Webpage:每个任务给同一网页在 desktop / tablet / mobile 的 prototype images 和分辨率要求;Agent 必须生成一个单一静态网页,在不同设备上还原 layout、visual content 与 styling。这里主要测 responsive UI perception 与视觉还原。
  • Level 2: Interactive Frontend:输入变成多张 prototype images 加页面间逻辑关系文本;Agent 要生成 fully interactive multi-page frontend,保持结构一致、导航连贯、组件组织合理。这里开始测跨页推理和前端状态。
  • Level 3: Full-Stack Website:输入包含 structured requirement documents 与 prototypes;Agent 要解释需求、管理复杂状态、做集成调试,并交付 cohesive full-stack system。这里测端到端软件工程能力。

所有任务都带 multimedia resource library(images、icons、videos、fonts),并有明确 requirements,避免模型把真实开发中常见的资源和规格假设掉。

3.3 数据构建:从真实网页到可评测任务

Vision2Web 的数据全部来自 C4 validation set,目的是降低热门网站或训练集泄漏风险。构建流程分三步:

  1. Structural Assessment:参考 Design2Code 的原则,分析 HTML tag distribution、DOM tree depth 和 token length;过滤过于简单、结构异常或语义不足的页面,候选集缩到 63,515 个 websites。
  2. Content Screening:用 VLM-based scoring 过滤内容和设计质量,只保留 7,391 个在 functional richness、modular clarity、visual coherence 上较好的页面;排除缺少有意义交互、布局组织差或功能覆盖有限的网页。
  3. Manual Review:标注者按 page consistency、跨设备质量、实现难度、页面尺寸、交互功能清晰度与丰富度复核,并保持类别覆盖平衡。

Figure 2 解读:任务覆盖 Content、Transaction、SaaS Platforms、Public Services 四个 macro categories,并进一步细分为 16 个 subcategories。这种分布让 benchmark 不只是“漂亮网页复刻”,也包括交易流程、企业 SaaS 和公共服务等功能密集网站,从而更容易暴露状态管理、表单、认证、搜索过滤等工程问题。

最终数据规模如下:

StatisticValue
Total tasks193
Static webpage tasks100
Interactive frontend tasks66
Full-stack website tasks27
Prototype images918
Test cases1,255
Input files21,516

各层平均输入规模:

LevelAvg Prototype ImagesAvg Test CasesAvg Text Tokens ()
Webpage
Frontend
Website

3.4 Workflow-Based Agent Verification

传统功能测试在这里很难直接使用:不同 Agent 可以用 React、Vue、vanilla JS、不同后端或不同路由结构实现同一需求,固定 unit test 会过度绑定 implementation。Vision2Web 的做法是把端到端测试抽象成 directed dependency graph:每个节点是一个自包含 verification sub-procedure,边表示顺序依赖和 shared state;若若干节点属于同一个 application context,就合并成一个 agent-executable test workflow。

功能节点被形式化为: 其中 是测试目标, 是 guided actions, 是 validation criteria。GUI agent 在节点 上收到上下文: 其中 记录此前节点的 objectives 和 actions。显式给出 的意义是约束 agent 的行为范围,避免它在“测试登录功能”这种宽泛目标下随意探索,提升 reproducibility。

视觉节点被形式化为: 其中 是目标 prototype。VLM judge 对 rendered page 与 prototype 进行 component-level comparison,并按 prompt 中的 rubric 给每个 component 一个 分数。论文文字说 FS 是 functional verification nodes 的通过比例,VS 是跨 prototypes 的平均 visual score;结合 released code 的 prompt 输出结构,可以写成: Algorithm 1 的核心流程是:初始化 history、functional scores 和 visual scores;按 workflow 顺序遍历节点;功能节点调用 GUIAgentVerifier 并把 加入 history;视觉节点调用 VLMBasedJudge;最后返回

def workflow_based_verification(workflow, initial_state, gui_verifier, vlm_judge):
    history = []
    functional_scores = []
    visual_scores = []
    state = initial_state
 
    for node in workflow:
        if node.type == "functional":
            passed, state = gui_verifier.run(
                history=history,
                objective=node.objective,
                actions=node.guided_actions,
                validations=node.validation_criteria,
                state=state,
            )
            functional_scores.append(float(passed))
            history.append((node.objective, node.guided_actions))
        elif node.type == "visual":
            component_scores, state = vlm_judge.compare(
                prototype=node.prototype,
                current_state=state,
            )
            visual_scores.append(sum(component_scores) / len(component_scores))
 
    return functional_scores, visual_scores

3.5 Agent-assisted annotation 与 verifier 配置

测试标注也按层级变化:static webpage 的 annotation 主要是 resolution-specific visual verification;interactive frontend 主要让 Claude Code 从 prototypes 推断 navigation structures 生成 navigation-oriented test cases;full-stack websites 因为有 long-horizon dependencies、cross-module interactions 和 boundary cases,采用 expert-in-the-loop:专家先从需求文档和 prototypes 起草 high-level workflows,再由 Claude Code 扩展成 executable interaction sequences 和 verifiable criteria。

Figure 3 解读:这张图展示 website-level tasks 的 test case 类型分布,说明 full-stack 层不只测页面跳转,还覆盖认证、状态管理、CRUD、搜索过滤、文件/媒体等功能场景。也就是说,Vision2Web 的测试不是“打开网页看一眼”,而是把用户旅程拆成多个可执行、可验证的 workflow nodes。

论文 appendix 指出 GUI agent verifier 使用 GLM-4.6V,VLM judge 使用 Gemini-3-Pro-Preview;released code 的 EvaluationConfig 默认也设置 gui_agent_model="glm-4.6v"vlm_judge_model="gemini-3-pro-preview"。released code 还体现了两个实现细节:GUIAgentTester._compare_prototype 对 VLM 比较最多重试 3 次;EvaluationEngine._wait_for_port(..., timeout=600) 与论文“deployment 超过 10 分钟视为失败”一致。论文公式与 released code 实现差异:未发现关键指标定义上的冲突;代码主要把论文中的 workflow verification 具体化为 JSON workflow、Playwright/GUI agent 执行、prototype screenshot 保存和 component-level JSON score 解析。

3.6 Released code 的执行路径

zai-org/Vision2Web 提供的是 benchmark runner 与 evaluator,而不是训练代码。代码入口大致分成 dataset discovery、inference generation、evaluation 三段:

def discover_projects(datasets_dir, task_filter=None):
    projects = []
    for task_type in task_filter or ["webpage", "frontend", "website"]:
        for project_dir in sorted((datasets_dir / task_type).iterdir()):
            project = Project(
                name=project_dir.name,
                task_type=task_type,
                prototypes_dir=project_dir / "prototypes",
                resources_dir=project_dir / "resources",
                workflow_path=project_dir / "workflow.json",
                prompt_path=project_dir / "prompt.txt",
                prd_path=project_dir / "prd.md",
            )
            projects.append(project)
    return projects
async def run_inference_for_project(project, config, sandbox_manager, adapter):
    workspace = make_workspace(project)
    copy_project_files(project, workspace)
    container_id = await sandbox_manager.create_container(workspace)
    prompt = get_prompt_for_task(project.task_type)
 
    max_attempts = 1 + config.inference.max_retries  # default 3 attempts
    for attempt in range(max_attempts):
        result = await adapter.run_task(
            workspace=workspace,
            prompt=prompt,
            project_info=project.to_dict(),
        )
        if result["status"] == "success" and (workspace / "start.sh").exists():
            return {"status": "success", "workspace": workspace, "attempt": attempt + 1}
    return {"status": "failed", "workspace": workspace}
async def evaluate_project(result_project, dataset_project, config, sandbox_manager):
    workspace = result_project["workspace"]
    container_id = await sandbox_manager.create_container(workspace)
    workflow = load_json(dataset_project.workflow_path)
 
    await sandbox_manager.exec_command(container_id, "bash", "start.sh", detach=True)
    if not await wait_for_port(container_id, port=config.evaluation.base_port, timeout=600):
        return {"status": "error", "error": "deployment timeout"}
 
    tester = GUIAgentTester(
        gui_agent_model=config.evaluation.gui_agent_model,
        vlm_judge_model=config.evaluation.vlm_judge_model,
    )
    test_results = await tester.run_test(workflow)
    prototype_scores = tester.compare_all_prototypes()
    return aggregate_scores(test_results, prototype_scores)

Code reference: main @ 3111cc31 (2026-05-02) — pseudocode and mapping based on this commit

Paper ConceptSource FileKey Class/Function
Dataset layout and task discoveryvision2web/core/dataset.pyProject, DatasetManager.discover_projects, load_workflow
Inference orchestrationvision2web/inference/engine.pyInferenceEngine.run_single_project, run_all_projects
Agent framework adaptersvision2web/inference/adapters/claude_code.py; vision2web/inference/adapters/openhands.pyClaudeCodeAdapter.run_task, OpenHandsAdapter.run_task
Sandbox isolationvision2web/core/sandbox.py; docker/Dockerfile.sandboxSandboxManager.create_container, exec_command, copy_to_container
Evaluation orchestrationvision2web/evaluation/engine.pyEvaluationEngine.evaluate_single_project, _run_tests_in_container, _wait_for_port
GUI functional verifiervision2web/evaluation/gui_agent_test.pyGUIAgentTester._execute_test_case, _execute_action, run_test
VLM visual judgevision2web/evaluation/gui_agent_test.py; vision2web/evaluation/prompts.py_compare_prototype, PROTOTYPE_PROMPT
Runtime configsvision2web/core/config.py; scripts/run_inference.sh; scripts/run_evaluation.shInferenceConfig, EvaluationConfig, CLI flags

3.7 代表性任务与失败样例

Figure 7 解读:静态网页样例把同一页面在 desktop、tablet、mobile 下同时给出,迫使模型学习 responsive constraints。它比单张 screenshot-to-HTML 更难,因为同一代码必须在多个 viewport 上保持一致,而不是只对一个尺寸过拟合。

Figure 8 解读:交互前端样例展示多页 prototype 和页面间跳转逻辑。模型不只是复刻首页,还要理解哪些元素触发 navigation、哪些状态跨页面保持,以及页面组件如何共享统一信息架构。

Figure 9 解读:full-stack 样例更接近真实产品开发:页面视觉稿、业务工作流、表单和数据状态共同出现。对 Agent 来说,难点从“写出页面”转向“把需求、前端交互、后端状态和部署脚本连成一个能被 workflow 测试的系统”。

4. Experimental Setup (实验设置)

4.1 数据集与规模

实验使用 Vision2Web 自身的三层 benchmark:100 个 static webpage tasks、66 个 interactive frontend tasks、27 个 full-stack website tasks,总计 193 tasks、918 prototype images、1,255 test cases、21,516 input files。任务覆盖 Content、Transaction、SaaS Platforms、Public Services 四类,16 个子类;Table 7 中每类任务分布例如 Content/Knowledge 为 10 static、7 frontend、2 website,Transaction/Retail 为 10/5/2,Public Services/Government Portal 为 9/4/2。

4.2 Baselines / coding agents

论文评估 8 个 multimodal models,并把它们接入两种 coding-agent framework:

  • Models:Claude-Opus-4.5、Claude-Sonnet-4.5、GPT-5、Gemini-3-Pro-Preview、Gemini-3-Flash-Preview、Seed-1.8-VL、Qwen3-VL-32B-Instruct、Qwen3-VL-8B-Instruct。
  • Frameworks:Claude Code 与 OpenHands。
  • Evaluation backbones:GUI agent verifier = GLM-4.6V;VLM judge = Gemini-3-Pro-Preview。

4.3 Metrics

  • Static Webpage score:分别报告 desktop、tablet、mobile 与 Avg,衡量不同设备上的视觉还原质量。
  • VS (Visual Score):VLM judge 对 rendered page 与 reference prototype 的 component-level visual fidelity 平均分,0–100。
  • FS (Functional Score):GUI agent verifier 执行 functional verification nodes 后得到的平均通过比例,0–100。
  • Avg:interactive/frontend 或 full-stack 中 VS 与 FS 的综合平均。
  • DSR (Deployment Success Rate):部署成功率;论文说明它是 reference metric,不作为官方核心指标。

4.4 运行与配置

论文没有训练新模型,因此没有 optimizer/LR/batch size/GPU 训练配置;实验是 inference + evaluation benchmark。可复现实验配置来自 released code:

  • Sandboxvision2web-sandbox:latest,由 docker/Dockerfile.sandboxdocker/build.sh 构建。
  • Inference defaultsInferenceConfig.framework="claude_code"model="claude-sonnet-4-5-20250929"max_workers=5timeout=3600 秒、max_retries=2,即总尝试次数
  • Evaluation defaultsEvaluationConfig.gui_agent_model="glm-4.6v"vlm_judge_model="gemini-3-pro-preview"max_workers=1base_port=3000headless=Truewindow_width=1024window_height=768
  • Deployment constraint:每个 Agent 需要生成 start.sh;evaluation 启动项目后等待固定端口,_wait_for_port(... timeout=600) 对应 10 分钟超时。

5. Experimental Results (实验结果)

5.1 主结果:复杂度越高,分数越低

FrameworkModelStatic AvgFrontend VS/FS/AvgWebsite VS/FS/AvgWebsite DSR
Claude CodeClaude-Opus-4.550.546.1 / 63.6 / 54.934.3 / 53.1 / 43.792.6%
Claude CodeClaude-Sonnet-4.540.024.9 / 48.7 / 36.814.5 / 26.8 / 20.766.7%
Claude CodeGPT-543.123.3 / 64.7 / 44.09.6 / 23.4 / 16.585.2%
Claude CodeGemini-3-Pro-Preview52.313.3 / 14.6 / 14.05.7 / 12.9 / 9.363.0%
Claude CodeGemini-3-Flash-Preview43.313.1 / 27.9 / 20.52.3 / 4.6 / 3.563.0%
Claude CodeSeed-1.8-VL18.07.0 / 13.3 / 10.20.0 / 0.0 / 0.00.0%
Claude CodeQwen3-VL-32B-Instruct0.90.0 / 0.0 / 0.00.0 / 0.0 / 0.00.0%
Claude CodeQwen3-VL-8B-Instruct11.90.0 / 0.0 / 0.00.0 / 0.0 / 0.00.0%
OpenHandsClaude-Opus-4.553.446.5 / 66.7 / 56.638.4 / 57.6 / 48.096.3%
OpenHandsClaude-Sonnet-4.547.132.4 / 59.0 / 45.715.7 / 23.9 / 20.466.7%
OpenHandsGPT-549.623.9 / 61.4 / 43.218.3 / 49.7 / 34.1100%
OpenHandsGemini-3-Pro-Preview55.829.7 / 40.7 / 35.211.7 / 22.6 / 17.277.8%
OpenHandsGemini-3-Flash-Preview47.825.9 / 38.4 / 32.27.7 / 17.2 / 12.566.7%
OpenHandsSeed-1.8-VL1.37.5 / 33.9 / 20.20.0 / 0.0 / 0.014.8%
OpenHandsQwen3-VL-32B-Instruct0.00.0 / 0.0 / 0.00.0 / 0.0 / 0.00.0%
OpenHandsQwen3-VL-8B-Instruct0.10.0 / 0.0 / 0.00.0 / 0.0 / 0.00.0%

最重要的结果是复杂度递增带来的系统性掉分。OpenHands + Gemini-3-Pro-Preview 在 static webpage 上取得最高 static average 55.8(desktop 63.3、tablet 55.8、mobile 48.3,DSR 95%),但 full-stack 只有 VS 11.7、FS 22.6、Avg 17.2、DSR 77.8%。OpenHands + Claude-Opus-4.5 是总体最强:static Avg 53.4,interactive frontend VS/FS/Avg = 46.5/66.7/56.6,full-stack VS/FS/Avg = 38.4/57.6/48.0,但 full-stack 仍明显低于前两层。

Figure 4 解读:这张图按 prototype height 展示 representative models 在 OpenHands 下的 VS 分布。它揭示了一个直观但重要的现象:页面越长、视觉结构越复杂,模型越容易在版式、组件位置和细节对齐上积累误差;这解释了为什么静态网页平均分看似尚可,但复杂页面和后续 full-stack 任务会快速退化。

5.2 与已有 benchmark 的覆盖差异

Benchmark# Tasks# Test Cases# PrototypesMultimodalTask Types
SWE-Bench Multimodal617yesIssue fixing
Design2Code484484yesSingle page UI-to-Code
WebGenBench101647noWebsite generation
Vision2Web1931,255918yesFull-stack website development

论文还比较了静态网页任务复杂度:Design2Code-Hard 的 Avg Tag Count 为 、Avg DOM Depth 为 、Avg Unique Tags 为 ;Vision2Web Webpage tasks 分别为 。这说明即使只看 Level 1,Vision2Web 的网页结构也明显更复杂。

Figure 5 解读:prototype size distribution 说明 Vision2Web 的页面高度覆盖更宽,尤其包含长页面和多模块页面。这会放大视觉还原中的局部误差,因为长页面不仅需要对齐单个组件,还需要保持整体滚动结构、模块间距和响应式布局一致。

5.3 类别与功能维度的弱点

在 OpenHands 下,full-stack website 的类别结果显示:

Website CategoryClaude-Opus-4.5 VS/FSClaude-Sonnet-4.5 VS/FSGPT-5 VS/FS
Content37.1 / 61.29.3 / 16.120.7 / 53.5
Transaction43.2 / 64.910.8 / 14.313.4 / 50.6
SaaS Platform22.9 / 39.921.7 / 42.816.7 / 40.5
Public Service56.9 / 60.041.2 / 52.027.4 / 56.0

Public Service 网站结构相对简单、交互有限,因此视觉和功能分数最好;SaaS Platform 多页导航和复杂交互更多,因此最难。按 test-case category 看,Claude-Opus-4.5 在 Navigation & Routing / Authentication & Authorization 上分别为 66.3 / 61.8,但 State Management、CRUD Operations、File & Media Operations 降到 43.2、43.6、33.3;GPT-5 在 Authentication & Authorization 为 60.0、Form Interaction 为 56.8,但 File & Media Operations 只有 16.7。这说明当前 Agent 对状态持久化、跨组件数据流和系统资源协调仍不稳定。

5.4 失败模式

Figure 10 解读:static webpage 的失败主要表现为细粒度视觉对齐问题:布局间距、字体、组件比例和响应式位置与 prototype 偏离。此时功能需求少,错误更多来自视觉 grounding 与 CSS execution。

Figure 11 解读:interactive frontend 的失败更像“跨页一致性”问题:单页局部可能看起来合理,但导航、页面状态和组件间关系无法保持一致。说明模型并不只是缺 CSS 技巧,而是缺少把多张 prototype 组织成同一个 application model 的能力。

Figure 12 解读:full-stack 失败进一步升级为系统级问题:项目可能无法启动,或启动后功能链路不完整、状态不同步、表单/CRUD/认证失败。论文把这归因于 long-horizon planning、execution drift 和缺少可靠 self-verification;这些问题无法靠更好的 screenshot matching 单独解决。

5.5 Verifier validation 与局限

作者验证了两个 evaluator 的可靠性。GUI Agent Verifier 在从 64 个任务中随机抽样的约 100 个 test workflows 上,由人工逐节点检查;在 node level,250 个 nodes 中 218 个判断与人工一致,准确率 87.2%。VLM-Based Judge 在 100 个随机 prototypes 上与人类偏好做 Spearman rank correlation,平均 、median ;同一集合上的 human inter-annotator agreement 为 。这说明自动 judge 已有较强实用一致性,但仍低于人类之间的一致性上界。

论文的局限也很明确:workflow 和 verifier 虽然比固定 unit test 更灵活,但仍依赖 GUI/VLM backbone 的能力,残余误判主要来自模型自身 reasoning hallucinations;visual preference 本身有主观性;full-stack 网站的复杂状态和边界场景仍难完全覆盖。作者计划 quarterly 更新 VLM judge 和 GUI agent,以维持 evaluator reliability。整体结论是:当前最强 multimodal coding agents 在视觉网站开发中仍存在明显短板,尤其是跨页状态、复杂交互、长期规划和系统级自我验证。