Playwright 任务增广(合成题目生成)
本目录为 playwright / playwright_webarena 两个 MCP service 增广(augment)合成题目,
供 rollout 采集 SFT 轨迹。所有生成逻辑都在本目录内,不修改 src/mcp_services/ 与
评测主流程。
0. 核心增广哲学(五条,所有生成器共用)
我们做的不是"造新题",而是在真实评测站点上、按评测集已有题型,换参数换问法地放大题量:
- 不换站点 / 不换网页 —— 复用评测集用的同一批真实站点(Postmill 论坛、Magento 商城/后台、不可变 arXiv 页、eval-web.mcpmark.ai)。绝不新建/改写站点,保证 agent 看到的页面(观测分布)和评测集一致。
- 不超纲、对齐评测集分布 —— 题型严格落在评测集
tasks/playwright*/standard/已有 形态内;生成集要覆盖评测集原题的各种形态,不引入新能力。 - 只换三样:问哪个事实/字段、参数(SKU / 关键词 / 价格区间 / 顾客 / 税州 / arXiv id…)、问法(换措辞、换语气,保留全部确切实体)。
- GT 预先求真值(不靠 LLM 猜答案) —— 建题时先用浏览器/
docker exec curl/本地权威 CSV 把 ground-truth 真跑出来,定格到label.txt/content.txt。arXiv 页、eval-web 表、docker 站快照都是稳定可复现的。 - verify 真实可核 —— agent 在对话里给
<answer>块,verify 读MCP_MESSAGES逐字段 精确比对(数值按 int、文本 normalize,照搬评测集parse_answer_format/compare_answers); 操作题还要回站点核实改动是否真的发生。
历史教训(见 memory):早期"自包含玩具 HTML"那套对真实评测提分基本无用,已废弃; 现在一律在真站点上按评测集原生 task 格式增广。
1. 目录结构(一个任务类型一个文件夹)
playwright/
├── base.py # 真网 Generator 基类 + verify 头 + 换问法 diversify_question
├── generate.py # 真网生成器的离线生成 + oracle 自检入口
├── run_eval.py # 真网生成器的端到端 runner(生成→rollout→verify)
├── deepseek_keys.txt # LLM key 池(每行一个;dimcode deepseek-v4-pro)
├── runs/ # 真网生成器的结果落地
│
├── reddit/ # A 类:webarena docker 生成器
│ ├── gen_reddit.py
│ ├── _snapshot_reddit.json # 站点快照缓存(GT 来源)
│ └── forum_data.json
├── shopping/
│ ├── gen_shopping.py
│ └── _snapshot_shopping.json
├── shopping_admin/
│ ├── gen_shopping_admin.py
│ └── _snapshot_shopping_admin.json
│
├── web_search_fact/ # B 类:真网 Generator(REGISTRY 注册,见 __init__.py)
│ └── __init__.py
└── web_table_extract/
└── __init__.py
本目录有两套生成机制,对应两类站点:
| 类 | 生成器 | 站点 | 产出 | 运行方式 |
|---|---|---|---|---|
| A | reddit / shopping / shopping_admin | 本地 docker(WebArena) | 直接写 mcpmark 原生 task 目录 到 tasks/playwright_webarena/standard/<cat>_gen/ |
独立 CLI;rollout 用 pipeline.py --mcp playwright_webarena |
| B | web_search_fact / web_table_extract | 真实互联网(走代理) | base.Generator 子类,进 __init__.py 的 REGISTRY |
generate.py / run_eval.py |
2. A 类:WebArena docker 生成器(reddit / shopping / shopping_admin)
独立脚本,爬一次真站点存快照 → 从快照采样按评测题型批量造题 → 写原生 task 目录。
每题目录含 params.json(参数)、label.txt(GT)、description.md、meta.json、verify.py。
rollout 时 playwright_webarena 的 state manager 会自动起对应 docker 容器(按 category 映射
镜像/端口),agent 在真站点上操作,结束后跑 verify.py。
2.1 reddit(Postmill 论坛,容器 forum/forum_s{n},端口 9999+n)
- 取数:
docker exec forum curl抓各论坛 top 排序前 N 页(容器内访问,稳,不依赖端口映射)。 复用评测触及的论坛 + 同实例其它热门论坛(仅为多样性,不新建)。 - 题型(严格对齐评测集):Top-N 高赞/高评论榜、关键词计数+极值、跨页"年份/图片帖" 计数+全局最高赞、给指定帖投赞(操作题)。
- 核对:内容题预爬 GT 存
label.txt,agent 发帖报答案,verify 登录→按标题找帖→ 解析Key|Value逐字段比(数值 int、用户名 strip 下划线、Top 榜票数递减校验,照搬buyitforlife_research);操作题回站点读vote__net-score(照搬routine_tracker_forum)。
2.2 shopping(Magento 商城 storefront,端口 7770+n)
- 取数:宿主→容器快照(须干净环境,去 LD_PRELOAD/proxychains,否则 localhost 被绕走)。
- 题型:高级搜索(Product Name + 价格区间)→ 结果计数;按价升/降序 → 最便宜/最贵商品 的 SKU+价格(极值);加购指定数量 → 购物车 Subtotal(=单价×数量)。
- 核对:GT 由浏览器预快照执行得到(total/价格/SKU/subtotal),agent 给
<answer>, verify 读MCP_MESSAGES逐字段精确比。刻意避开评论数/评分%/颜色/尺寸/产地(列表页 不显示、需逐个进详情且不稳,无法保证真 GT)。
2.3 shopping_admin(Magento 后台,端口 7780+n)
- 取数:宿主→容器快照(干净环境,封装在
_run_clean()自动重启)。 - 题型:products 网格(名称含某词计数 / 按 SKU 查价·库存·状态 / 数量等于某值计数)、 dashboard Bestsellers、orders 网格(总数/按状态计数/最高 Grand Total 的顾客+金额)、 customers 网格、Search Terms、Cart Price Rules、Tax Rates;覆盖评测集的"多字段捆绑题"。
- 核对:读取题 GT 存
label.txt+<answer>比对;操作题(~25%)照搬customer_segmentation_setup—— 记 baseline → 建客户组+建顾客 → 报 before/after,verify 既比<answer>又回站点核实(组/顾客存在 + records found 计数)。
用法(干净环境)
PY=/home/sunhc/miniconda3/envs/mcpmark/bin/python
env -u LD_PRELOAD -u PROXYCHAINS_CONF_FILE -u PROXYCHAINS_QUIET_MODE \
$PY reddit/gen_reddit.py --n 300 # shopping / shopping_admin 同理
# 仅刷新快照:--refresh-crawl(reddit)/ --snapshot-only(shopping*)
生成多了后按分片重切成 <cat>_gen_s0..sN、每片一个 docker 容器并行 rollout。
3. B 类:真网 Generator(web_search_fact / web_table_extract)
base.Generator 子类,定格在不可变真网页面上,沿用 oracle 契约:
build(抓页/读权威数据→定格 GT 到 content.txt)→ description → verify_src
(重算/比对)→ solve(oracle 浏览器再跑一遍证明 verify 接受预期答案、拒空答)。
- web_search_fact(对齐
playwright/web_search):锚定不可变 arXiv/abs/<id>页 (永不变)。一个 arXiv id × 多个问法模板生成多变体,问页面上的确切细节(逼模型真开页 而非凭记忆)。一部分题走搜索模式:藏 URL,让模型按标题用搜索引擎找到论文(练 web_search 的搜索能力)。GT 来自建题时的页面快照。 - web_table_extract(对齐
eval_web/extraction_table):用评测同一个页面https://eval-web.mcpmark.ai/extraction,读它的表(Title/Rating/Likes/Views/Replies), 只换问法。GT 来自仓库里已提交的权威data.csv(97 行固定),建题时确定性算出答案定格, 不抓取、不让 LLM 猜。(早期用 Wikipedia 被否:偏离评测分布 + 图片多撑爆单代理 navigate 超时。)
两者 rollout 时需经代理出网($SYNTH_PROXY,默认 US socks5 socks5://127.0.0.1:7893)。
用法
# 离线生成 + oracle 自检(无需 API)
conda run -n mcpmark python -m synth.generators.playwright.generate --no-llm --n 4
# 端到端:生成 → rollout(DeepSeek) → verify
conda run -n mcpmark python -m synth.generators.playwright.run_eval \
--n 8 --k 4 --keys-file synth/generators/playwright/deepseek_keys.txt
4. 答案格式与核对通道(两类共用)
每题报多字段 <answer> 块(对齐评测集,如 customer_segmentation_setup),verify 逐字段比
(数值 int、文本 normalize):
<answer>
Key1|value1
Key2|value2
</answer>
核对通道:对话 MCP_MESSAGES(真实评测的有效通道,browser agent 只能"说"答案);
A 类操作题 / B 类 oracle 还会用站点状态 / answer.txt 二次确认。
5. rollout 与轨迹压缩(与本目录配合)
- A 类用
pipeline.py --mcp playwright_webarena --tasks <cat>_gen_s{n} --models deepseek-v4-pro跑;B 类用run_eval.py。LLM 走 dimcodedeepseek-v4-pro(DEEPSEEK_BASE_URL=https://dimcode.cn/v1)。 - 为把轨迹压进 token 上限,rollout 可加
--summarize-tool-response:每个 playwright 浏览器 工具结果在进入对话历史之前被 LLM 总结(保结构、保确切数值),"模型看到的 == 轨迹记录的", 保真无损失;仅对 playwright 生效,数据型 service 不动。详见src/agents/mcpmark_agent.py。
6. 环境
conda create -n mcpmark python=3.11 -y
conda run -n mcpmark pip install -e .
conda run -n mcpmark python -m playwright install chromium # B 类 oracle / 快照需要
@playwright/mcp@latest 由 npx 按需拉取(Node ≥ 18)。docker 站点镜像
(postmill / shopping / shopping_admin)需预先加载。