screenshot-to-code 中的 Claude 3 视觉能力评测:一套可复现的"截图转代码"模型评估体系
本文围绕 screenshot-to-code 项目的评测博文 evaluating-claude.md 展开,完整还原作者评估 Claude 3(Sonnet / Opus)与 GPT-4 Vision 在"截图转代码"任务上表现的方法论:16 张截图数据集、0–4 分人工复现度打分、并行评测脚本与前后对照 UI,并给出三个模型的实际得分对比。读完本文,你既能理解这套评测如何设计,也能基于仓库中的 run_evals.py 与 Evaluation.md 在自己的环境里复现模型对比实验。
评测背景与总体结论
screenshot-to-code 是一个利用 GPT-4 vision 将截图/设计稿转换为干净代码(HTML/Tailwind/React/Vue 等)的开源项目。Claude 3 发布时宣称在大量任务上可与 GPT-4 比肩,作者随即针对自己项目最核心的任务——截图转代码——做了一次直接对比。
原文给出的 TLDR 结论是:Claude 3 在截图转代码上达到 GPT-4 vision 的水平,某些方面更好,某些方面更差。 这个结论不是拍脑袋得出的,而是基于一套完整的评测流程,下面逐层拆解。
评测设置:数据集、指标与打分机制
由于当时没有公开的"截图转代码"基准测试,作者自建了一个简单的评测体系,包含三个要素:
- 评测数据集:16 张截图,混合了 UI 组件、落地页、仪表盘和知名网站(如 Hacker News)页面,覆盖面兼顾了从局部组件到完整页面的不同复杂度。
- 评测指标:复现准确度(Replication accuracy),即"生成的代码渲染后与原截图有多接近"。作者明确指出,虽然代码质量、速度等指标同样重要,但复现度是该项目用户最关心的第一指标。
- 评测机制:由人工对每个输出按 0–4 分打分——4 分表示"几乎完全复刻",0 分表示"与原截图毫无相似之处"。16 张截图意味着单轮跑分的理论最高分为 64 分。
需要说明的是,仓库中的 Evaluation.md 在描述前端打分界面时写的是"按 1–4 分打分",与博文中的 0–4 分略有出入;两者都是作者对同一个人工评分环节的表述,本文以博文原述的 0–4 分制为准。
为了降低评测操作成本,作者编写了一个 Python 脚本对所有输入并行执行代码生成,并配套一个简单的 UI 用于输入/输出的前后对照比较。这一套工具链在后文结合源码展开。
评测工具链的源码实现
入口脚本:backend/run_evals.py
博文链接到的 run_evals.py 入口极其精简:
from dotenv import load_dotenv
load_dotenv()
import asyncio
from evals.runner import run_image_evals
async def main():
await run_image_evals()
if __name__ == "__main__":
asyncio.run(main())
它先加载环境变量(API Key 等),然后调用 evals/runner.py 中的 run_image_evals。按 Evaluation.md 的说明,运行前需要在脚本中设置 STACK(技术栈)与 MODEL(模型)两个变量,并以 OPENAI_API_KEY=sk-... python run_evals.py 的形式执行——脚本会对输入数据集并行跑代码生成,"仍需几分钟才能完成"。
并行执行与重试机制
从 runner.py 的源码结构看,评测执行器的核心设计包括:
- 并行调度:所有(输入 × 尝试次数)的任务被封装为协程列表,通过
asyncio.as_completed按完成顺序消费结果(见 runner.py),这是博文所说"runs code for all the inputs in parallel"的底层实现。 - 失败重试:单张截图的生成失败会重试,上限由
MAX_EVAL_RETRIES = 2控制(runner.py);但预算超限(BudgetExceededError)这类错误不做重试,因为"每次重试都会重新花掉整个预算上限"。 - 输出组织:结果写入以日期、模型、技术栈命名的子目录,即
{EVALS_DIR}/results/{今天日期}_{model}_{stack}/,每张截图输出为{输入文件名}_{尝试序号}.html(见 runner.py)。EVALS_DIR可通过环境变量配置,默认指向backend/evals_data(见 config.py)。 - 可观测产物:除 HTML 输出外,还会追加写入
generation_times.txt(每个输出的耗时,用于评测中"速度"这一维度的观察)和failed_tasks.txt(失败日志)。
单图生成链路
真正调用模型的是 evals/core.py 中的 generate_code_for_image:它用 build_image_prompt_messages 组装图像提示词消息,按模型所属厂商校验对应的 API Key(ANTHROPIC_API_KEY / GEMINI_API_KEY / OPENAI_API_KEY,见 core.py),再通过 Agent 运行器执行生成。也就是说,评测流程与正式产品生成共用同一套 prompt 与模型调用链路——这保证了博文结果反映的是项目真实使用场景下的模型表现,而非脱离上下文的裸模型测试。
一个值得注意的细节:Claude 3 在发布初期由 OpenAI 兼容网关间接访问,如今仓库已内置完整的 Anthropic 原生 Provider(agent/providers/anthropic/provider.py),负责 OpenAI 消息格式到 Claude 消息格式(含图片 base64 块、20 图以上时的尺寸压缩)的转换,并支持工具调用、流式 thinking 与 token 用量/成本统计。模型清单在 llm.py 的 Llm 枚举中维护——可以看到当时的 Claude 3 Sonnet/Opus 已随时间演进为 claude-sonnet-4-6、claude-opus-4-8 等更新型号,但"按 provider 分组 + 显式映射"(MODEL_PROVIDER,llm.py)的多模型架构与博文评测时期一脉相承。
人工打分 UI
博文提到"一个简单的 UI 用于输入/输出前后对照"。在仓库中,评分入口是前端 /evals 路由下的评测页面族(EvalNavigation.tsx),包括 AllEvalsPage(全部评测对照)、RunEvalsPage(运行评测)、BestOfNEvalsPage 等。后端对应路由在 routes/evals.py:GET /evals?folder=... 会列出指定输出目录下的 HTML 文件,并按输入文件名把同一截图的多次尝试归组返回,前端据此渲染"原图 vs 生成结果"的对照卡片供人工打分。Evaluation.md 补充了使用方式:打分完成后可将页面打印为 PDF 分享给他人。
评测结果:三个模型的复现度对比
先交代被测代码类型:screenshot-to-code 支持 HTML + Tailwind、React、Vue 等多个技术栈(stack),技术栈会显著影响复现度——例如 Bootstrap 可用元素集相对受限,用 Bootstrap 生成的页面往往带明显的"Bootstrap 味"。本次评测只跑 HTML/Tailwind,因为这是 GPT-4 vision 表现最好的技术栈,可排除技术栈差异对模型的干扰。
以下为每个模型 3 次独立运行取平均的得分(原始为 64 分满分制的百分比化结果):
| 模型 | 得分 | 备注 |
|---|---|---|
| GPT-4 Vision | 65.10% | 基准线,"我们要超越的对象" |
| Claude 3 Sonnet | 70.31% | 略胜一筹 |
| Claude 3 Opus | 61.46% | 意外垫底,低于前两者 |
两个值得注意的发现:
- Sonnet 超过 GPT-4 Vision:70.31% 对 65.10%,且差距并非噪声级别的。
- Opus 反向落榜:按产品定位,Opus 应该是"更聪明但更慢"的模型,却在复现度上同时输给了 GPT-4 Vision 和 Sonnet。作者当时的猜测是:Opus 的差距可以通过更好的 prompting 弥补到与其他模型相当的水平。
作者同时诚实地标注了评测局限:打分是主观的(subjective),但综合来看"Claude 3 毫无疑问与 GPT-4 Vision 处于同一水平,甚至更好"。原文还附了 Claude 3 Sonnet 与 GPT-4 Vision 各一轮跑分的整页前后对照截图(托管在项目配套文件仓库中,本文不转载外部图片)。
评测中的定性观察
除了分数,博文记录了几条对使用者有直接参考价值的行为差异:
- 提示词适应性:所用 prompt 是为 GPT-4 vision 优化的;为 Claude 做少量调整后确有小幅提升,但"并非改变格局",且要权衡维护两套 prompt 的成本。
- 代码质量整体出色:所有模型的代码质量都接近甚至超过人类水平。
- "偷懒"行为差异显著:以复刻 Hacker News 为例,GPT-4 Vision 只会生成列表中的两条新闻,并在代码里留下
<!-- Repeat for each news item -->、<!-- ... other news items ... -->这类占位注释;Claude 3 Sonnet 虽然偶尔也会偷懒,但大多数时候会完整执行你的要求。 - flex 横向布局是共同短板:"所有模型"在并排 flex 布局上都有困难,这说明视觉到布局结构的映射是该任务的固有难点,而非某一家模型的缺陷。
- 速度:Claude 3 Sonnet 明显更快。
- 颜色准确性:Claude 3 经常弄错背景色与文字色(Hacker News 案例中即有体现)。
最终结论:作者对 Claude 3 Sonnet 在该用例上的表现"印象深刻",并将其作为 GPT-4 Vision 的替代选项加入开源仓库。从当前仓库源码看这一集成确实长期存续并持续演进:llm.py 中 Anthropic 模型族已扩展到 Sonnet/Opus/Fable 多个型号与多种 effort 档位,Anthropic Provider 实现了完整的流式会话、工具调用循环与用量计费,ANTHROPIC_MODELS 成员集合(llm.py)则被 evals/core.py 用于评测时的 API Key 校验——博文评测所引入的"多模型可比性"架构一直保留至今。
如何自己复现这套评测
按 Evaluation.md 的步骤,可以在本地完整复现该评测流程:
- 准备输入:输入截图放在
backend/evals_data/inputs,输出会落到backend/evals_data/outputs(或results,见 runner 实现);如需修改位置,改 evals/config.py 中的EVALS_DIR环境变量。 - 选择技术栈与模型:在 run_evals.py 中设置
STACK与MODEL变量。 - 并行执行:
OPENAI_API_KEY=sk-... python run_evals.py——对数据集并行生成代码,耗时数分钟。 - 人工打分:访问前端
/evals页面,对每个输出打分,并可将结果页打印为 PDF 分享。 - 统计口径:作者的做法是对每个"模型/prompt + 技术栈"组合跑 3 次测试取平均分——本文的结果表即遵循该口径。
此外,当前仓库的评测体系已比博文时期更完整:支持命名的评测集(PNG 放入 sets/{名称}/inputs/,由 evals/sets.py 管理清单与图片哈希)、评测会话与 agent 运行记录(evals/sessions.py、fs_logging/agent_runs.py)、OpenAI 输入格式对比页(routes/evals.py、OpenAIInputComparePage.tsx)等。作者也在博文中提到,当时正着手用 Elo 评分机制替代纯人工打分,欢迎社区参与改进。
小结
这篇评测的价值不在于某一轮的胜负数字,而在于展示了一个视觉代码生成项目"如何诚实地评估新模型"的完整范式:明确的单一核心指标(复现度)、可控的变量(固定 HTML/Tailwind 技术栈)、多次运行取均值(3 runs)、保留定性观察(偷懒、flex 布局、颜色错误)以及全部工具开源可复现。Claude 3 Sonnet 以 70.31% 超越 GPT-4 Vision 的 65.10%,而 Opus 以 61.46% 意外垫底——这个"更大模型未必更好"的反直觉结果,至今仍是评估 LLM 能力时值得记住的教训。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0622
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00