把任意网站克隆成可运行的 Vite + React + TypeScript + Tailwind v4 项目。
Web Imitator 用一个基于 LangGraph 的多阶段 agent 流水线,把"看清一个页面 → 理解它的结构 → 生成组件代码 → 组装成项目 → 跟原图对比 → 修不好就降级"这个完整闭环自动化。输入一个 URL,输出一个能 npm run dev 跑起来的项目。
7 阶段流水线,每阶段的产物落盘作为下一阶段的契约(单进程、文件为契约,不依赖任何外部服务即可跑通):
URL
│
▼
recon ───────► Playwright 截图 + DOM dump + computed styles
│
▼
analysis ────► 视觉 LLM 拆分页面 → component_inventory + page_topology
│
▼
spec ────────► 每个 component 生成 ComponentSpec(含 computed_styles、
│ interactions、content、accessibility、responsive)
│ ▼ Send API fan-out(并行)
▼
build ───────► 每个 spec 生成 .tsx + 下载 assets + tsc 校验
│ ▼ 汇合到 built_components
▼
assemble ────► scaffold Vite 模板 + 复制 .tsx + LLM 生成 Page.tsx +
│ npm install && npm run build
│
▼
qa ──────────► 启动 dev server,原图 vs 克隆图 pixel diff +
│ 行为契约校验 → QAReport(issues 含 root_cause)
│
▼
diagnose ────► 规则化根因判定(spec_wrong / build_wrong /
│ asset_missing / acceptable)
│ ├─ re_spec → Send 回 spec_component(单组件级重跑)
│ ├─ re_build → Send 回 build_component(单组件级重跑)
│ └─ mark_known_issue / 预算耗尽 → 写 known-issues.md,END
│
▼
done ◄────── 外层循环重跑 assemble → qa → diagnose 直到无重试
设计细节见 docs/superpowers/specs/2026-07-05-web-imitator-design.md。
cd agent
uv sync --all-extras
uv run playwright install chromium把 .env.example 复制到仓库根目录的 .env,填入 DashScope API key:
cp ../.env.example ../.env
# 编辑 ../.env,填入 DASHSCOPE_API_KEY=sk-...可选:开启 Langfuse 追踪用于调试 LLM 调用链:
cd ../docker && docker compose -f docker-compose.langfuse.yml up -d
# 然后在 .env 里填 LANGFUSE_PUBLIC_KEY / LANGFUSE_SECRET_KEY / LANGFUSE_HOSTuv run web-imitator clone https://example.com跑完后产物在 output/<run_id>/:
output/<run_id>/
├── run.json # 运行元数据(url、status、qa_summary、known_issues)
├── known-issues.md # 放弃重试的组件清单(如有)
├── recon/ # 截图 + DOM + computed styles
├── specs/ # 每个 component 的 spec.json + spec.md
├── components/<id>/*.tsx # 生成的组件代码
├── project/ # 最终的 Vite 项目(可 npm run dev)
├── qa/ # qa-report.json + 对比图
└── checkpoints.sqlite # LangGraph 检查点(断点续传用)
进入 project/ 跑起来:
cd output/<run_id>/project
npm run devclone 是一键端到端入口。每个阶段也暴露了独立子命令,便于调试单阶段:
| 命令 | 作用 |
|---|---|
clone <url> |
一键端到端:recon → ... → diagnose loop → done |
recon <url> |
只跑 recon,写截图 + DOM |
analyze <run_id> |
只跑 analysis(复用已有 recon) |
spec <run_id> |
只跑 spec(复用已有 inventory) |
build <run_id> |
只跑 build(复用已有 specs) |
assemble <run_id> |
只跑 assemble(复用已有 components) |
qa <run_id> |
只跑 QA(复用已组装的 project) |
web-imitator clone <url> [OPTIONS]
Options:
--run-id TEXT 自定义 run_id(默认 host-timestamp)
--output-base PATH 输出根目录(默认 output/)
--force-rerun 忽略已有产物,从头跑
--reuse-recon 复用已有 recon/,从 analysis 起跑
--reuse-spec 复用已有 specs/,从 build 起跑
--threshold FLOAT 相似度阈值(0-1),低于此值标 PARTIAL
--max-retries INT diagnose 循环最大迭代数(覆盖 config 预算)退出码:0 = 成功或部分成功(有可用 project);1 = 致命错误(见 run.json 的 error 字段);2 = 前置条件不满足(如 --reuse-* 但无对应产物)。
通过环境变量配置(v1 不用 YAML)。详见 .env.example。
| 环境变量 | 必填 | 说明 |
|---|---|---|
DASHSCOPE_API_KEY |
是 | Qwen / DashScope API key |
WEB_IMITATOR_LLM_API_KEY |
否 | 备选 key 名 |
LANGFUSE_PUBLIC_KEY |
否 | 开启 Langfuse 追踪 |
LANGFUSE_SECRET_KEY |
否 | 开启 Langfuse 追踪 |
LANGFUSE_HOST |
否 | Langfuse 地址(默认 http://localhost:3000) |
LLM 路由默认值(在 agent/src/web_imitator/config.py 里改):
| Phase | Model |
|---|---|
| analysis / spec / qa_visual | qwen-vl-max(视觉) |
| build / assemble | qwen3-coder-plus(代码) |
| diagnose | qwen3-max(推理) |
| fallback | qwen3-max |
web-imitator/
├── agent/ # Python agent(LangGraph 流水线)
│ ├── src/web_imitator/
│ │ ├── cli.py # typer CLI 入口(clone/recon/analyze/...)
│ │ ├── orchestrator.py # clone 命令的外层 diagnose 循环
│ │ ├── config.py # 环境变量 → CloneConfig
│ │ ├── errors.py # FatalError / LogicError / TransientError
│ │ ├── run_manager.py # run.json 生命周期
│ │ ├── graph/ # LangGraph builder + 7 个节点
│ │ ├── llm/ # LLM client + prompts
│ │ ├── qa/ # QA + diagnose 根因判定
│ │ ├── codegen/ # scaffold + icons + tsc 校验
│ │ ├── models/ # pydantic 模型(tokens / qa / inventory)
│ │ ├── storage/ # RunPaths + serializers
│ │ ├── tools/ # Playwright capture + browser pool
│ │ └── observability/ # logging + langfuse + metrics
│ ├── tests/ # unit + integration + e2e fixtures
│ └── pyproject.toml
├── scaffold-templates/ # Vite + React + TS + Tailwind v4 模板
├── docker/ # Langfuse docker-compose
└── docs/ # 设计文档 + 实现计划
cd agent
uv run pytest # 全套测试
uv run pytest tests/unit/ # 只跑单元测试
uv run pytest tests/e2e/ # 只跑 fixture 完整性测试
uv run ruff check . # lint
uv run mypy src/web_imitator # 类型检查agent/tests/e2e/sites/ 下有三个本地 fixture 站点(simple / medium / complex),代表三个复杂度档位,阈值分别为 95% / 90% / 85%:
# 跑 simple fixture 验收(需要 API key + Playwright)
uv run web-imitator clone "file://$(pwd)/tests/e2e/sites/simple/index.html" \
--run-id e2e-simple-$(date +%Y%m%d)详见 agent/tests/e2e/README.md。真实网站验收报告见 docs/examples/。
第一次真实 E2E 验收(simple fixture,2026-07-06):
| 指标 | 值 |
|---|---|
| 相似度 | 71.89% |
| 预期阈值 | ≥ 95%(simple 档) |
| 耗时 | 14 分 34 秒 |
| LLM 调用 | 28 次(qwen3.7-plus) |
| Token 消耗 | ~100,000 tokens |
| 状态 | partial |
完整报告见 docs/examples/simple-2026-07-06.md。
结论:7 阶段流水线端到端跑通(recon → analysis → spec → build → assemble → qa → diagnose),QA 像素对比正常运行(非降级),diagnose 回路正确工作(3 次重试后降级为 known issues)。主要差距在 build 阶段 tsc 校验——.tsx 生成成功但通不过 strict TypeScript 校验,后续迭代改进。
三层错误模型(设计规范 §6):
- TransientError(网络 / 限流 / 浏览器崩溃)→ 工具层 tenacity 自动重试
- LogicError(spec 校验失败 / 组件无解)→ 进 diagnose 回路,按预算重试
- FatalError(配置错 / 依赖缺失)→ 顶层捕获,写
run.json+ 退出码 1,磁盘上的部分产物保留可 salvage