当前状态
当前版本已经把 inputs.jsonl 和 gold.jsonl
分开:模型预测时只允许读 input 和 visible graph;评测时 evaluator 才读取 gold。
整体数据流
数据源与 Intent 类型
每条原始 trajectory 被统一成一个 Episode。闭域 intent
用于分类;开域 intent 是完整自然语言目标,后续用 LLM judge 或相似度评测。
| 数据源 | open intent | closed intent | 闭域标签空间 | 当前注意点 |
|---|---|---|---|---|
WebLINX |
从 instructor utterance 抽取完整用户指令 | 从首个 URL host 派生网站域名 | 102 labels weblinx.derived_website |
可见 utterance 可能天然包含完整指令,后续需要 no-utterance ablation |
Mind2Web |
confirmed_task |
domain |
3 labels mind2web.domain |
metadata 已去掉 domain/subdomain,避免闭域标签泄漏 |
GUI-Odyssey |
instruction 或 task |
category |
6 labels gui_odyssey.category |
metadata 已去掉 category/meta_task |
FingerTip CSV |
intentDescription |
intentClass |
42 labels fingertip_csv.intentClass |
当前只用 repo CSV;完整动作轨迹需要 Kaggle token 后补齐 |
Prefix 切分逻辑
每条 trajectory 都按同一个 requested grid 生成 task:
10%, 20%, 30%, 40%, 50%, 60%, 70%, 80%, 90%, 100%。
由于 step 是离散的,实际前缀步数用向上取整。
prefix_step_count = min(total_steps, max(1, ceil(requested_prefix_ratio * total_steps)))
effective_prefix_ratio = prefix_step_count / total_steps
为什么保留 requested ratio
AUC 需要所有样本在同一 x 轴上比较,所以默认用 requested ratio
0.1 ... 1.0 积分。这样不同长度 trajectory 可以直接聚合。
小于 10 步怎么办
多个 requested ratio 可能映射到同一个 step count。prototype 不删除这些点,
而是保留并标记 is_duplicate_prefix=true,便于主实验对齐 AUC,
ablation 时也可以按 unique prefix step collapse。
Graph 构造逻辑
graph 的目标是把 prefix observation 变成更适合 graph method 的结构化输入。 当前图是轻量 schema:节点表示 episode、可见 metadata、app/profile、prefix step 和 action;边表示归属、时序和局部关系。
节点类型
episode:一条 trajectory 的根节点。
metadata:数据源、网站、设备、场景等非答案字段。
app / profile_attribute:GUI-Odyssey app 序列、FingerTip 用户画像。
step / action:prefix 中每一步及其动作文本。
边类型
observed_prefix_step:episode 到可见 step。
contains_action:step 到 action。
next_step:prefix 内部的时间顺序。
uses_app、has_profile_attribute:metadata 关系。
可见图原则
生成时内部会先构造带 hidden target 的完整图,然后通过
build_visible_graph 删除所有 hidden target 节点和边。
当前落盘的 visible_graphs/*.json 中:
hidden_nodes = 0
intent_nodes = 0
防泄漏文件拆分
现在的 benchmark 文件分为模型可见和 evaluator-only 两组。真实方法只能读左边, 评测脚本才读右边。
模型可见
data/prototype_prefix_graph/inputs.jsonl
每行一个 prefix task,只包含 metadata、observed_steps、visible graph path、prediction contract。
data/prototype_prefix_graph/tasks.jsonl
兼容别名,内容等同 input-only task,不含 target。
data/prototype_prefix_graph/visible_graphs/*.json
graph method 的结构化输入,不包含 intent target 节点。
data/prototype_prefix_graph/label_spaces.json
闭域分类标签空间;只列出候选 label,不给当前样本答案。
Evaluator-only
data/prototype_prefix_graph/gold.jsonl
每行一个 gold record,包含 open_intent、closed_intent、intent_modes 和 metrics。
data/prototype_prefix_graph/evaluation_spec.json
定义数据隔离规则、预测格式、AUC、area gain、TTC 等指标。
规则很简单:predictor 不能读 gold.jsonl,也不能读任何名为
target 的字段。否则 AUC 会变成答案泄漏,而不是 early awareness。
Spec wording: Predictors must not read gold.jsonl or any field named target.
评测逻辑
当前 evaluator 读预测 JSONL 和 gold.jsonl,按
requested_prefix_ratio 聚合每个 prefix 点的表现,然后计算 early 指标。
闭域 intent:分类
对于 closed.available=true 的 task,预测必须给出
closed_intent,且应来自对应 label space。
Acc(r) = correct predictions at prefix r / tasks at prefix r
AUC = trapezoid_integral(Acc(r), r = 0.1 ... 1.0)
normalized_AUC = AUC / (1.0 - 0.1)
另算 macro_f1 和 ttc_stable。TTC 是某条 episode
第一次预测正确且之后一直正确的最早 ratio。
开域 intent:生成 / Judge
对于 open intent,模型输出自然语言 predicted_intent。实际评测时可用
LLM judge 或 embedding similarity 给 0..1 分。当前 evaluator
接收已经算好的 open_judge_score。
OpenScore(r) = mean judge score at prefix r
AUC_open = trapezoid_integral(OpenScore(r), r = 0.1 ... 1.0)
area_gain = AUC(method) - AUC(baseline)
open 的稳定识别点可以定义为 judge score 超过阈值且后续保持超过阈值的最早 ratio。
预测文件格式
{"task_id":"weblinx:cptbbef:r0.10","method":"graph_method","closed_intent":"www.momondo.in","closed_confidence":0.74,"predicted_intent":"search one-way flights from Azerbaijan to Turkey","open_judge_score":0.82}
运行 evaluator
python src/evaluate_prefix_predictions.py --predictions path/to/predictions.jsonl
python src/evaluate_prefix_predictions.py --oracle
--oracle 只用于 sanity check,会从 gold 复制答案,所以 normalized AUC
等于 1.0;这不代表真实方法效果。
代码入口与关键函数
| 文件 / 函数 | 职责 |
|---|---|
src/prototype_prefix_graph.py |
主生成器。读取本地数据,生成 input/gold/visible graph/label space/evaluation spec。 |
load_weblinx / load_mind2web / load_gui_odyssey / load_fingertip |
把不同数据源标准化成统一 Episode 结构。 |
build_graph |
把 episode prefix 转成完整 graph,其中 target intent 被标记为 hidden。 |
build_visible_graph |
删除 hidden target 节点和边,生成模型可见 graph。 |
build_input_record |
生成模型可见 task 行,包含 observed prefix 和 graph path,不含答案。 |
build_gold_record |
生成 evaluator-only gold 行,包含 open/closed target 和 metrics 定义。 |
src/evaluate_prefix_predictions.py |
读取 predictions 与 gold,计算 prefix 点指标、AUC、normalized AUC、TTC、area gain。 |
重新生成 prototype
python src/prototype_prefix_graph.py
python src/prototype_prefix_graph.py --limit-per-dataset 50
限制与下一步
1. WebLINX utterance 太强
WebLINX 的可见 utterance 可能已经包含完整用户指令。这不是
gold.jsonl 泄漏,但会让 early intent 任务偏简单。
建议加 no_utterance 或 no_initial_instruction 版本。
2. FingerTip 轨迹不完整
当前 FingerTip 使用 CSV 中的 action length 构造占位 step。要做严肃 benchmark, 需要 Kaggle token 下载完整 episode/action。
3. 现在是小样本 prototype
当前只取每个数据源 2 条 episode。下一步应扩大到 train/dev/test split, 并加入 baseline、graph method 和 open-intent judge pipeline。
推荐下一步实验矩阵:full context、no utterance、actions only、visible graph only、 graph + text hybrid。比较每个设置下的 closed AUC、open AUC、area gain 和 TTC。