20260507-web Agent

4 阅读13分钟

基于昨天的想法,我做的agent中要包含类似browser use的web agent功能。于是继续用Gemini DeepResearch看了下现在的web agent有哪些,另外详细看了下browser use的设计。希望能给自己、给大家带来一些参考

Web Agent调研

代理/框架系统主要市场定位与功能核心机器感知路径关键技术差异、性能表现与局限性
Browser-Use开发者自定义代理框架 / 完全自主导航纯DOM解析与文本提取在WebVoyager基准测试中以89.1%的成功率位居榜首。深度整合LangChain进行自主任务规划。局限在于其测试通常依赖本地白名单IP,可能无法真实反映其对抗高级Bot防护系统的能力 1 。
Skyvern (2.0)无代码企业工作流自动化 / 云端商业化基于视觉(Vision-Based)的多模态解析基准成功率达85.85%。采用独特的“规划者-行动者-验证者(Planner-Actor-Validator)”三相闭环逻辑。原生支持SOP文档上传,擅长处理极其复杂的政府和保险表单,并具备处理验证码的云端住宅代理支持。
Firecrawl网页数据提取层 / RAG数据管道DOM解析与CLI优先控制提供完全托管的沙盒环境,无需本地安装Chromium。其结构化Markdown输出相较于原始HTML可将LLM的Token消耗降低67%。支持大规模并发会话。
Agent-E开源网页自动化代理深度DOM提炼(DOM Distillation)成功率为73.1%。通过“感知技能(Sensing Skills)”和HTML提炼极大降低推理成本。但在高度动态、重度依赖JavaScript渲染的网站(如复杂航班日历预订)上表现疲软。
LaVague逐步引导执行工具(Step-by-step)DOM解析以较低的延迟执行特定原子级命令(如“点击搜索按钮”),跳过了高层LLM的复杂规划开销。但在目标网站UI重构时极为脆弱,需要手动干预。
Stagehand自动化测试SDK (面向TypeScript)混合感知模式构建于Playwright等传统测试工具之上的AI推理层。能够动态适应UI变化,有效解决了传统自动化测试中常见的“选择器失效(Flaky Selector)”问题。
Opera Neon面向消费者的通用AI浏览器混合感知模式内置双重AI代理架构。采用任务导向的“卡片(Cards)”系统,并提供对Meta、Google等公司提供的169种开源权重模型的访问支持。
Dia Browser隐私优先的消费者浏览器混合感知模式2025年被Atlassian收购。提供极简界面与环境AI辅助,其核心是基于上下文触发操作的“技能系统(Skills System)”以及常驻的AI侧边栏。
来自Google Gemini Deep Research

web agent总结下来大致分为两类:

  • 基于playwright的分析DOM并执行
  • 基于视觉模型实现

优缺点

基于playwright的,执行较快,操作web原生界面。但是DOM往往内容多,冗余,喂给大模型时易产生幻觉。

基于视觉模型的,其实个人理解是以后的发展方向,类似于computer use实现的功能,对网页截图,然后定位像素,然后进行点击输入等操作。更灵活,体验更好。但是目前成本极高,且需要优秀的模型底座支持,同时执行速度慢很多

另外对于web agent,同样提到了自主学习自进化,多agent协作。这不仅是web agent,这是所有agent近期的发展和实现方向

同时还提到了webMCP协议,未来在搭建前端网页时,网页会提供基于webMCP协议的api供web agent调用,这样不需要分析DOM或者使用视觉技术,直接调用api即可实现对应的网页操作

Browser Use

这里的调研内容对于一个想要构建web agent的人有很多参考价值。 以下内容纯摘抄自Google Gemini Research: gemini.google.com/share/9e0e4…

智能体模块与 ReAct 引擎

智能体模块(browser_use.agent.service)是整个架构的中央大脑与任务编排器。它的核心运转机制是一个无限的异步 ReAct 循环。在每一个执行步(Step)中,Agent 引擎首先通过底层服务获取当前浏览器的环境状态快照,将此快照通过严格的提示词工程(Prompt Engineering)进行降维,随后输入给 LLM。LLM 的输出并不是自由格式的文本,而是被严格限制为符合 Pydantic 模型(ActionModel)的结构化 JSON 数据。引擎随后解析这些数据,并分发给底层工具执行。

从 DOM 到可访问性树(AOM)的语义降维

可访问性对象模型(AOM)的核心价值在于,它天生是一棵经过高度语义净化的子树。那些仅用于视觉排版和布局的标签(如没有 ARIA 属性的占位 <div><span>)会被浏览器内核自动修剪。AOM 节点仅保留了四个关键属性:名称(Name)、描述(Description)、角色(Role,如按钮、导航栏)以及状态(State,如复选框是否选中、下拉框是否展开)。
Browser-Use 深刻认识到,面向屏幕阅读器的 AOM 完美契合了 LLM 对结构化、高密度语义状态的需求。通过 DomService 模块,Browser-Use 将浏览器的可访问性树映射为一个类似虚拟文件系统的操作空间

动态 JavaScript 注入与节点过滤算法

Browser-Use 并不直接依赖操作系统底层的辅助 API,而是在每个执行循环中,通过 eval 向目标网页的上下文注入一段自定义的 JavaScript 脚本(核心逻辑位于 browser_use/dom/dom_tree/index.js)。这段脚本执行深度的 DOM 遍历,并依据严密的启发式规则进行节点过滤:

  1. 交互属性判定:脚本会识别元素是否拥有点击事件监听器、是否属于输入控件簇、或是具有可交互的语义标签(如 <a>, <button>, <input>)。
  2. 空间可见性计算:利用底层的 getBoundingClientRect 计算元素在当前视口中的绝对坐标与长宽。任何宽高为 0、被 display: none 隐藏、或被绝对定位元素完全遮挡的节点,都会被判定为无效并从树中剥离。
  3. 动态索引分配(Index Mapping) :为所有经过验证的有效交互节点分配一个自增的整数索引(Index ID)。
  4. 序列化输出:最终生成的并非层级树,而是一个被压平的字典结构(DOMInteractedElement),其中仅包含极简字段:索引 ID、元素角色、可见文本内容与坐标。

系统提示词(System Prompt)的结构化拓扑

系统提示词模板(system_prompt.md)是驱动 LLM 进行因果推理的内核法则。在每一个 ReAct 循环步,提示词都会被动态组装并分割为四个严格规范的区块:

区块层级语义内容表述系统内嵌机制映射
区块一:宏观历史(Event Stream)按时间顺序流排列的先前动作及其具体返回结果。提供失败尝试的记忆,防止模型陷入循环重试的死胡同。
区块二:微观状态(Current State)Agent 的短期工作记忆(Memory)、当前宏观目标的进展总结,以及即刻需要规划的下一子目标(Next Goal)。锚定当前操作节点,保障多步复杂推导过程中的主线不偏移。
区块三:环境感知(Page State)当前浏览器的 URL、标签页拓扑结构,以及最重要的——附带数字索引的交互元素列表及内容萃取文本。模型做出动作输出的直接上下文依据。
区块四:视觉补充(Browser Vision)Base64 编码的实时浏览器截屏图像(包含边界框标注)。多模态环境理解支撑层。

基于 MessageCompactionSettings 的记忆浓缩算法

当任务持续的步骤数不断累加时,原始区块一和区块二的长度会急剧膨胀。Browser-Use 巧妙地设计了 MessageCompactionSettings(消息压缩配置)类,实现了自动化、启发式的上下文修剪机制。
该机制的工作逻辑类似于操作系统的内存分页与交换。开发者可设定触发阈值,例如 compact_every_n_steps = 25summary_max_chars = 6000。当对话上下文积压超过此阈值,系统便会冻结当前的对话历史流,并唤起一个副模型(compaction_llm,为了节约成本往往指定为较小、推理较快的模型)介入。副模型读取这几万个 Token 的繁杂冗余历史,并将其凝练为一小段仅包含关键事件里程碑和数据沉淀的执行摘要。随后,这段摘要被塞回主模型的工作记忆区,而原始的冗杂交互日志则被丢弃。这一优雅的设计确保了 Browser-Use 构建的 Web Agent 可以执行数百步的复杂流程式拉取任务,而永远不会崩溃或越界

基于 Pydantic 的 Schema 验证机制

大模型天生具有输出幻觉和 JSON 格式结构不稳定的问题。即使在系统提示词中三令五申,模型也偶尔会漏掉括号、输出错误的数据类型或提供不符合预期的参数字段。
为了彻底阻断此类错误向底层执行环境蔓延,Browser-Use 依赖 Pydantic 构建了 ActionModel 规范。任何来自 LLM 的动作输出,都会立刻经过这个 Schema 对象的拦截验证。如果 JSON 格式破损或缺少必填的参数(如 click 动作缺少 index),Pydantic 将直接抛出明确的 Validation Error,Agent 框架会捕获这一异常,将其包裹进下一次循环告诉 LLM 具体的解析错误位置,强迫其重新生成。
内置的核心动作集合高度凝练,主要涵盖:

  • 交互类click(基于索引的点击)、type / input(聚焦后发送键入流)、select_option(处理下拉列表)。
  • 导航类open_urlgo_backscroll
  • 宏操作类extract_content(由 LLM 基于当前视口提取结构化数据对象)、send_keys(模拟特定键盘组合如 "Tab Tab Enter" 以处理纯基于 JavaScript 的奇特组件)。

精确并发与资源超时控制

在批量处理效率方面,通过参数 max_actions_per_step(默认配置为 4),LLM 被允许在一个推理回合中输出一个动作数组。例如,面对一个简历投递表单,模型可以一次性输出四条 type 命令分别填写姓名、邮箱、电话和地址。系统在底层顺序执行这些指令,并持续监听 DOMWatchdog,只要页面未发生导致结构失效的关键刷新,就会一直执行直到指令队列清空。这极大提高了吞吐量,减少了模型交互回合数。
另外,浏览器操作最令人头疼的莫过于不可预知的网络卡顿和无尽的 Loading。Browser-Use 对每一种具体的动作类型设置了环境变量级别的硬件超时控制:

执行事件类型 (Action Event)环境变量控制键默认超时阈值 (秒)应对场景分析
节点点击TIMEOUT_ClickElementEvent15.0元素在设定时间内无法获取焦点或响应,通常由遮罩层导致。
文本输入TIMEOUT_TypeTextEvent60.0长文本内容的键入耗时较长,特意放宽限制以防输入中途中断。
页面导航TIMEOUT_NavigateToUrlEvent15.0防止 DNS 解析过长或目标服务器未响应导致的全局线程死锁。
文件上传TIMEOUT_FileUploadEvent30.0处理远程代理浏览器中由于上传带宽受限引发的阻塞。

ReAct 驱动的自适应环境修复

Browser-Use 在每一次动作执行后,其 BrowserSession 都会触发新的 DOM 解析与视觉截屏。这意味着:

  • 应对交互路径变更:如果一个目标按钮原本在主页面,今天突然被隐藏到了左侧的汉堡菜单(Hamburger Menu)中,Agent 观察到页面变化后,其大模型的知识和视觉常识会立刻认识到这一点,自动输出点击汉堡菜单的指令,随后在下一帧即可发现暴露出来的按钮并完成点击。
  • 应对意外弹窗阻断:当页面突然弹出一个意料之外的订阅推广模态框(Modal Overlay)遮挡了目标表单,底层的 Playwright 往往会抛出 ElementNotInteractable 异常。Browser-Use 捕获这一失败信息后反馈给 LLM,LLM 分析最新的视觉截图,发现明显的干扰弹窗,它会先决策寻找并点击弹窗上的“X”关闭按钮,然后顺畅地继续之前的流程。这种处理逻辑与人类用户如出一辙。

步骤级故障容忍度(Max Failures Tolerance)

不可预知的极端情况(如页面陷入了严重的验证码死循环)依旧存在。为了防止 Agent 在特定步骤上无限制地燃烧 API Token 从而产生巨额成本,Browser-Use 设置了硬性的边界熔断参数 max_failures(默认阈值为 3 次)。
在同一个子目标的执行阶段,若 Agent 连续三次向执行器发送非法指令或导致相同错误(例如反复尝试点击一个已经被禁用的提交按钮),熔断机制将会被触发,系统抛出中断信号。值得一提的是,final_response_after_failure 参数在此时发挥关键作用——它允许模型使用最后一次中间数据状态强制生成一份任务未完结的诊断报告。这极大地便利了开发者的事后追溯与日志重放排查

browser-Use 为此打通了无缝对接真实浏览器上下文的链路。在执行命令时,通过传递 --profile "Default"--profile "Profile 1" 参数,系统能够指定系统路径下的特定 Chrome 用户数据目录。Agent 能够直接继承人类用户早已验证通过的持久化 Session Cookie、浏览器历史记录,甚至继承已经安装好的环境插件(如用于阻断广告加载的 uBlock Origin)。

小结

今天很懒,心情也很烂。没有将以上调研吸收到自己身上,纯是复制粘贴过来的

但browser use的ReAct、容错机制、等待时间、提示词工程、schema验证等其实可能是我这几天看下来最有用的东西。

今天其实都没有继续更新的动力,没想到才第3天就想放弃了,总是高估自己...

不过还好还是坚持下来了,至少分享了一点内容,不知道有没有用,有没有意义

继续加油吧