跳到主要内容

数据截至 (上游 commit 544ec87f2ede)

第 3 章 引擎核心 —— a11y 快照、两步推理、缓存与自愈

本章讲什么: v4 换了交付形态,但引擎的灵魂原样保留在 packages/extension/ 里。本章讲 act 的完整推理链:快照怎么抓、模型怎么只回一个 ID、两步法如何用「树 diff」升级、缓存和自愈怎么兜底。

1. grounding 地基:混合快照

captureHybridSnapshot(understudy/a11y/snapshot/capture.ts:59)产出两样东西:

产物干什么
combinedTree人类可读的无障碍文本树,每个可交互元素带唯一 ID(跨 iframe 拼好)
combinedXpathMap元素 ID → 精确 XPath 的字典(:275-276、:792-809——iframe 里的 XPath 会带上 encId 前缀拼回主文档坐标系)

模型只看文本树、只回 elementId + 方法名;框架拿 ID 查字典得 XPath,再经 understudy 的 CDP(performUnderstudyMethod)落到真实 DOM。「把话落到元素上」从视觉猜测降级为字典查表——这就是 Stagehand 比纯视觉 agent 稳的根本原因,v4 原样继承。

2. act 的两步推理:升级为「树 diff」

actService.act(services/actService.ts:48)的主链:抓快照 → inference.act 问模型 → 拿 elementId → 查 XPath → understudy 落点。

两步法的 v4 升级(:179-197):第一步做完后,若模型说「还要一步」(twoStep),框架重新抓一张快照,用 diffCombinedTrees(understudy/a11y/snapshot/index.ts 导出)把新老两棵树 diff 出「刚才那步改变了什么」,再用 buildStepTwoPrompt 把「指令 + 第一步动作 + 页面变化」喂给模型决定第二步。比起「把整棵树再发一遍」,diff 既省 token 又让模型聚焦变化。

模型给的候选动作集合被显式收窄:SupportedUnderstudyAction 里枚举的动作(还会剔掉下拉框选项这种特殊情形,:188-196)——模型的自由度被限制在「引擎真能执行的动作」里。

3. 缓存与自愈:可复用与能自愈

  • act 缓存:缓存键由 cacheService.buildActCacheData 按指令+参数构造(第 2 章 §3)。命中则跳过模型直接重放存好的 XPath——跑一次工作流可以零模型调用。
  • 自愈(self-heal):落点失败且开了 selfHeal 时,重抓快照再问一次模型、换新 XPath 重试(actService.ts:347 起;第二步路径里会显式把 selfHeal 关掉再递归,:253——防止自愈套娃)。

4. observe / extract:同一块地基的另外两种用法

  • observeService.observe(services/observeService.ts:25):抓快照 → 问模型要一批候选元素 → 映射成带 XPath 的 Action[] 返回给你,你自己决定点哪个。等于把 act 的「选元素」单独拆出来用。
  • extractService.extract(services/extractService.ts:42):a11y 树(可选加截图)喂给模型,按 Zod schema 返回结构化数据。

三个动词共享同一块地基(快照 + inference + understudy),只是「模型回答的形状」不同——这正是 v3 时代「handler 三分」在 v4 的对应物(services 三分)。

5. 一个传承关系的小结

v3(已退役)v4(当前)
交付形态npm 包,引擎与客户端同进程Chrome 扩展 + 三语言瘦客户端
act/observe/extracthandlers/actHandler.tsservices/actService.ts
快照understudy/a11y/snapshot/capture.ts(core 包)同名同思路,搬到 extension 包
两步法重发整棵树树 diff(diffCombinedTrees)
客户端界面库内函数调用stagehand.v4 JSON-RPC + SemVer 协商