Watchdog 服务模式 — 专注式子服务设计
学习目标
- 理解 Watchdog 模式的设计原理和接口约定
- 掌握各 Watchdog 的职责划分和交互方式
- 了解如何扩展自定义 Watchdog
项目实践
WatchdogBase 基类
所有 Watchdog 继承自 WatchdogBase,提供统一的接口:
WatchdogBase: async def start(self) -> None: # 启动 Watchdog,注册事件处理器 async def stop(self) -> None: # 停止 Watchdog,清理资源 # 事件处理器自动根据注册的事件类型调用启动流程:
- BrowserSession 启动时,创建所有 Watchdog 实例
- 每个 Watchdog 向事件总线注册其关注的事件类型
- 事件触发时,对应 Watchdog 的处理器被调用
Watchdog 职责矩阵
| Watchdog | 关注事件 | 核心职责 |
|---|---|---|
| DOMWatchdog | BrowserStateRequestEvent | DOM 快照获取、截图、元素高亮 |
| DownloadsWatchdog | FileDownloadedEvent | PDF 自动下载、文件追踪 |
| SecurityWatchdog | NavigationStartedEvent | 域名白名单/黑名单验证 |
| PopupsWatchdog | JS dialog events | 弹窗自动关闭、消息记录 |
| AboutBlankWatchdog | 页面加载事件 | 空白页自动重定向 |
| CaptchaWatchdog | 页面变化事件 | CAPTCHA 检测与等待解决 |
| CrashWatchdog | CDP 连接事件 | 浏览器崩溃检测 |
| LocalBrowserWatchdog | 生命周期事件 | 本地浏览器启动/关闭 |
| PermissionsWatchdog | 权限请求事件 | 摄像头/麦克风等权限管理 |
| RecordingWatchdog | HAR 事件 | HAR 网络录制 |
| ScreenshotWatchdog | 截图事件 | 截图存储到磁盘 |
DOMWatchdog — 最复杂的 Watchdog
DOMWatchdog 是核心 Watchdog,负责:
- DOM 快照:通过 CDP
DOMSnapshot.captureSnapshot获取完整 DOM 树 - 元素高亮:在页面上注入 CSS 标记交互元素
- 截图获取:通过 CDP
Page.captureScreenshot获取页面截图 - 无障碍树:获取 accessibility tree 用于 LLM 理解
DOM 处理流程:
CaptchaWatchdog — 被动等待模式
CaptchaWatchdog 不主动解决 CAPTCHA,而是检测并等待:
- 监听页面变化(URL 变化到已知 CAPTCHA 页面模式)
- 检测到 CAPTCHA 后,等待解决(依赖 Cloud 服务或用户手动)
- 等待期间返回
CaptchaWaitResult告知 Agent - 解决后或超时后继续
Watchdog 之间的协作
多个 Watchdog 可以响应同一事件:
NavigationCompleteEvent → DOMWatchdog: 获取新页面的 DOM 快照 SecurityWatchdog: 验证新页面的域名 ScreenshotWatchdog: 截图保存 CaptchaWatchdog: 检查是否是 CAPTCHA 页面每个 Watchdog 独立处理,互不干扰。
问题与规避
Watchdog 启动顺序依赖
问题:某些 Watchdog 依赖其他 Watchdog 先启动(如 DOMWatchdog 需要 CDP 连接就绪)。
对策:
- BrowserSession 按顺序启动 Watchdog
- Watchdog 内部处理启动失败的优雅降级
Watchdog 之间的状态共享
问题:Watchdog 需要访问共享状态(如当前页面 URL)。
对策:
- 通过事件传递上下文,而非共享可变状态
- 需要共享的数据通过 BrowserSession 的属性访问
添加新 Watchdog 的成本
问题:添加新 Watchdog 需要了解事件类型和 BrowserSession 内部。
对策:
WatchdogBase提供统一接口,实现start()/stop()即可- 事件类型定义在
events.py中,文档清晰 - 现有 Watchdog 作为参考实现
设计取舍
单一 Watchdog vs 复合 Watchdog
| 方案 | 优势 | 代价 |
|---|---|---|
| 单一职责(当前) | 独立测试、替换、扩展 | Watchdog 数量多 |
| 复合 Watchdog | 数量少、实现简单 | 职责混合、难以独立测试 |
Browser Use 选择单一职责:每个 Watchdog 可以被独立启用/禁用/替换,在 Cloud 模式和本地模式下可以灵活组合。