A Weekly Field Guide for AI Product Managers
Teardown · Nº 03

AI Radar.

深度工程拆解 · 一件产品一篇。
Nº 03 · Teardown 2026-W32

wai-play

面向 vibe coding 网页游戏作者的自动试玩 + 质量诊断 agent,在真实浏览器里像玩家一样把游戏打通关并出评测报告

工具层Agent Loop可观测与评估

§ 01定位

wai-play 是面向"用 vibe coding 快速做网页游戏"的人的自动试玩 + 质量诊断 agent。给它一个游戏 URL(可选传 ZIP 源码),它在真实浏览器里把游戏当作要通关的任务去玩,记状态、截图、录像,最后出五维评分 + 可复现的问题卡片 + 优化建议[1]。它本身就是一个在浏览器里跑的 agent,所以下面几条决策能干净地挂在 Harness 层上——和 goal-flow 一致,与上上篇 Wallfacer(层标签留空)相反。

§ 02它实现了什么 · 怎么运作

  • 接入检查(先卡门):开测前它先验游戏能不能测。它要求游戏在页面里暴露一个测试接口 window.GameFlowIntegration,里面有 observe()(读当前状态)、availableActions()(有哪些动作)、step(action)(执行一个动作)、evaluate()(返回 {done, success, failed, reason})、reset() 等函数;checkScenarioPreconditions 校验必需的状态字段在不在,缺了就向游戏要一个 repairPlan 补齐。没有这套绑定,它直接抛错"请接入真实动作处理逻辑",拒绝硬测[5]。
  • 建游戏模型:SourceGameModelBuilder 读游戏源码(如果给了 ZIP)抽出通关约束、目标描述、可用动作规则(带 ai_used 标记说明用了大模型分析源码),配合首屏观察建出一个游戏模型;再由 build_completion_plan 生成一份带 route_plan(通关路线)和 replan_when(什么情况该重规划)的通关计划[3]。
  • 试玩循环:每一步分观察相位和动作相位。拿到要执行的动作后,经浏览器适配器执行——优先调游戏 API 的 step(action)(动作串如 MOVE_RIGHTATTACK),没有 API 才退回 _fallback_step 用 Playwright 的 page.keyboard.press / page.click 模拟键鼠[2];执行后调 evaluate() 拿成败,再判断要不要停[3]。
  • 感知(它怎么知道现在game怎么样):优先读游戏 API 的 observe() 拿血量/分数/进度这些结构化状态;同时截图(page.screenshot)、扫 DOM 里的 script、录屏、注入 window.__gameflowBrowserMetrics 采帧率和卡顿、监听 console/pageerror 抓报错[2]。接口在时,状态是确定的;接口缺时,只能靠动作前后的视觉差分和 DOM 启发式来近似猜状态变了没[2]。
  • 失败重规划:一次尝试没通关,它做两层重规划——中途连续 N 步没进展就重新问 AI planner;整次失败后 _analyze_attempt_failure 抽出失败原因、错误签名、最后几个动作,喂给下一次尝试;最多 20 次自适应重试[3]。为省成本,它不是每步都问大模型:决策优先级是"高优 skill 动作 > 还在跑的 AI 计划 > 新叫一次 AI planner > 规则兜底",只有卡住了(_should_consult_ai_planner)才叫 LLM[3]。
  • 出报告:整条 trace 跑完,先由 rater 打五维分,再由 reporter 出报告——问题卡片绑证据(状态变化 / 截图 / ≤20 秒录像),同一问题只展示一次[1];评分刻意把"测试可信度"(API 接入、证据完整度、agent 操作可靠性)单列出来,不混进游戏质量分[1]。

打个比方:把它想成一个第一次玩这游戏、手边没有存档、也不能任意重开某一关的玩家——它只能从头打,边打边猜规则,输了复盘再从头来,最多来 20 次。下面三条决策都能对回上面这些机制。

§ 03我的初判 vs 实际

初判(Vivian,两段式): - 产品读:游戏测试复杂、流程长,非专业人士难上手、更难一次测全;它给这群人做游戏产品的自动化测试。 - 推导的花样位置:浏览器操控——操控不够精准/自然,它报的"bug"可能是它自己操控失误、而非游戏的问题;所以必须把操控做到接近人类水平,测试才有意义。

对照下来——这篇的差值很值钱: - 你把中心风险找对了,这是真本事。 "怎么知道一个报出来的 bug 是游戏的错、而不是测试器操控失误?"——这确实是这类产品的命门,你纯从产品逻辑就推到了它。 - 但你押的解法(把操控做到人类级)恰恰是它故意绕开的路。 浏览器操控这块,它交给了 Playwright——一个成熟的浏览器自动化库,点击按键本身很可靠,不是前沿难题[2]。面对"操控/感知不可靠"这个你担心的风险,它的工程答案不是"把手练到完美",而是从三个方向降低对这只手的依赖: 1. 把成败判定权搬进游戏自己暴露的接口(决策一):要求游戏实现 observe/step/evaluate,"通关没通关"由游戏亲口报,而非 agent 看画面猜;没接口就拒测[5]。 2. 操控分层:有接口时走确定性的 step(action),没有才退回近似的键鼠 + 视觉差分[2]。 3. 把评分设计成对测试器的毛病不敏感(决策三):接口接得好不给游戏加分,只采信玩家能观察到的证据,并把测试器自己的可靠度单列出来[4][1]。 - 所以这篇给你的判断升级是:面对一个不可靠的能力,工程上的第一反应往往不是"把它做准"(常常做不到),而是"减少对它的依赖"——靠契约把活推给环境、靠分层在能确定时就确定、靠稳健的度量让结论不被工具的毛病带偏。 你的产品直觉指对了病灶,拆解补上的是"药方长什么样"。 - 另外,和 goal-flow 那篇同一个规律:这产品真正最难的一块,你的产品视角没推到——是那个"没有存档、不能模拟的环境里,靠观察诊断失败、整体从头重跑"的通关 agent loop(决策二)。

§ 04关键设计决策

工具层

要求游戏暴露测试接口,没有绑定就拒测,而非硬做黑盒

  • 对回机制

    上一节的接入检查——游戏须实现 window.GameFlowIntegration(observe/availableActions/step/evaluate/reset);适配器优先调 window.GameFlowAgentAPI.step(action);checkScenarioPreconditions 校验状态字段,缺则要 repairPlan;无绑定直接抛错"请接入真实动作处理逻辑"[2][5]。

  • 证据

    [2][5]

  • 增量(README 不会直说的)

    README 的口径是"给个 URL 就能黑盒试玩,传 ZIP 源码会更准"——把接口/源码说成锦上添花。但代码显示,可靠的那条路要求游戏本身实现测试接口:接口在,状态和成败是确定的;接口不在,只能退到视觉差分 + DOM 启发式的近似模式,再没有动作绑定就干脆拒测[2][5]。也就是说,它真正的可靠性契约是"游戏得配合"。这一步正面回答了你担心的风险:与其让 agent 从画面里猜"我赢没赢"(会把 agent 的误判算成游戏的 bug),不如让游戏用 evaluate() 亲口报成败,把 ground truth 从 agent 手里挪到游戏手里。

  • 代价

    可靠性是拿"能可靠测的游戏范围"换来的——它更适合作者给自己(能改代码、愿意接一个测试接口)的游戏做测试;对一个纯 URL、画面全在 canvas 里、没接口的陌生游戏,它只能退到近似模式,可信度打折。README 里说的"给个网址就能测任何游戏"在这条路上是降级的。

  • 可迁移判断

    当 agent 对原始环境的感知或操作不可靠时(视觉识别、模拟键鼠),一个稳的做法是把"成没成、对不对"的判定权搬进环境自己暴露的接口契约里,并在没有契约时拒绝硬来。给任何 agent 产品做验证/测试类功能时,先问一句:成败信号是 agent 自己看出来的,还是被测对象亲口报的? 后者才经得起追问。

Agent Loop · 模型路由与成本

在没有存档、不能模拟的环境里靠观察诊断失败、整体从头重跑,并把贵的推理藏在便宜的默认后面

  • 对回机制

    test_game 的多次尝试 + _test_single_attempt 的步循环;_analyze_attempt_failure 把失败原因/错误签名/最后动作传入下一次;_should_consult_ai_planner 门控 LLM 调用,决策优先级"高优 skill > 在跑 AI 计划 > 新 AI 计划 > 规则兜底"[3]。

  • 证据

    [3]

  • 增量

    README 只有一句"首次路线失败就按真实状态倒推重规划,不盲目重复"。代码里这其实是一套三级重规划:中途停滞时重问 planner、整次失败后把失败分析喂给下次、最多 20 次自适应重试。更关键的一层限制代码自己暴露了——它没有模拟器、没有状态回滚,重规划只能靠从噪声观察里诊断"上次为什么卡住",然后从头再跑一遍,指望游戏够确定、前几步能回到同一个岔路口[3]。所以这产品真正最硬的地方在这儿:让一个陌生游戏被从头打通关,而手里既没有它的世界模型、也不能跳到任意一关。同时它有一层成本设计:不是每步都叫大模型,只有卡住了才升级到 LLM planner,平时走便宜的规则执行[3]。

  • 代价

    "从头重跑 + 指望确定性"这条路,对带随机性或流程很长的游戏容易失效;20 次尝试 × 每次多步会烧 token 和时间,所以才要那道"卡住才叫大模型"的门控来压成本。

  • 可迁移判断

    在一个不能存档、不能模拟的环境里让 agent 达成目标,重规划只能建立在"从观察里诊断失败 + 把失败教训带进下一次整体重跑"上,且要接受"能不能回到同一个岔口取决于环境有多确定"。另外那道"贵推理(大模型 planner)藏在便宜默认(规则执行)后面、卡住才升级"的门控,和你 AI Radar 的双模型路由是同一个成本模式——能用规则/小模型先扛的,别每步都惊动大模型。

可观测与评估

把评分设计成对测试器自身的毛病不敏感,并把测试器可靠度单列出来

  • 对回机制

    上一节出报告那步——五维加权评分,加上"测试可信度"被单独拎出来展示、不混进质量分[1][4]。

  • 证据

    [1][4]

  • 增量

    这是对你那个风险的第二重、也更隐蔽的回答。它不去假设"测试器是完美的",而是把评分本身设计成经得起测试器不完美:scoring_standards.py 里写死了"API 接入完整度不计分""内部 API 数值变化不能单独作为高分依据",反馈维只采信"玩家可见、可听或可从录像确认"的反馈、排除只在内部 API 里发生的变化[4];再把测试器自己的可靠度(API 接入、证据完整度、agent 操作可靠性)作为一个独立的轴报出来,让你自行打折[1]。一句话:它追求的是一个诚实、会亮出自己置信度的测试器,而不是假装一个完美的测试器。

  • 代价

    这要一套克制的评分规则去维护;而且"只算玩家可见的证据"会让一些只在内部状态里冒头的真 bug 被折价、甚至漏掉。

  • 可迁移判断

    当你没法保证测量工具本身准,别只想着把工具修准——①把指标设计成对工具已知的毛病不敏感(只采信玩家能观察到的证据,不让"接口接得好"抬高游戏分),②把工具自己的可靠度作为一个独立的数报出来,让读的人自行打折。这条对任何"用 AI 当裁判"的评测系统都成立,包括你 AI Radar 自己给产品打分那套——一个敢亮出置信度的评测,比一个只给结论的评测更可信

§ 05市场与需求

  • 需求判断和你一致(推断):它服务用 vibe coding 做网页游戏的人,这批人往往不写自动化测试脚本,却要回答"这游戏能不能从头玩到通关、玩法顺不顺"[1]。
  • 但它的适用边界被决策一钉住了(推断):要可靠测,前提是游戏接了 GameFlowIntegration 接口。所以它更贴合"作者自己(能改代码、愿意接个测试接口)测自己的游戏",而非"随便丢个网址就能测任何游戏"。README 的路线图也承认,要做"多用户隔离、任务队列、远程 URL 安全限制"才谈得上对公众开放[1]——现在它是个本地自测工具。
  • 一个更一般的呼应:它把"测试器可靠度"单列给人看,本质是承认自动化评测不完美、并把不确定性透明化。做 AI 产品时,评估任何"AI 自动评测 / AI 打分"类功能,都可以拿这把尺子问一句:它敢不敢把自己的置信度亮出来?

§ 06证据清单

  1. README(wai-play,已由管线抓取):自动试玩 + 质量诊断 agent;给 URL、可选 ZIP 源码;工作流(选类型→给 URL/源码→检查可测→建游戏模型→真实试玩 + 失败重规划→出报告);测试可信度诊断(API 接入 / 证据完整度 / agent 操作可靠性)单独展示、不混进质量分;问题卡片绑证据、同一问题只展示一次;Playwright/chromium、Streamlit、DeepSeek+Kimi;入口 app.py / agent/orchestrator.py / web/web_game_adapter.py / agent/scoring_standards.py / integration_templates.pyhttps://github.com/waiterve/wai-play
  2. web/web_game_adapter.py:控制经 Playwright(page.keyboard.press / page.click),主控路径优先调 window.GameFlowAgentAPI.step(action)(动作串 MOVE_RIGHT/ATTACK),无则 _fallback_step 键鼠;感知优先 GameFlowAgentAPI(getGameInfo/observe/availableActions/evaluate),另有 page.screenshot、DOM/script 扫描、录屏、注入 window.__gameflowBrowserMetrics 采帧率/长任务、console/pageerror 监听;API 在时确定性、缺失时靠视觉差分 + DOM 启发式近似 — https://github.com/waiterve/wai-play/blob/main/web/web_game_adapter.py
  3. agent/orchestrator.py:test_game 多次尝试(baseline + 至多 20 次自适应重试)+ _test_single_attempt 步循环(观察相位→动作相位→stepevaluatestop_decision);SourceGameModelBuilder 读源码抽约束/目标/动作规则(ai_used);build_completion_planroute_plan+replan_when;三级重规划(停滞中途重规划、跨尝试 _analyze_attempt_failurefailure_reasons/error_signature 传入下次);决策优先级 高优 skill > 在跑 AI 计划 > 新 AI 计划 > 规则兜底 > skill 推荐,_should_consult_ai_planner 门控 LLM;无模拟器 / 无回滚,靠观察诊断 — https://github.com/waiterve/wai-play/blob/main/agent/orchestrator.py
  4. agent/scoring_standards.py:五维加权(核心流程 0.24 / 核心玩法 0.26 / UI 0.20 / 反馈 0.15 / 技术 0.15);"API 接入完整度不计分""内部 API 数值变化不能单独作为高分依据";反馈维只算"玩家可见 / 可听 / 可录像确认"的反馈、排除内部 API 变化;六档评分带 — https://github.com/waiterve/wai-play/blob/main/agent/scoring_standards.py
  5. integration_templates.py:游戏须暴露 window.GameFlowIntegration(observe/availableActions/step/evaluate/reset,选配 jumpToScenario/evaluateScenario/repairScenario);checkScenarioPreconditions 校验前置状态字段,缺则求 repairPlan;无绑定则抛错"请接入真实动作处理逻辑",拒绝黑盒模拟 — https://github.com/waiterve/wai-play/blob/main/integration_templates.py