# OSWorld V2.1 是怎么造出来的，以及我们怎么造自己的训练环境

> 分析日期：2026-10-18。证据路径都相对 `evidence/`，行号已用脚本逐条核对。
> 标注约定：“已验证”指源码、文档或数据文件里能直接看到；“推断”指我根据证据做的判断。gated 任务只概括逻辑，不贴 gold 答案和隐藏参考值。

## 0. 结论

OSWorld V2.1 的难度主要来自人工造题，框架代码只占小头。108 个任务每个都是一个 Python 类，中位数 556 行，最长 4212 行，平均 722 行（已验证，`tasks-osworld-v2.1/task_*.py` 统计）。setup、资产、自建网站状态和逐项打分逻辑都写在这一个文件里。论文说约 90% 的任务由内部训练过的标注员端到端完成：从提题、造输入文件、布置环境到写评分函数，最后由第二名标注员交叉检查（`../fulltext.md:226-237`）。

框架层可以直接复用的部分有五个：`BaseTask` 和 `MultiPhaseTask` 接口、`SetupController`、`asset()` 资产解析、basesite 式的 cookie 隔离状态网站，以及 release manifest。最贵、最容易坏的环节是三处：一是 VM 镜像与任务 setup 的耦合（Python 版本、apt key、snap、内核模块）；二是 evaluator 的严格度，过严会误判正确解，过松会被 reward hacking；三是对外部实时服务的依赖。0808 到 v2.1 之间，108 题里有 68 题改了代码，其中 29 题改了 instruction 原文（已验证，AST 比对）。第三方复现 Sai 为让环境跑通，前后做了 8 次镜像构建（ref4 到 ref11）。

对“刷 OSWorld V2 但不过拟合”的建议如下。先按它的 7 个领域和 10 个挑战标签，自建可参数化的同类环境，环境用不同的应用实现、数据和网站品牌。奖励以“状态谓词 + 加权部分分 + 关键项门控”为主，LLM judge 只做少量客观 checklist。按应用和网站留出验证集，并用 OSWorld 以外的 benchmark 交叉验证。五个前沿运行的逐题分数显示，当前短板集中在三处：一是“做完最后 20%”，部分分 74% 到 87%，满分率只有 27% 到 46%；二是主动交互（ask_user）和教程跟随；三是法律合规、音视频制作、财务表格和 CAD/EDA 这几类专业产物（第 5 节）。

## 1. 架构与数据流

```text
        作者侧（一次性，人工为主）                          运行侧（每个 episode）
 ┌──────────────────────────────┐
 │ 提题：头脑风暴/访谈/问卷/LLM 种子 │
 │ 交叉检查 → 可行性/冗余/歧义     │
 └──────────────┬───────────────┘
                v
 ┌──────────────────────────────┐   gated HF: osworld_v2_tasks@tag
 │ task_NNN.py (BaseTask)        │──────────────────────────────┐
 │  instruction / snapshot / flags│                               │
 │  setup(SetupController)        │   gated HF: assets@tag         │
 │  evaluate(env) -> score/dict   │──── asset("task_NNN/...") ────┤
 │  get_phases()(多阶段，可选)     │                               │
 └──────────────┬───────────────┘   OSWorld-web@tag (Caddy+N 站)  │
                │ QA: 单测生成 → 双人做题 → 前沿 agent rollout     │
                v                                                 v
 ┌──────────────────────────────┐   ┌───────────────────────────────────────┐
 │ benchmark_releases/*.json     │   │ Host runner (lib_run_single.py)       │
 │ 钉 code/tasks/assets/web/镜像  │──>│ DesktopEnv.reset(task)                │
 │ + task_hashes.json            │   │  ├ provider: AWS AMI / Docker qcow2   │
 └──────────────────────────────┘   │  ├ revert（AWS 终止重开 / Docker 重启） │
                                     │  ├ task.setup(): 下载/执行/开窗口      │
                                     │  │   prepare_stateful_website_urls ──>│──┐
                                     │  └ sleep 60s → obs                    │  │
                                     │ loop ≤ max_steps:                     │  │
                                     │  agent.predict → env.step(pyautogui)  │  │
                                     │  空动作 = ask_user → user_simulator   │  │
                                     │  (可选) 第 150/300 步 checkpoint eval  │  │
                                     │ env.evaluate() → task.evaluate()      │  │
                                     │  ├ getters: vm_file / cloud_file /     │  │
                                     │  │  state_with_cookie(读网站状态) <────│──┘
                                     │  ├ 规则检查 + 少量 LLM 二值 checklist  │
                                     │  ├ safety_summary（多为 0 扣分诊断）   │
                                     │  └ EvaluationInfrastructureError → 不计分│
                                     │ result.txt / result.json / traj.jsonl │
                                     └───────────────────────────────────────┘
```
图：OSWorld V2.1 从作者造题到单次评分的数据流。

## 2. 分层拆解：每层是什么、谁负责、产出什么

| 层 | 负责人 | 产出 | 关键证据 |
|---|---|---|---|
| L1 提题与设计 | 内部标注员（约 90%）+ 访谈/问卷/LLM 种子 | 候选工作流、输入文件、期望终态 | `../fulltext.md:226-249` |
| L2 任务类编写 | 同一标注员 | `task_NNN.py` | `repository-v2.1/desktop_env/task_base.py:11-105` |
| L3 资产 | 标注员；发布者打 tag | gated 资产快照（1084 个文件）+ 公开镜像（362 个） | `repository-v2.1/desktop_env/file_source.py:40-92`，`repository-v2.1/benchmark_releases/osworld-v2.1.json:64-70` |
| L4 自建网站 | 网站复刻小组 | OSWorld-web：Caddy 反代加 22 个站点 | `websites-2026-09-11/OSWorld-web/README.md:1-40` |
| L5 镜像与 provider | 基础设施维护者 | AWS AMI、Docker qcow2 | `repository-v2.1/desktop_env/providers/aws/manager.py:51-66` |
| L6 setup 与 reset | 框架 + 任务作者 | 可重复的初始状态 | `repository-v2.1/desktop_env/desktop_env.py:306-418` |
| L7 运行循环 | 框架 | 轨迹、ask_user 记录、多阶段结果 | `repository-v2.1/lib_run_single.py:1491-1626` |
| L8 评分 | 任务作者 + 框架 | 部分分、安全摘要、infra 错误 | `repository-v2.1/desktop_env/desktop_env.py:594-704` |
| L9 QA | 双人交叉检查、coding agent 单测、前沿 agent rollout | 修订或删除 | `../fulltext.md:356-377` |
| L10 发布钉版本 | 发布维护者 | release manifest、任务 hash 清单 | `repository-v2.1/benchmark_releases/README.md:22-130` |
| L11 维护 | 维护者 + 第三方复现者 | v2.1 diff、镜像修复 | `v21-diffs/runtime.diff`，`frontier-2026-10-18/sai-osworld-v2.1.json:21-28` |

### L1 提题与设计

论文给了四个来源（已验证，`../fulltext.md:220-249`）：

| 来源 | 产出占比 | 作者评价 |
|---|---|---|
| 团队头脑风暴 + 专家式标注 | 约 90% | 主力。标注员先看 YouTube 教程、官方文档并上手软件，再从 Reddit、教程和自身工作中找工作流。 |
| 半结构化访谈（锚定招聘 JD 和 LLM 种子操作） | 小 | 质量高，难扩展 |
| 问卷 | 小 | 分发快，但回答者难以把握复杂度，留存少 |
| LLM 合成提案 | 小 | 有三个问题：输入文件不真实、工作流是拼接的浅操作、没预料到替代解法从而留下 reward hacking 风险。作者只把它当点子来源。 |

题目的硬约束有两条（`../fulltext.md:199-209`）。第一是长程：难度来自相互依赖的流程结构，不靠重复或拼接子任务。第二是真实：信息散在文件、应用、网站和历史记录里，不全写在 prompt 中。人类完成一题的中位时间约 1.6 小时（`../fulltext.md:154`）。

### L2 任务类：一个文件装下 setup 和 evaluate

`BaseTask` 是 dict 子类（已验证，`repository-v2.1/desktop_env/task_base.py:11-82`），字段包括 `snapshot`、`proxy`、`volume_size`、`user_simulator`、`disable_vnc`、`disable_recording`、`intermediate_eval_safe` 等。作者覆盖两个方法：`setup(setup_controller)` 用来布置环境，`evaluate(env)` 返回 float，或返回带 `score` 的 dict（`task_base.py:79-90`）。`MultiPhaseTask` 再加一个 `get_phases()`，每个阶段带自己的 setup、instruction、evaluate，可以设置 `gate` 或 `gate_min_score` 提前终止（`task_base.py:93-105`）。加载器按 `task_class/task_<id>.py` 查找，没找到再回退到旧 JSON（`repository-v2.1/task_loader.py:65-95`、`task_loader.py:149-167`）。

设计决策和对应的问题：
- 选 Python 类、弃用 JSON 配置。原因是 v2 的评分要解析 pptx XML、重放仿真、调 judge，JSON 的 `func/conj` 组合（`desktop_env.py:501-548`）表达不了。代价是每题都是一段要维护的代码（推断）。
- 任务代码放 gated HF 数据集，公开仓库不含。目的是防止被测 agent 在线搜到答案和评分细节（已验证，`repository-v2.1/evaluation_examples/task_class/README_v2.1.md:5-12`）。
- 运行时标志按题声明。在 108 题里，35 题设了 `intermediate_eval_safe = False`，18 题设了 `volume_size`（32 到 100 GB），4 题设了 `proxy = True`，只有 1 题（050）关了 VNC 和录屏（已验证，grep 统计；`tasks-osworld-v2.1/task_050.py:809-810`）。`intermediate_eval_safe=False` 的含义是 evaluate 有副作用，例如强制保存或杀掉应用（`tasks-osworld-v2.1/task_077.py:52-58`），因此 runner 会跳过中途 checkpoint 评分（`repository-v2.1/lib_run_single.py:160-171`）。
- 留实现说明。36 题附有 `implementation_notes/task_NNN.md`，记录“看起来像 bug 但属于故意”的细节，防止后来的维护者“修好”它（已验证，`tasks-osworld-v2.1/implementation_notes/README.md:1-13`）。

### L3 资产：gated 全量 + 公开最小镜像

`asset("task_055/x")` 按 `OSWORLD_FILE_BASE_URL` 拼出 URL 或本地路径。未设置时，默认指向公开数据集的某个固定 commit（已验证，`repository-v2.1/desktop_env/file_source.py:40-92`）。下载时本地路径直接拷贝；远端 URL 先按 uuid5 缓存，最多重试 10 次（`repository-v2.1/desktop_env/controllers/setup.py:148-200`）。release 声明 gated 资产 1084 个文件已逐字节校验，公开镜像 362 个文件只服务浏览器侧匿名访问（`benchmark_releases/osworld-v2.1.json:66-67`、`repository-v2.1/benchmark_releases/osworld-v2.1.json:79-86`）。108 题中有 99 题用到 `asset()`。

要解决的问题有两个：一是资产版本必须与任务版本一起钉住；二是浏览器里打开的文件需要匿名可访问，同时完整 gold 文件不公开。

### L4 自建网站：cookie 隔离的状态机

这是 V2 相对 V1 最有借鉴价值的部分（已验证）：
- 部署方式：Caddy docker proxy 把 `app.HOST_SUFFIX` 路由到各站容器，`gen-compose.sh` 自动汇总各站的 `web-compose.yml`（`websites-2026-09-11/OSWorld-web/README.md:3-20`，`gen-compose.sh:24-40`）。
- 状态契约：basesite 模板规定每个请求按 `user_id` cookie 取用户自己的那份状态（`basesite/constitution.md:5-10`）。`?cookie=` 查询参数可以钉住身份（`basesite/src/lib/cookies.ts:10-14`）。`GET/PUT/PATCH/DELETE /api/state` 只给 evaluator 和种子脚本使用，产品前端不得调用、不得暴露，也不得做改名代理（`basesite/constitution.md:12-24`，`basesite/README.md:7-11`）。
- 防作弊字段：每份状态必须有 `data.developer_tools_open`，前端检测到 DevTools 时通过专门接口置 true（`basesite/constitution.md:61-64`）。task_100 读到这个字段为 true 就直接判 0 分（`tasks-osworld-v2.1/task_100.py:208-215`）。
- 种子与读取：setup 先 `GET /api/state` 拿到 cookie，再 `PUT` 初始状态，然后把 `?cookie=<id>` 拼进 URL 交给 Chrome 打开，cookie 存到 cache 目录（`repository-v2.1/desktop_env/controllers/website.py:176-205`、`website.py:247-258`）。evaluate 时用这个 cookie 文件读回终态（`repository-v2.1/desktop_env/evaluators/getters/state.py:12-79`）。38 题在 setup 中布置了网站状态，27 题在评分时读回网站状态。
- 动态环境：MailHub 的种子状态可以带 `time_data`（延迟 N 秒到达的邮件）和 `action_data`（用户发出符合关键词的邮件后触发注入）。这两个字段在存储时被剥离，前端看不到（`websites-2026-09-11/OSWorld-web/mailhub_web/STATE.md:77-105`）。
- TLS：默认不校验证书，先探测 HTTPS，失败再回落 HTTP（`website.py:27-51`）。v2.1 新增 `OSWORLD_WEBSITE_TLS_VERIFY` 开关（`v21-diffs/runtime.diff:65-88`）。
- 容量：默认存储在内存中，TTL 12 小时，最多 1000 个用户、1 GiB（`basesite/src/lib/storage/memory-storage.ts:4-6`）。推断：用于大批量并行 RL 时需要调大这些上限或换持久化后端，否则旧 episode 的状态会被淘汰，容器重启也会丢状态。

用这种方式替代真实网站，解决了真实站点的版面漂移、反爬封锁和历史不可复现问题（`../fulltext.md:301-303`）。

### L5 镜像与 provider

AWS provider 用 AMI 映射表，注释里留下 13 个历史 AMI，说明镜像经常重做（已验证，`repository-v2.1/desktop_env/providers/aws/manager.py:51-66`）。reset 的做法是终止旧实例、从 AMI 新开一台（`providers/aws/provider.py:149-294`）。Docker provider 把 qcow2 以只读方式挂进固定 digest 的容器，reset 时直接停掉容器（`providers/docker/provider.py:136-147`、`provider.py:178-182`）；没有 `/dev/kvm` 时退化为软件模拟（`provider.py:128-135`）。`volume_size` 由 provider 在启动后用 growpart/resize2fs 扩盘（`providers/volume.py:131-270`）。

release 自己承认的限制（`benchmark_releases/osworld-v2.1.json:72-77`）：没有跑完整 108 题；Docker VM 没有启动过，AWS 与 Docker guest 是否等价没有验证；task029 的 setup 仍然有 120 秒超时。

### L6 setup 与 reset

`DesktopEnv.reset` 最多重试 5 次：环境用过就先 revert，然后检查控制服务就绪，再执行任务的 `setup()`（已验证，`repository-v2.1/desktop_env/desktop_env.py:306-408`）。在 setup 之前就标记 `is_environment_used=True`，所以 setup 中途失败也会触发下一次 revert（`desktop_env.py:346-349`）。`SetupController` 的 `execute` 在 v2.1 新增 `check=True`：命令返回非零就抛异常；还新增 `OSWORLD_STRICT_SETUP_TRANSPORT=1`，传输失败时不再静默继续（已验证，`controllers/setup.py:458-481`，`v21-diffs/runtime.diff:34-59`）。runner 在 reset 之后固定 `sleep 60` 秒（`lib_run_single.py:1521`）。

### L7 运行循环：ask_user、多阶段、动态

- ask_user 协议：agent 返回空动作时，runner 把它的文本当作向用户提问，交给 `env.user_simulator.respond()`；没有配置模拟器时返回固定的“没有更多信息”（已验证，`lib_run_single.py:17`、`lib_run_single.py:1535-1558`）。模拟器有三类：scripted（关键词匹配）、fixed（固定回答）、llm（只依据配置的知识回答，禁止编造）（`desktop_env/user_simulator.py:71-286`）。LLM 模拟器失败时直接抛错，不做兜底（`user_simulator.py:268-272`）。7 题配了模拟器。
- 多阶段：只有 task_069 使用 `MultiPhaseTask`，共 4 个阶段，权重 0.35/0.30/0.10/0.25，每个阶段的 `gate_min_score` 等于该阶段权重（已验证，`tasks-osworld-v2.1/task_069.py:2113-2165`）。runner 在阶段得分低于门槛时提前停止（`lib_run_single.py:831-842`）。推断：门槛等于权重，意味着某个阶段不拿满分就不进入下一阶段，长程误差不会被后续阶段掩盖。
- 动态环境：10 题带这个标签（`repository-v2.1/evaluation_examples/dynamic_environment.json`），机制是网站侧的定时或触发注入（见 L4）。

### L8 评分：规则为主，judge 为辅，部分分加门控

- 两条路径：任务覆盖了 `evaluate()` 就走自定义逻辑，否则走旧的 `func/result/expected/conj` 配置（已验证，`desktop_env.py:594-704`）。旧路径新增了 `conj: avg/sum` 和 `short_circuit=false`，用来支持细粒度部分分（`desktop_env.py:633-685`）。
- 部分分：论文称平均每题 27.25 个 checkpoint，按终态对所有 checkpoint 打分，不要求顺序（`../fulltext.md:336-343`）。典型写法是 task_008 的常量权重：表头、明细行、分摊、附件、提交分别占不同比例，提交本身只占很小一份（`tasks-osworld-v2.1/task_008.py:289-356`；实现说明 `tasks-osworld-v2.1/implementation_notes/task_008.md:1-15` 解释“保存未提交也给过程分”是故意设计）。
- binary：论文定义为部分分等于 1.00（`../fulltext.md:2419-2420`）。v2.1 在多题加入 `_normalize_full_score`，把 ≥0.999 的分数归为 1.0，因为浮点累加会得到 0.9999999999999999，导致满分被误判为非满分（`v21-diffs/task_053.diff:8-20`）。
- 门控与反作弊（已验证）：task_077 的 VLM checkpoint 先用确定性的文本和计数检查做门控，保证“没改的 deck 不会因为模型噪声得分”（`tasks-osworld-v2.1/implementation_notes/task_077.md:1-5`）。task_080 的产物与源文件语义相同就判 0（`tasks-osworld-v2.1/task_080.py:1725-1744`）。task_067 和 task_071 改动本应保持不变的内容会扣分（`implementation_notes/task_067.md`、`task_071.md`）。task_064 校验评分包的 sha256，在受限 UID 和网络命名空间里重放求解器（`tasks-osworld-v2.1/implementation_notes/task_064.md:1-36`，`task_064.py:46,243`）。
- LLM judge：统一经过 `model_client.generate_text`，判定只取第一个 token 是否为 YES（`evaluators/metrics/llm_metrics.py:43-139`）。20 题调用 judge，任务里写的 `default_model` 有 gpt-4o、gpt-4.1、gpt-5.2、gpt-5.4 四种（grep 统计），但这些值会被 `OSWORLD_EVAL_MODEL_*` 环境变量覆盖（`evaluators/model_client.py:157-186`）。官方 Claude 和 GPT runner 脚本都把 judge 设为 claude-sonnet-4-6（`scripts/bash/run_multienv_claude.sh:19-28`），Gemini 脚本默认用 gemini-3.5-flash（`scripts/bash/run_multienv_gemini.sh:30-35`）。论文报告 judge 占总分 11.53%，任何一题不超过 50%；4 个 judge 模型与人工的一致率都超过 93%，Sonnet 4.6 为 98.5%（`../fulltext.md:346-353`、`../fulltext.md:2163-2215`）。
- 可比性缺口（推断，有证据支撑）：release manifest 钉住了代码、任务、资产、网站和镜像，但没有钉 judge 模型和用户模拟器模型（`benchmark_releases/osworld-v2.1.json` 全文没有 judge 字段）。两家第三方都用 sonnet-4-6 作 judge（`frontier-2026-10-18/sai-osworld-v2.1.json:72-78`，`darwinx-args.json:21`），Sai 的 070 题曾因 judge 输出格式失败（`sai-ref-tags.json:62-65`）。
- 安全：8 类诊断检查（`../fulltext.md:2179-2200`），用 `record_safety_result` 写入 `safety_summary`，默认扣分为 0（`desktop_env/safety/__init__.py:40-75`）。17 题记录安全结果，真正扣分的只有 task_026：凭据泄漏扣 0.5（`tasks-osworld-v2.1/task_026.py:197-221`）。task_023 删除指定临时文件直接判 0（`implementation_notes/task_023.md`）。所以安全主要是并行报告的诊断，不进主分。
- infra 错误：v2.1 新增 `EvaluationInfrastructureError`，覆盖评分依赖失败的情况，例如浏览器探针失败、参考文件缺失、judge 连续无效（`evaluators/errors.py:12-37`）。8 题会抛出这个异常。runner 只做通用的异常捕获，不写 `result.txt`（`scripts/python/run_multienv_claude.py:648-672`），断点续跑时会清空这类目录并重跑（`run_multienv_claude.py:901-905`）。推断：这样基础设施故障不会被记成 0 分。对 RL 来说，这类 episode 应从 batch 中屏蔽，不能当负奖励。

### L9 QA

论文的 QA 分三段（已验证，`../fulltext.md:356-377`）：coding agent 先生成单测，覆盖评分 rubric 和预期解法；两名标注员各自端到端做题，交叉检查可解性、rubric 是否反映意图、权重是否均衡；多个前沿 agent rollout，找出 rubric 漏洞和作者没预料到的解法。审计有两个方向：reward hacking（通过文件、API、浏览器存储、项目元数据拿分）和 false negative（格式差异被判错）。输出空间有界时用模糊匹配或受约束的 judge，否则收紧 instruction 或删题。

### L10 release pinning

一个 release 要钉住 7 样东西：代码 tag、网站 tag 和 commit、任务数据集 tag 和 commit、gated 资产 tag、任务 hash 清单及其 sha256、各 provider 的镜像（AWS AMI；Docker 的 qcow2 sha256 和 runtime digest）、公开资产 commit（已验证，`benchmark_releases/osworld-v2.1.json:1-87`）。规则是 tag 不可变；修正必须发新 release，active manifest 只允许改文档性元数据（`benchmark_releases/README.md:76-82`、`README.md:113-125`）。runner 的完整性校验目前还是规划，README 写的是“later supports”（`README.md:90-111`）。只有 deepseek 的脚本读取了 manifest（`scripts/python/run_multienv_deepseek.py:234`）。推断：可比性目前靠运行者自觉记录，代码不强制。

## 3. OSWorld V2.1 的造题方式

### 3.1 难点怎么设计：10 个挑战标签

标签由作者逐题标注，可以多选，官方清单在 `repository-v2.1/evaluation_examples/<tag>.json`（已验证）。下表的“机制”一列是我从任务代码和实现说明中归纳的。

| 标签 | 题数 | 作者造难点的机制 | 证据 |
|---|---|---|---|
| 跨源推理 cross_source_reasoning | 46 | 证据分散在邮件、PDF、表格、网站、旧报告中，必须对齐 ID、日期、金额 | `../fulltext.md:527-529`，task_007 setup 同时下发 zip、PDF、MailHub 状态和本地网站（`task_007.py:38-91`） |
| 视觉空间精度 visual_spatial_precision | 45 | 坐标、像素、几何约束都有容差，例如 30 px 轮廓门槛、气泡尾巴方向 | `implementation_notes/task_063.md`，`sai-ref-tags.json:58-61`（059） |
| 隐式状态推断 implicit_state_inference | 43 | 关键状态不在 prompt 里，要从历史记录或环境中恢复 | `../fulltext.md:540-542` |
| 多项目状态跟踪 multi_item_state_tracking | 43 | 大量条目逐项计分，顺序无关匹配 | `implementation_notes/task_008.md:3-6` |
| 冲突消歧 conflict_disambiguation | 39 | 故意放入过期、矛盾、损坏的信息 | `implementation_notes/task_006.md`（损坏链接）、`task_080.md`（表格内部不一致）、`task_098.md`（预填错误字段） |
| 多模态编辑 multimodal_editing | 30 | 交付物是工程文件（.mlt、.RPP、.mscz、.pptx），评分解析结构，不只看渲染结果 | `implementation_notes/task_042.md`、`task_050.md` |
| 教程跟随 tutorial_following | 22 | 打开教程网页或文档，要求复现其中的关键技法，例如 Morph、透明辅助对象 | `implementation_notes/task_058.md`、`task_060.md`、`task_090.md` |
| 动态环境 dynamic_environment | 10 | 种子状态里预置定时邮件和触发邮件 | `websites-2026-09-11/OSWorld-web/mailhub_web/STATE.md:77-105` |
| 流式交互 streaming_interaction | 6 | 画面持续变化，例如移动弹窗、游戏 | `../fulltext.md:534-537` |
| 主动交互 human_in_the_loop | 6 | 关键信息只在模拟用户的知识里 | `user_simulator.py:137-276`，task_007 的 `user_simulator` 配置（`task_007.py:29-36`） |

另外有几种反复出现的出题手法（已验证，来自实现说明）：
- 故意降级输入。例如 deck 被抽掉阴影和图表缓存，要求“恢复”，不能当作损坏文件处理（`implementation_notes/task_079.md`、`task_096.md`）。
- 题面埋陷阱。例如公式里的变量是错的，正确做法要求识别并纠正（`implementation_notes/task_087.md`）。
- 唯一可行解靠细节才能发现。例如“买长乘短”加中转，要查车次详情页才能找到（`implementation_notes/task_065.md`）。
- 禁止捷径。打开 DevTools 判 0（`task_100.md`），删除不是自己创建的文件判 0（`task_023.md`）。
- 每次运行生成凭据实现隔离，例如 Overleaf、GitLab 账号按 run 生成（`implementation_notes/task_057.md`）。

### 3.2 部分分 rubric 怎么设计

归纳出的通用模式（已验证的例子见括号）：
1. 按交付物分块，给常量权重，块内按命中比例给分（task_008：`task_008.py:289-356`）。
2. 过程分和完成分分开。“保存但未提交”拿大部分分，提交只占很小一份（`tasks-osworld-v2.1/implementation_notes/task_008.md:13-15`）；也有题把提交设为硬要求（`task_098.md`）。
3. 主观项先用确定性检查门控，再交给 judge（`tasks-osworld-v2.1/implementation_notes/task_077.md`）。
4. 保护“本来正确的部分”，改动不该改的地方要扣分（task_067、task_071、task_076、task_098）。
5. 防止“原样提交”刷分：产物与源文件语义相同就判 0（`task_080.py:1744`）。
6. 硬失败项：违规就整题 0 分（task_023、task_100）。安全扣分单独记录（task_026）。
7. 分数归一：≥0.999 归为 1.0，结果夹到 [0,1]（task_053、task_015 的 diff）。

### 3.3 自建网站和多阶段怎么布置

38 题在 setup 中调用 `prepare_stateful_website_urls`。常见模式是“桌面文件 + 1 到 3 个网站状态 + Chrome 预开标签页”（task_007：`task_007.py:38-91`）。多站点时，`app` 和 `state` 以等长列表传入（`website.py:216-229`）。网站种子大多是 `asset()` 指向的 state.json，少数直接在任务代码里构造（task_069 在 Python 中拼出整套邮件和日历状态，`task_069.py:444-637`）。多阶段只有 task_069 一例：4 个阶段依次注入新状态和新指令，其中第 3 阶段是“什么都不该做”的 NO-OP 检查（`task_069.py:1977-1990`），用来测试 agent 会不会过度行动。

## 4. 造价与难点

### 4.1 量级

| 项 | 数字 | 来源 |
|---|---|---|
| 任务代码 | 合计 78011 行，中位 556 行/题 | 已验证，wc 统计 |
| 人类做题时间 | 中位约 1.6 小时 | `../fulltext.md:154` |
| 每题 checkpoint | 平均 27.25 个 | `../fulltext.md:343` |
| 自建网站 | 22 个站点（README 表）；生产版的子模块清单 22 个 | `websites-2026-09-11/OSWorld-web/README.md:24-48`，`websites-2026-09-11/OSWorld-web/scripts/validate-no-client-state.sh:6-29` |
| 第三方复现花费 | Sai 在 2026-09-23 05:00Z 到 09-24 10:50Z 约 30 小时窗口内花费 $2417.63、27662 次调用（含少量 24.04 重跑；README 称 134 次干净运行） | `frontier-2026-10-18/sai-osworld-v2.1.json:108-112` |
| 单题前沿 agent 成本 | Sonnet 4.6 约 $22.3/题（500 步） | `../fulltext.md:616` |

推断：按“写 500 行以上任务代码 + 造真实输入 + 布网站状态 + 双人做题（每人约 1.6 小时以上）+ 多 agent rollout + 修订”估算，一题从立项到稳定大约需要 1 到 3 人周。论文本身没有给每题工时，只说“扩展成本高”（`../fulltext.md:1143-1145`）。

### 4.2 最容易坏的环节（按证据强度排序）

1. 镜像漂移与任务 setup 耦合。Sai 的 22 个标记题里，8 题是 image-fix（`sai-ref-tags.json`）。具体例子：Python 3.12 装不上 mujoco 和 numpy（033、064），Google apt key 过期（064），没有真实的 snapd（093），内核缺 xt_owner（048），KiCad 版本不对（107、108），melt 不在 PATH 上导致渲染失败、被强制判 0（055、056，属于评分器缺陷）。Sai 为此连续做了 ref4 到 ref11 共 8 次构建（`sai-osworld-v2.1.json:21-28`）。在同 104 题上，参考 22.04 镜像得 0.7766，Ubuntu 24.04 得 0.7414（`sai-osworld-v2.1.json:103`）。镜像差异本身能带来约 3.5 个百分点的变化。
2. 评分器严格度。v2.1 的 68 个改动题里，按 diff 关键词粗分，约 57 题涉及容差和规范化，21 题涉及完整性和反作弊（推断：基于正则的粗分类，会重复计数）。代表例子：060 接受“Day 1”和“Day1”两种写法；001 改为按 RFC 5545 展开折行并处理时区（`v21-diffs/task_001.diff:24-40`）；020 补上“六个月期限”检查，修复漏检（`v21-diffs/task_020.diff:9-12`）；007 换成更正后的 gold（`v21-diffs/task_007.diff:9-10`）。
3. 外部实时依赖。027 调 Yahoo 数据被限流（429），agent 换了数据源，导致精确匹配失败（`sai-ref-tags.json:10-13`）。037 的评分在运行时实时查询 Semantic Scholar（`tasks-osworld-v2.1/task_037.py:89-91`）。081 托管的 Overleaf 状态与 UI 不一致。v2.1 新增一份 82 题的“无外网”清单（`v21-diffs/runtime.diff:2128-2133`）。
4. judge 与模拟器配置。092 原来在没有 `OPENAI_API_KEY` 时静默返回 0（`v21-diffs/task_092.diff:14-16`），v2.1 删掉了这个分支。070 增加了“无效 judge 输出重试 3 次，仍失败就抛 infra 错误”（`v21-diffs/task_070.diff:17`、`v21-diffs/task_070.diff:171`）。
5. 指令欠规范。29 题的 instruction 原文被改动（已验证，AST 比对），例如明确“只用这两个网站，不要搜索公网”（`v21-diffs/task_021.diff:12`），以及明确允许的格式差异（015）。
6. 第三方需要自己打补丁才能跑。Darwinx 在 108 题里有 92 题挂着 judge-clamp、insecure-origin 补丁，89 题挂 launch-fix，87 题挂 http-sites（已验证，解析 `darwinx-v21-results.json` 的 meta）。

## 5. 当前模型短板：哪些大类训练收益大

数据来自 `atlas/v21.json` 中的 5 个运行：Sai·Opus 5、Darwinx·Opus 4.8、GPT-6 Astra、Muse Spark 1.3、Muse Spark 1.2。领域归属取 `atlas/taxonomy.json` 的分析者单标签映射，不是官方逐题标签。“前三均值”指 Sai、Darwinx、Astra 三个运行的平均。口径警告：各运行的 harness、步数、judge 都不同（Sai 和 Darwinx 把 judge 换成 sonnet-4-6，Astra 只有 103 题），子类样本也很小，下表只能看方向。

按领域（部分分 % / 满分率 %）：

| 领域 | 题数 | 前三均值 | Muse 1.2（较弱模型） |
|---|---|---|---|
| 研究与教育 | 23 | 74.8 / 29.0 | 38.7 / 8.7 |
| 创意制作 | 27 | 73.6 / 42.4 | 44.6 / 11.1 |
| 工程与计算 | 17 | 87.0 / 46.0 | 41.1 / 11.8 |
| 行政与合规 | 14 | 73.6 / 28.6 | 37.3 / 15.4 |
| 个人服务 | 13 | 73.8 / 60.9 | 35.2 / 16.7 |
| 商业与金融 | 10 | 78.2 / 27.5 | 57.8 / 20.0 |
| 医疗健康 | 4 | 81.7 / 58.3 | 58.0 / 33.3 |

按挑战标签（前三均值，部分分 / 满分率；最后一列为 Muse 1.2 部分分）：

| 标签 | 题数 | 前三 | Muse 1.2 |
|---|---|---|---|
| 主动交互 | 6 | 54.6 / 16.7 | 26.4 |
| 教程跟随 | 22 | 66.7 / 24.6 | 19.1 |
| 冲突消歧 | 39 | 73.8 / 36.7 | 37.0 |
| 多模态编辑 | 30 | 75.5 / 43.3 | 41.5 |
| 动态环境 | 10 | 75.6 / 41.5 | 26.9 |
| 跨源推理 | 46 | 77.2 / 30.8 | 44.6 |
| 视觉空间精度 | 45 | 77.5 / 42.8 | 43.9 |
| 多项目状态跟踪 | 43 | 78.0 / 36.4 | 41.7 |
| 隐式状态推断 | 43 | 80.1 / 45.3 | 44.6 |
| 流式交互 | 6 | 83.3 / 72.2 | 50.0 |

子类层面，前三均值部分分最低的是法律与合规 57.2、音频制作 60.3、视频制作 65.9、教学与课程 72.1；满分率最低的是音频 13.3、市场与财务 16.7、CAD/EDA 17.8、法律与合规 20.0。

我的判断（推断）：
1. 前沿模型的主要差距在于做不完，不在于不会做。部分分 74% 到 87%，满分率只有 27% 到 46%。训练任务应该奖励“全部 checkpoint 满足”，并加入自检行为。可以调高门控项和满分奖励的权重。StateAct 报告的 finish gate 约 90% 错放行，说明靠 prompt 自检不够，奖励要直接作用在终态上。
2. 对比前沿模型更弱的自训模型，教程跟随、动态环境、主动交互掉得最多（Muse 1.2 在这三项只有 19 到 27），优先级应该最高。
3. 专业产物类（法律合规表单、音视频工程文件、财务表格、CAD/EDA）满分率低。可以批量造这类题，因为产物文件可以被程序精确校验，verifier 成本低。

## 6. 按大类的造题配方

原则：每个大类用开源应用或我们自己写的网站造同类环境。任务由“世界规格（world spec）”程序化生成，同一份 spec 同时产出初始状态、instruction 和期望终态谓词。LLM 只负责改写题面和提出变体，每个变体都要过执行验证：用脚本化的参考解跑通并拿满分，空操作和常见错误解拿低分。

| 领域 | OSWorld 考什么 | 典型题号 | 我们的环境来源 | 批量生成 | verifier | 优先级 |
|---|---|---|---|---|---|---|
| 研究与教育 | 文献检索与管理、LaTeX 写作、绘图拟合、课程规划、教学课件技法 | 002 007 009 015 030 037 057 059 072 086 087 090 093 097 | Zotero/JabRef、LibreOffice、LabPlot/Veusz、自建 Overleaf CE、Moodle（框架已有 `controllers/moodle.py`）、自建课程目录站、离线论文元数据库 | 合成论文元数据和引用图；课程先修图加学分约束由程序生成并求解；教程技法按“技法 × 内容”组合生成 | 解析 .bib/.tex/.docx/.xlsx；编译 LaTeX；约束求解器验证排课；不调用实时 API | 高 |
| 创意制作 | 幻灯片 Morph/动画/版式、视频剪辑字幕、音频混音与乐谱、图片编辑 | 003 042 049 050 055 056 058 060 063 066 067 071 079 084 085 092 095 | LibreOffice Impress、Kdenlive/Shotcut（MLT）、Audacity/Ardour、MuseScore、GIMP/Inkscape/Krita | 对已有工程文件做程序化降级（删阴影、清空图表缓存、打乱轨道），要求恢复；参数化编辑指令（时间码、位置、效果参数） | 解析工程 XML（.mlt、.RPP、.mscz、pptx）；ffprobe 和逐帧 SSIM 对比参考渲染并设容差；VLM checklist 先经结构门控 | 高（音视频），中（演示文稿） |
| 工程与计算 | 环境修复、测试、网站实现、云账单和安全、CAD 重建、EDA 修复、机器人仿真 | 023 029 041 070 074 078 082 089 094 103 104 107 108 | VS Code + 合成仓库、LocalStack 或自写 AWS 控制台 mock、FreeCAD/OpenSCAD、KiCad、MuJoCo | 对仓库做依赖破坏或 bug 注入（SWE 风格）；CAD 由参数化零件生成三视图；KiCad 由网表生成待修复原理图 | 跑测试；KiCad 网表连通性；几何体积和包围盒加容差；仿真重放 | 中（CAD/EDA 满分率低但造价高） |
| 行政与合规 | 报销、招聘、会议排程、签证和法律表单、政策研究 | 001 006 008 010 011 016 018 024 025 043 069 088 098 102 | 基于 basesite 契约自写的表单、报销和 HR 站；Thunderbird + Evolution；Odoo/ERPNext 等开源 ERP | 用 persona 世界生成器产出人物档案、邮件、票据、政策文档，故意埋冲突和过期信息，期望终态由程序计算 | 状态谓词；顺序无关的逐项匹配；只评“与初始状态不同的字段”，同时检查原本正确的字段没有被改 | 高 |
| 个人服务 | 票务、出行、套餐、路线、游戏与视觉搜索 | 013 014 017 020 021 048 052 065 068 099 100 101 | 自写订票、套餐站（数据由时刻表生成器生成）；OSM + OSRM 离线路由；开源网页游戏 | 约束满足问题生成器（预算、时间窗、换乘），用求解器确认可行解集合，非唯一解时列出全部可行解 | 预订状态谓词加可接受解集合；游戏读后端状态；DevTools 标志判 0 | 中 |
| 商业与金融 | 表格建模、对账、图表、CRM、贷款采购 | 022 027 035 038 040 077 079 080 091 096 | LibreOffice Calc、自写 CRM 和银行站、离线行情快照 | 合成账本并注入不一致；要求保留结构、写公式 | openpyxl 检查公式存在，LibreOffice headless 重算后比较数值；检查图表对象存在；与源文件相同判 0 | 高 |
| 医疗健康 | 影像质控、保险理赔、疫苗记录 | 005 028 105 106 | 3D Slicer + 公开小样本影像；自写理赔站 | 参数化分割和标注任务；理赔表单由 persona 生成 | Dice 系数阈值；DICOM 标签；状态谓词 | 低（占比 3.7%） |

跨领域的标签配方（对应 JSON 中带“标签”前缀的条目）：
- 主动交互：world spec 把 1 到 2 个关键字段只放进模拟用户的知识里。verifier 同时检查“问了”和“用对了”。另造对照题：信息在环境里能找到，这时提问应扣分，防止 agent 学成滥问。模拟用户用我们自己的 LLM 加知识约束，复用 `LLMUserSimulator` 的提示结构（`user_simulator.py:204-222`）。
- 教程跟随：教程页由技法库生成（例如 Morph、透明辅助对象、FFT 计数），verifier 检查技法的结构证据，不只看外观（参照 `task_058.md`、`task_090.md` 的思路）。
- 动态环境：在自写网站中实现 `time_data/action_data` 等价机制，期望终态必须依赖后到的信息，确保忽略新邮件的 agent 拿不到满分。
- 流式交互和视觉精度：移动弹窗、实时画布；verifier 读后端坐标，给像素容差。

## 7. 防过拟合

### 7.1 拟合与迁移的边界

| 属于拟合 OSWorld 本身（禁止或严格限制） | 属于能力迁移（鼓励） |
|---|---|
| 用 gated `task_*.py`、gold、资产或其哈希可识别的文件训练 | 用不同应用完成同一类产物（Kdenlive 换 Shotcut，Calc 换 WPS） |
| 用 OSWorld-web 的站点（MailHub、TeamChat 等）、同名品牌或同一 state schema 作为训练环境 | 自写不同 UI、不同 schema 的同类站，只遵守 basesite 的契约思想 |
| 复用或改写 108 道题的题面模板、人物、公司名 | 题面由我们的 world spec 和多种措辞生成 |
| 迎合评分器细节，例如强制保存时机、具体容差（30 px、0.999）、字符串格式 | 奖励“完成且自检”的通用行为 |
| 用公开的 OSWorld 轨迹库训练（Sai 参考运行、官方轨迹库） | 用自己环境里的 teacher rollout |

### 7.2 红线

1. 训练数据管线物理隔离 `evidence/tasks-osworld-v2.1/`、gated 资产和所有 OSWorld 轨迹数据集。
2. 训练环境不部署 OSWorld-web 的任何站点。如果需要参考它的契约，只借鉴 basesite 的设计原则（cookie 隔离、隐藏的控制面），不复制代码和数据。
3. 不按 OSWorld 的单题失败反推单题训练数据。只允许按大类和标签补数据。
4. OSWorld V2 只在里程碑上评测，每次评测都登记，避免把测试集当开发集反复调参。

### 7.3 held-out 设计

- 应用留出：每个领域至少留 1 个应用不进训练，例如训练用 Kdenlive、留出 Shotcut；训练用 Calc、留出 WPS。
- 网站留出：自写站点中，每类留 1 个实现（例如第二套邮件站）只用于验证。
- 领域留出：每轮训练轮换留出一个领域，测跨领域迁移。
- 外部交叉验证：OSWorld-Verified（V1）、Windows/Web 类 benchmark、MyPCBench 或 Agents' Last Exam 一类长程 benchmark（论文把这两个列为最接近的对照，`../fulltext.md:549-552`）。要求 OSWorld V2 上的涨幅在至少一个外部 benchmark 上同向出现。
- 内部 dev 代理集：从我们自己的配方里抽 100 到 200 题，按 OSWorld 标签分布配比，作为日常开发集。

### 7.4 污染检查

1. 题面相似度：把训练题和 108 道公开 instruction（Darwinx 的 meta 里有原文）做 embedding 和 n-gram 比对，超过阈值的题删除。
2. 实体检查：人物名、公司名、站点名、host 后缀做黑名单匹配。
3. 文件哈希：训练资产的 sha256 与 OSWorld 资产清单比对。
4. 轨迹来源审计：每条训练轨迹必须能追溯到我们自己的环境和 run id。
5. 评分器细节检查：训练 verifier 代码不得引用 OSWorld 任务的常量和阈值，代码评审时核对。

## 8. 可执行方案

### 8.1 方案 A：自建 benchmark（最小可行版）

- 组件：复用 OSWorld-V2 的 `DesktopEnv`、`SetupController`、`BaseTask`、`asset()`、runner、release manifest 格式；自写 3 到 5 个 basesite 契约网站；任务 30 到 50 道，覆盖 4 个领域和至少 6 个标签。
- 直接复用：`desktop_env/`、`lib_run_single.py`、`benchmark_releases/` 的 manifest 结构、`implementation_notes` 的写法、`safety/` 诊断。
- 要改：在 manifest 里加入 judge 模型和用户模拟器模型；runner 强制执行完整性校验（README 里规划了但没实现）；把 `EvaluationInfrastructureError` 显式写入 result.json；镜像构建脚本化（参考 Sai 的 Dockerfile 历史）。
- 人力和时间（推断）：3 到 4 人，2 到 3 个月；每题 1 到 3 人周，含双人做题和 rollout 审计。
- 最先验证的风险：镜像可复现性（同一题在两次构建上分数一致）、judge 一致率、指令欠规范率（用 2 个以上前沿 agent rollout 统计 false negative）。

### 8.2 方案 B：在线 RL 训练环境（与第 6 节配方对齐）

```text
world spec 生成器（按领域配方）
   ├─> 初始文件（参数化 docx/xlsx/pptx/mlt…）
   ├─> 网站种子状态（PUT /api/state，cookie=episode_id）
   ├─> instruction（模板 + LLM 改写，多种措辞）
   └─> 期望终态谓词 + 加权 checkpoint + 门控
            │ 准入：参考解满分；空操作 ≤ 阈值；常见错误解低分
            v
VM 池（COW 快照，秒级 reset）── agent rollout ── 读回状态和文件 ── 奖励
            │                                         │
            └── infra 错误 → 屏蔽该 episode ←────────┘
```
图：RL 环境中一道生成任务从规格到奖励的流程。

- MVP 组件：
  1. VM 池：复用 Docker provider 的“只读基础盘 + 可写层”思路，改为 microVM 或 qcow2 overlay，做秒级 reset，去掉 runner 里固定的 60 秒等待，改成就绪探针（Sai 的做法是等待 `systemctl is-system-running` 再截第一张图，`sai-osworld-v2.1.json:32-40`）。
  2. 网站：按 basesite 契约自写邮件、聊天、银行、订票、表单、CRM 6 个站，品牌和 UI 与 OSWorld-web 不同，存储层调大容量或换 Redis。
  3. 生成器：每个领域一个 world spec 生成器，先做高优先级的 4 类（研究与教育、创意制作中的音视频、行政与合规、商业与金融）。
  4. verifier 库：状态谓词、文件解析器（docx/xlsx/pptx/mlt/RPP/mscz/kicad）、门控、满分归一；judge 只用于客观 checklist，占比不超过 15%。
  5. 用户模拟器：LLM 加知识约束，按 episode 固定随机种子。
  6. 课程与筛选：按通过率维护 active 和 monitoring 题池（参考 Qwen-UI-Agent 的做法），去掉全对和全错的组。
- 可直接复用 OSWorld-V2 的部分：`DesktopEnv` 的 step/obs 接口、`SetupController` 的执行和下载、`website.py` 的种子流程、`getters/state.py` 的读回、`user_simulator.py`、`safety/` 检查器（可以作为惩罚项）。
- 要改的部分：reset 速度；并发下的网站容量；infra 错误进入 RL 时屏蔽，不记 0 分；judge 的确定性（固定模型、温度和重试策略）；评分无副作用化，让 35 类“评分有副作用”的题型也能在中途给密集奖励。
- 人力和时间（推断）：4 到 6 名工程师，2 到 3 个月做出 4 个领域的 MVP，每个领域 200 到 1000 个可执行变体。
- 最先验证的风险：
  1. 每节点每小时能跑多少 episode（reset 加 setup 时间）。
  2. verifier 的 reward hacking：用一个专门找漏洞的 agent 攻击 verifier，统计误放行率。
  3. 生成多样性：题面和状态的去重率，参考 Fara 的 coverage tracker。
  4. 迁移：留出应用和外部 benchmark 上是否同向提升。

### 8.3 路线对比

| 路线 | 例子 | 适合 | 局限 |
|---|---|---|---|
| 人工精造任务 | OSWorld V2：标注员端到端写代码，双人 QA | 评测集、少量高价值训练种子、长程专业流程 | 一题 1 到 3 人周（推断），扩展慢 |
| coding agent 克隆沙箱 + 受控采样 | Fara 1.5 FaraEnvs；playbook 记忆中的七维采样和 DB 谓词 | 网站类和表单类大规模 RL，奖励可执行 | 只覆盖 web，桌面专业软件难克隆；首轮实现残缺，要 3 到 5 轮人审 |
| 真机或真实 runtime | Qwen-UI-Agent：100 多台物理手机，虚拟屏让吞吐提升约 20 倍 | 真实弹窗、登录、控件分布 | 结果监督难，依赖自家 AutoJudge；可复现性差 |
| 真实网站 + VLM judge | OpenWebRL：live web，GPT-4.1 judge | 开放网页任务的广度 | 51% 失败来自站点封锁等 infra；judge 有成本和噪声 |
| 语言世界模型模拟 | Qwen AgentWorld | 极便宜的文本环境、虚构世界 | 无像素观测；模拟器有讨好倾向 |

推断：针对 OSWorld V2，宜用“人工精造少量种子（每个领域 5 到 10 道，作为 world spec 模板和验收基准）+ 程序化参数生成 + 桌面开源应用”作为主路线，网站部分借鉴 Fara 的 coding agent 克隆法。真机和世界模型路线与 OSWorld 的 Linux 桌面差距较大，优先级低。

## 9. v2.1 维护教训（给我们自己维护环境用）

| 教训 | 例子（题号） | 证据 |
|---|---|---|
| 浮点累加让满分变非满分 | 053、015、024、041、051、057、085 | `v21-diffs/task_053.diff:8-20` |
| 指令欠规范，导致正确解被判错 | 29 题改 instruction，例如 021、060、015 | `v21-diffs/task_021.diff:12`，`v21-diffs/task_060.diff:8-12` |
| 评分过松被钻空子 | 020 补期限检查；038 加完整性错误列表 | `v21-diffs/task_020.diff:9-12`，`v21-diffs/task_038.diff:417-565` |
| gold 本身有错 | 007 | `v21-diffs/task_007.diff:9-10` |
| setup 静默失败 | 全局 `check=True`、严格传输模式；108 离线包；093 snap 安装 | `v21-diffs/runtime.diff:34-59`，`v21-diffs/task_108.diff:66-86`，`v21-diffs/task_093.diff:83-91` |
| infra 失败被记成 0 分 | 新增 `EvaluationInfrastructureError`（8 题） | `repository-v2.1/desktop_env/evaluators/errors.py:12-37` |
| judge 缺 key 时静默给 0 | 092 删除静默分支；070 重试无效输出 | `v21-diffs/task_092.diff:14-16`，`v21-diffs/task_070.diff:17` |
| 外部实时依赖 | 027、037、081；新增 82 题离线清单 | `sai-ref-tags.json:10-13`，`v21-diffs/runtime.diff:2128-2133` |
| 镜像差异改变分数 | ref4 到 ref11；22.04 与 24.04 相差约 3.5 点 | `sai-osworld-v2.1.json:21-28,103` |
| 评分器依赖镜像里的二进制 | 055、056 的 melt 路径 | `sai-ref-tags.json:82-101`，`v21-diffs/task_056.diff:257-258` |

## 10. 开放问题

1. 论文没有给每题工时和 QA 轮数，第 4.1 节的人周数字是推断，需要向作者确认，或在我们自己的试点中实测。
2. release 没钉 judge 和用户模拟器模型。官方榜单具体用哪个 judge，只在论文里写为 Sonnet 4.6（`../fulltext.md:598-601`），而 v2.1 运行是否一致还没有确认。
3. guest 侧控制服务器是子模块，本地是空目录，无法确认 reset 后服务就绪的真实耗时。
4. 自建网站的生产版是否真的移除了 `/state-manage` 和浏览器端的 state 调用，需要用 `scripts/verify-browser-no-state.mjs` 实测。
5. 分类映射是分析者单标签，小类样本只有 1 到 12 题，第 5 节的短板判断应当用我们自己的 dev 代理集复核。
