1. 面试开场怎么讲
30 秒版本
这个项目解决的是 GUI agent demo 很难复盘的问题:最终失败时,我们不知道是页面没打开、 browser target 绑错了、证据没抓到,还是模型真的不会操作某个控件。我搭了一个本地确定性浏览器 benchmark,并围绕 UI-TARS 做了 preflight 修复、capture、judge、step trace 和 failure taxonomy。 最终它能把一次 agent run 变成可审计 artifact,而不是口头描述。
2 分钟版本
- 背景:GUI agent 的评测很容易停留在“成功/失败”,但工程上更需要知道失败层级: 环境、目标页、证据采集、最终状态,还是具体交互 primitive。
- 方法:我把 benchmark app、task registry、deterministic judge、run recorder、 UI-TARS integration、CDP preflight、capture bundle、step trace、failure taxonomy 和 finish gate 分层组织,每层都有 schema 和验证脚本。
- 结果:扩展到 10 个任务后,全部任务都有 capture bundle,finish gate 显示 local 和 integration 都 ready;但 UI-TARS 没有 full success,说明问题不在“没有证据”,而在交互执行质量。
- 价值:面向 agent reliability,它提供的是 failure analysis workspace,可以指导后续 model/operator 改进,也能避免把环境错误误判成模型能力问题。
2. 项目要解决的问题
GUI agent 看似简单:给模型一个浏览器任务,让它点击、输入、提交,然后看结果。但真正做 benchmark 时会遇到三类混在一起的问题。
环境问题
模型服务、隧道、UI-TARS 本地配置、Chrome 子进程、CDP 端点都可能出错。
P0/P1 风险 不能直接算模型失败目标页问题
UI-TARS 可能看着 Google、空 tab、错误 task、多个 benchmark tab 或 Chrome error page。
target binding preflight repair交互能力问题
页面正确时,agent 仍可能无法提交 dropdown、表格选择、modal 确认、分页和复杂表单。
primitive failure taxonomy3. 组织架构:代码和职责怎么分
项目采用轻量但很清晰的分层:浏览器任务和 judge 是 deterministic core;UI-TARS/CDP 相关代码是 integration layer;实验、报告、taxonomy、finish gate 是 evidence layer;scripts 把这些层串成 可重复运行的命令。
public/本地浏览器 app,10 个任务,暴露
window.__BENCH__。
src/state.mjssrc/judge.mjs确定性状态和评分。
src/runs.mjssrc/trace-importer.mjs记录、导入、导出 run。
src/uitars-*.mjspreflight、capture、real round、raw trace。
docs/experiments/artifacts/报告、taxonomy、finish gate。
目录视角
| 目录 | 职责 | 面试讲法 |
|---|---|---|
public/ |
浏览器 benchmark UI、任务入口、可操作控件、tasks.json。 |
“我没有依赖真实网站,因为我需要可重复 judge 和可控状态。” |
src/state.mjs / src/judge.mjs |
定义初始状态、可见数据、每个 task 的 deterministic success criteria。 | “judge 不看截图主观判断,只看状态是否满足 criteria。” |
src/runs.mjs / src/trace-importer.mjs |
把用户/agent 操作记录成 run schema,并支持外部 trace 导入。 | “run export 是模型无关格式,避免把 benchmark 绑死在某个工具日志上。” |
src/uitars-preflight.mjs |
发现 UI-TARS child Chrome、检查 CDP、识别 benchmark/search/error target、创建/导航/激活 tab。 | “这是我花最多工程判断的部分,因为 target 绑错会污染所有后续结论。” |
src/uitars-capture.mjs / src/uitars-real-round.mjs |
从正确 benchmark target 里抓 final state 和 evaluation,汇总真实 round。 | “每个 task 都要有 capture、trace、run-export,不能只说跑过。” |
src/oracle-baseline.mjs |
用 scripted UI actions 验证所有任务通过 UI path 可解。 | “它不是 agent score,而是证明任务和 judge 不是坏的。” |
docs/ / experiments/ / artifacts/ |
报告、schema、failure taxonomy、实验 artifact、finish gate。 | “项目产出不是一个 demo,而是一组可复核证据。” |
scripts/ |
所有 validator、harness runner、health check、smoke check。 | “用命令把质量门槛固定下来,减少口头状态。” |
核心数据流
4. Benchmark 覆盖了哪些 GUI primitive
任务不是随便堆出来的,而是覆盖了企业应用里常见且容易让 GUI agent 失手的操作类型。 每个任务都有明确的初始状态和可机器判断的成功标准。
| 任务 | 目标 primitive | 为什么有价值 |
|---|---|---|
onboarding-form | 多字段表单输入和 submit | 测试文本输入连续性、select、日期、最终提交。 |
catalog-filter | 搜索、过滤、列表选择 | 测试 agent 能否把“找到目标”变成 committed selection。 |
settings-toggle | checkbox + dropdown | 拆分简单 toggle 和 select value commit 的差异。 |
ticket-review | 表格搜索、行选择、review commit | 接近实际后台系统里的 queue review。 |
modal-confirmation | 打开 dialog 并确认 | 测试跨 UI state 的两步确认流程。 |
pagination-review | 分页导航和行操作 | 测试 agent 是否能先切换页面再操作目标项。 |
sortable-inventory | 排序和目标选择 | 测试“排序改变表格状态”后再选择。 |
multi-select-approvals | 多选集合和 submit | 测试 precise set selection,不能多选或少选。 |
validation-error-recovery | 先触发 validation,再修复表单 | 测试从错误状态恢复到成功提交。 |
file-upload-request | 文件选择、dropdown、description、submit | 测试上传类 workflow,不只看文件是否 attach。 |
5. 证据链:为什么这个项目可信
这个项目最重要的不是“跑了 10 个任务”,而是每个结论都能回到 artifact。面试时可以强调: 我们把一次 GUI agent run 拆成多个可验证层级,每层都有 schema、validator 和失败边界。
deterministic task -> UI-TARS attempt -> preflight target check / repair -> capture.json + trace.json + run-export.json -> real-run-summary.json -> step trace attribution -> failure taxonomy -> finish gate
Capture bundle
每个 task 的 real-run/ 包含 capture.json、trace.json、run-export.json。
Step trace
把 preflight、operator prompt、capture、evaluation、finish gate 组织成带证据引用的 timeline。
derived attribution not raw action logFailure taxonomy
区分 infrastructure、operator binding、interaction primitive、task execution。
P0/P1/P2 root-cause framingFinish gate
一次性验证 local validation、smoke、local config、tunnel health、remote read-only health。
ready=true CI-friendlyThe latest P2 pass adds sanitized, run-scoped native UI-TARS action-event transcripts for three representative attempts: the original settings-toggle run plus two visible-target/screenshot-tool failure attempts for onboarding-form and ticket-review.
6. 当前结果应该怎么解释
面试时不要把 0/10 讲成 leaderboard 结论。更准确的讲法是: 扩展轮次证明 capture completeness 和 environment readiness 已经闭环,所以失败不再主要归因于“我们没抓到证据”。 在这个前提下,失败集中出现在 interaction primitives。
| 任务 | 分数 | 主要失败 primitive |
|---|---|---|
onboarding-form | 0.33 | 文本输入没有持续到完整表单,submit 缺失。 |
catalog-filter | 0 | 搜索/过滤后没有完成目标 item selection。 |
settings-toggle | 0.75 | checkbox 成功,但 timezone dropdown 留在默认值。 |
ticket-review | 0 | 表格查询、选择、review commit 均未完成。 |
modal-confirmation | 0 | 没有完成 open dialog + confirm sequence。 |
pagination-review | 0.33 | 目标 invoice 存在,但未切到 page 2 并 review。 |
sortable-inventory | 0 | 没有把 risk sort commit 到正确方向,也没有选中目标 SKU。 |
multi-select-approvals | 0 | 未完成 precise multi-select 和 submit。 |
validation-error-recovery | 0.4 | 触发了 validation,部分填写,但 owner/date/submit 缺失。 |
file-upload-request | 0.25 | 文件 attach 成功,category/description/submit 失败。 |
settings-toggle 和 file-upload-request
是很好的 split cases。前者说明简单 checkbox 可以成功但 dropdown commit 不稳定;后者说明文件 attach 可以成功,
但后续表单 workflow 仍会失败。这种拆分比单一成功率更有工程价值。
7. 开发过程中的取舍思考
这一节是面试最容易加分的地方。不要只说“我写了哪些模块”,要说你面对不确定性时如何定边界。
取舍 1:本地确定性 app vs 真实网站
选择:先做本地确定性 benchmark app。
原因:真实网站变化快、状态不可控、登录和反爬会污染结论;本地 app 可以把任务、状态和 judge 固定下来。
代价:外部真实性弱一些,所以现在定位为 failure-analysis workspace,不是 paper-grade external benchmark。
取舍 2:证据链优先 vs 成功率优先
选择:先保证 10/10 captured,即使 success rate 低也不隐藏失败。
原因:没有完整 artifact 的成功率没有解释力;完整失败证据比漂亮数字更能暴露 agent primitive 问题。
代价:短期展示不如“高分 demo”好看,但更可信。
取舍 3:自动 target repair vs 手动救火
选择:preflight 自动发现、创建、导航、隔离和激活 benchmark target。
原因:UI-TARS 经常观察 search page、空 target、错 task 或 stale child Chrome。手动救火会让实验不可复现。
代价:preflight 逻辑复杂,需要明确安全边界和敏感信息清洗。
取舍 4:derived step trace vs 等待原始动作日志
选择:先用现有 artifact 重建 timeline,同时明确 evidence limitations。
原因:这样可以立刻解释失败发生在哪个阶段,不必等所有底层日志接入。
代价:不能做动作级行为分析,所以报告里明确不声称 raw action transcript。
取舍 5:zero dependency vs 引入测试框架/前端框架
选择:保持 Node.js zero-dependency。
原因:benchmark 本身更像 artifact pipeline,减少依赖能降低安装摩擦,也方便 CI 和公开复现。
代价:需要手写一些 harness、DOM stub、CDP WebSocket 逻辑,但可控性更强。
取舍 6:oracle baseline vs 直接跑更多模型
选择:先加 scripted oracle baseline,证明 10 个任务通过 UI path 可解。
原因:如果 oracle 都做不到,失败可能来自任务设计或 judge 错误,而不是 agent 能力。
代价:它不是模型评测结果,只是 P0 solvability proof。
取舍 7:公开安全 vs 原始信息完整
选择:公开 repo 里清洗私有连接、凭证、浏览器存储、截图 base64 和敏感字段。
原因:面向外部读者时,证据要可信,但不能泄露私有环境。
代价:一些低层原始上下文不会进入公开 artifact,所以要在 limitations 中说明边界。
取舍 8:定性 taxonomy vs 统计结论
选择:当前只做 qualitative failure taxonomy,不做 leaderboard 或显著性结论。
原因:10 个任务、单个扩展轮次不足以支持模型总体能力判断。
下一步:重复 10-task round、保留 raw action logs、报告 variance 和 confidence interval。
8. 实现细节:你需要能讲出来的几个点
8.1 Deterministic judge
public/tasks.json 定义任务和 criteria,src/judge.mjs 对每个 task 写确定性 judge。
评分是通过 criteria fraction 得到的,success=true 只有在所有 criteria 都通过时才成立。
这让 partial progress 可以被保留下来,例如 settings-toggle 通过 3/4 criteria 得到 0.75。
8.2 Browser API
app 暴露 window.__BENCH__.reset()、snapshot()、evaluate()、
exportRuns()、importRuns()。UI-TARS 或脚本不需要读内部实现,只要能打开页面并最终
从这个 API 拿 state 和 judge result。
8.3 UI-TARS preflight
preflight 的关键不是“检查页面能不能打开”,而是检查 UI-TARS 受控 Chrome 的 CDP target 是否唯一、正确、可激活。 它会处理几类高频问题:空 target list、search page start、active target mismatch、多个 benchmark tab、 stale child Chrome、Chrome error page。必要时它会创建新 target、导航 search target、隔离多余 target, 最后激活正确 benchmark tab。
8.4 Capture 和 artifact validation
capture 通过 CDP 在目标页面执行 benchmark capture expression,拿到 finalState 和
evaluation。validator 再检查 summary、capture bundle、taxonomy、step traces、finish gate
是否互相一致。这个设计能防止“summary 写了 captured,但实际没有 capture file”这类证据断裂。
8.5 Oracle baseline
validate:oracle-baseline 用 scripted UI actions 跑过同一个 public/app.mjs 事件路径,
再用 window.__BENCH__.evaluate(taskId) 评分。它验证 10/10 tasks 可以通过 UI actions 得到
score=1,所以当 UI-TARS 失败时,我们可以排除“任务本身不可解”这个 P0 风险。
9. 面试追问准备
Q1:为什么不用真实网站?
可以回答:真实网站适合最终外部验证,但第一阶段我更关心把失败原因拆清楚。真实网站会引入登录状态、网络波动、 DOM 变化、AB test、权限和反爬,容易让 judge 不稳定。本地 deterministic app 能保证同一个状态、同一个 criteria、 同一个 UI path,先把 reliability pipeline 做稳。后续可以把这套证据链迁移到更真实的网站任务上。
Q2:0/10 success 是不是说明项目失败?
不是。这个项目目标不是把 UI-TARS 调到最高分,而是构建能解释失败的 benchmark harness。0/10 full success 在 10/10 captured 和 finish gate ready 的前提下反而有分析价值:它说明环境和证据链已经闭环,失败集中在 dropdown commit、selection commit、modal、pagination、multi-select 等 primitives。项目产出的是 failure map。
Q3:怎么保证 judge 公平?
judge 只看 deterministic state,不读模型日志,也不靠主观截图判断。每个 task 有明确 success criteria; partial score 是 criteria 通过比例;oracle baseline 证明正确 UI 操作可以拿满分。这个组合能降低 judge bug 和任务不可解带来的误判。
Q4:preflight 为什么这么复杂?
GUI agent 的真实失败经常不是模型不会点,而是它根本看错了页面。UI-TARS 可能绑定到 search tab、空 target、 错任务、多个 benchmark tab 或已经失效的 Chrome 子进程。preflight 把这些问题显式化,并在安全条件下自动修复。 这样后续失败才可以归因到 interaction primitive,而不是环境噪声。
Q5:step trace 不是原始动作日志,会不会不可靠?
它的定位不是替代 raw action log,而是把已有 artifact 做成可读的 timeline attribution。每个 step 都标明 evidence kind 和 references,并在 schema 里承认 limitation。现在 P2 已经补了一组三任务 native action transcript 样本,但历史 expanded round 仍然不能被回填成 raw action log。
Q6:你在这个项目里最难的工程问题是什么?
可以讲 target binding。最开始 UI-TARS 有时看着 Google 或错误 tab,capture 也可能因为多个 benchmark target 变得 ambiguous。如果不解决这个问题,所有模型能力结论都会被污染。我后来把 preflight 做成状态机式的检查和修复: 发现 live UI-TARS child Chrome、过滤 stale endpoint、判断 benchmark/search/error target、必要时创建或导航 target、 隔离多余 tab、最后激活正确页,并把每次修复写成 artifact。
Q7:下一步你会怎么做?
- 修复 UI-TARS 可见窗口绑定,让截图稳定落在 prepared benchmark page。
- 带 native transcript preservation 重复 10-task expanded round,报告 variance 和 confidence intervals。
- 把同一 harness 接到更多 GUI agent/operator,对比 failure taxonomy,而不是只对比 success rate。
- 把 dashboard/GIF 放在证据闭环之后,用可视化帮助读者浏览,不替代 artifact。
10. 一段可以背下来的完整回答
这个项目叫 GUI Agent Benchmark,我把它定位成 agent reliability 方向的 failure-analysis workspace。 我观察到很多 GUI agent demo 最后只有成功/失败,但如果失败了,我们不知道是模型没能力、浏览器 target 错了、 远端模型服务不可用,还是最终状态没有被正确 capture。所以我做了一个确定性浏览器 benchmark,把任务、judge、 UI-TARS 集成、preflight 修复、capture、step trace、failure taxonomy 和 finish gate 串起来。
架构上,public/ 是本地 benchmark app,public/tasks.json 定义 10 个任务;
src/state.mjs 和 src/judge.mjs 做确定性状态和评分;src/uitars-preflight.mjs
负责 CDP target 检查和修复;capture 层抓 final state 和 evaluation;最后 docs/、
experiments/、artifacts/ 保存报告、taxonomy、step traces 和 finish gate。
最新扩展轮次覆盖 10 个常见 GUI primitive,10 个任务都 captured,finish gate 是 ready,但 full success 是 0/10。 我不会把这说成模型排行榜结论;它更像一个诊断结论:环境和证据链已经闭环,失败集中在 dropdown value commit、 table selection、modal confirmation、pagination、sorting、multi-select、validation recovery 和 upload workflow。
我最重要的取舍是先追求可复核证据,而不是追求漂亮成功率。比如我加了 oracle baseline,证明所有任务通过 scripted UI actions 都可以拿满分,所以任务和 judge 是可解的;我也把 step trace 明确标成 derived attribution,不把它包装成 raw action log。现在 P2 已补齐三类代表性 native transcript 样本;后续我会先修复可见 target binding,再重复多轮实验, 并把这个 harness 用到更多 GUI agent 上做 failure taxonomy 对比。
11. 面试前代码路径速查
| 你要说明的点 | 对应文件 |
|---|---|
| 任务定义和 criteria | public/tasks.json |
| 浏览器 app API 和 run recording | public/app.mjs |
| 确定性状态 | src/state.mjs |
| judge 评分逻辑 | src/judge.mjs |
| run schema 和 import/export | src/runs.mjs, src/trace-importer.mjs |
| UI-TARS target binding 和 CDP 修复 | src/uitars-preflight.mjs |
| 真实 round 汇总 | src/uitars-real-round.mjs, scripts/validate-real-round.mjs |
| step trace schema 和验证 | docs/step-trace-schema.md, scripts/validate-step-traces.mjs |
| failure taxonomy | docs/failure-taxonomy.md |
| oracle baseline | src/oracle-baseline.mjs, scripts/validate-oracle-baseline.mjs |
| finish gate | src/finish-gate.mjs, artifacts/finish-gate/2026-05-25-expanded-real-round.json |
| 公开说明 | README.md, docs/benchmark-report-2026-05-25-expanded-real-round.md |
12. 复习清单
- 能用 30 秒说清楚项目不是 leaderboard,而是 evidence-chain benchmark。
- 能画出 Task UI、Judge Core、Run/Trace、UI-TARS Layer、Evidence Gate 五层架构。
- 能解释为什么 10/10 captured 比 0/10 success 更关键。
- 能讲清 oracle baseline 的作用:证明任务和 judge 可解,不代表 agent 分数。
- 能主动说出 limitations:derived step trace、单轮扩展实验、缺少 raw action transcript。
- 能给出下一步:raw logs、重复轮次、variance、更多 agent/operator 对比。