本节摘要:本节为第 3 章立哲学,也与第 2 章正面对照。先摆三种执行模式——纯代码(Playwright 直写)、纯 Agent(browser-use 循环)、混合(Stagehand)——在确定性、成本、可测性、适应性四个维度上的矩阵,指出多数生产任务的真相:稳定流程占大多数,不确定步骤是少数。然后算清 Agent 调用的真实成本:每步至少一次模型调用,延迟与费用都按步数做乘法,而概率路径让回归测试从「比对步骤」退化为「比对结果等价」,测试成本也隐性翻倍。接着给出代码优先判定树(结构稳定写代码、语义清楚用 act、完全动态交 Agent),并澄清「兜底」的确切含义:不是不用 Agent,而是让 Agent 只出现在不确定处。本节收在与第 2 章的分工表:任务级自主与步骤级混合是两种正交选择,不是新旧替代。
把第 1.3 节的对照表扩成完整矩阵,加上第 2 章的全自主模式:
| 维度 | 纯代码(Playwright) | 混合(Stagehand) | 纯 Agent(browser-use) |
|---|---|---|---|
| 确定性 | 完全确定 | 分段确定 | 概率路径 |
| 模型调用 | 零 | 仅不确定步骤 | 每步一次 |
| 可测性 | 传统断言,粒度到元素 | 混合断言 | 结果等价断言,粒度到任务 |
| 适应性 | 页面变即死 | 语义不变即活 | 目标可达即活 |
| 排障入口 | 代码与日志 | 代码、轨迹各一段 | 执行轨迹 |
| 典型场景 | 回归测试、稳定后台流程 | 生产业务流(登录、下单) | 开放任务、探索性工作 |
矩阵背后是对生产任务的经验判断:一个真实业务流程里,稳定步骤通常占大多数——登录页半年不换、结算按钮十年叫「去结算」;真正多变的往往是一两处(弹窗、新版内页、动态列表)。纯代码模式为这一两处多变性付出整条流程的维护代价(第 0.1 节的结构脆断),纯 Agent 模式为整条流程的稳定部分白付模型成本。混合模式的存在理由就是这条不匹配:用代码吃掉确定的部分,把模型调用精确花在不确定的刀刃上。
把成本算术写直白。一个十步流程:
纯代码: 模型调用 0 次 总延迟 ≈ 页面操作耗时(秒级) 纯 Agent:模型调用 ≥ 10 次 总延迟 ≈ 10 ×(页面操作 + 模型往返 1~5 秒) 混合: 假设 2 步不确定 模型调用 2 次,其余走代码
三笔账一起算:直接费用按模型调用次数线性累积,日均千次执行的任务,这笔钱从咖啡钱变成服务器钱;延迟同样线性累积,用户等待的流程里每步一两秒的模型往返直接吃掉体验;测试成本最隐蔽——概率路径意味着两次执行的步骤序列可能不同,回归测试不能断言「第 3 步点了哪个元素」,只能断言「最终结果等价」,测试设计难度上升,且偶发失败需要轨迹级排查(第 6 章)。
还有第四笔:心智成本。全自主循环的行为不可枚举,排障靠读轨迹;代码路径行为可枚举,排障靠读代码与日志。团队维护一个「九成代码一成 Agent」的流程,远比维护一个全 Agent 流程省心——这不是技术问题,是工程经济学。
拿一个假设的日均千次任务算细账(数字为示意,只为展示算法):十步流程,模型往返均值两秒、单次调用成本记为一个调用单位。
| 方案 | 模型调用 | 延迟增量 | 说明 |
|---|---|---|---|
| 纯代码 | 0 | 零 | 页面一变全链路维护 |
| 全 Agent | 每日 1 万次 | 每任务约 20 秒 | 十步全走模型 |
| 混合(2 步不确定) | 每日 2 千次 | 每任务约 4 秒 | 八成调用被代码吃掉 |
混合方案省下八成调用费与八成延迟——这就是「代码优先」四个字的账面含义。注意账目的另一面:那 2 千次调用买来的是八步代码的「页面变更自愈」,若页面半年不变,省下的调用是真省;若页面天天变,act 段比例就该上调。成本结构决定理念边界,没有一劳永逸的配比。
代码优先不是「永远写代码」,而是逐段判断。对流程里的每一步问两个问题:页面结构稳定吗?语义清楚吗?
步骤 X(例如「点击结算按钮」) │ ├─ 结构稳定(选择器半年不用改)? │ ├─ 是 ──▶ 写 Playwright 代码(get_by_role 一族) │ └─ 否 ──▶ 语义清楚(可见文本稳定)? │ ├─ 是 ──▶ act 指令(语义锚定位) │ └─ 否 ──▶ observe 检视候选,或 Agent 循环兜底 │ └─ 判定会随时间变化:昨天的「不稳定」今天被证明稳定了 ──▶ 沿树向上固化(3.3 节的自动化方向)
两个实操要点。其一,判定的证据是运行轨迹,不是拍脑袋——一段 act 连续几十次执行都命中同一个元素,它就具备固化资格(3.3 节的缓存机制会把这个证据自动化)。其二,「兜底」要澄清:Agent 兜底不是降级替补,而是常驻的保险层——即使某步已固化为代码,也可以保留一个失败后回退 act 的分支(缓存失效策略,3.3 节),代码失效时由兜底分支接管。这样系统在两个世界里都拿到好处:确定性来自代码,韧性来自兜底。
判定树落到系统结构上,就是一张分层图——生产系统里的代码优先长这个样子:
一个下单流程的三层结构(示意) 任务入口 │ ▼ ┌─────────────────────────────────────────────┐ │ 固化层:登录、选品、结算(纯 Playwright 代码) │ 确定性、零调用 │ 失败时 ↓ 回退 │ ├─────────────────────────────────────────────┤ │ 语义层:优惠券弹窗、新改版内页(act 指令) │ 一次调用、语义自适应 │ 失败时 ↓ 降级 │ ├─────────────────────────────────────────────┤ │ 兜底层:异常工单转人工或全自主 Agent 处理 │ 罕见触发、有人盯 └─────────────────────────────────────────────┘ │ ▼ 验证层(第 6 章):每层出口都验结果
三层的关键关系是逐层兜底的失败方向:上层失败往下降级,而不是整体失败。绝大多数日常流量停在第一层(零模型成本),偶发变更落在第二层(一次调用),真正的异常才触底第三层。第 10 章的多智能体工作流会把第三层展开成完整的人机协同设计。
| 问题 | browser-use 的答案 | Stagehand 的答案 |
|---|---|---|
| 面向什么 | 开放任务:目标给出,路径未知 | 业务流程:路径已知,个别步骤脆 |
| 默认执行形态 | Agent 循环接管全程 | 代码接管全程,Agent 按段介入 |
| 模型角色 | 驾驶员 | 保险丝 |
| 优化目标 | 完成率、适应性 | 确定性、成本、可测性 |
两行对照表的用处是防站队:它们不是竞争关系,而是问题域不同的两个工具。同一系统里共存很常见——主流程用 Stagehand 固化跑量,长尾异常工单交给 browser-use 式智能体人机协同处理。第 10 章的多智能体网页工作流会把这种分层编排展开。
理念越简洁,误读越多。三个高频误读与澄清:
| 误读 | 澄清 |
|---|---|
| 「代码优先等于不用 Agent」 | 兜底层常驻(第三节),Agent 从「默认路径」降级为「保险路径」,出场率降低、必要性不降 |
| 「Stagehand 比 browser-use 先进」 | 两者面向不同问题域(第四节),比较先进性没有意义,比较适配度才有 |
| 「固化一次到位就不用再管」 | 判定随时间变化(第三节),固化是持续过程:监控覆盖率与失效率,按月度回顾调整 |
第三个误读最伤长期运行的业务流程:把固化当一次性项目做完就撒手,三个月后页面悄悄改版,固化层大面积失效还以为天下太平。正确的心智是把固化当作运营动作而不是开发动作——它的节拍跟页面变更频率对齐,而不是跟版本发布对齐。
最后一条反教条的自查:如果你发现自己在给一段「结构明明稳定」的路径写 act 指令,或给一段「每天变样」的页面写死选择器,判定树用反了——理念服务于成本结构,不服务于信仰。给入门者的三步自我校验:第一步,把现有流程的每一步按判定树归类,标出稳定、语义、动态三种颜色;第二步,统计动态步骤占比,超过三成说明该流程更适合全 Agent 路线(回第 2 章),不足一成则代码占比可以更高;第三步,为每个语义层步骤设计降级路径,没有降级的 act 是新的单点故障。这套校验做熟了,第 3.3 节的固化流程只是它的自动化版本。
理念立住了,接下来给武器:下一节进入 Stagehand 的 API 实战——act 的指令怎么写才算好、extract 的数据模式怎么收窄、observe 的候选清单怎么消费、错误怎么处理。