Page Agent 深度解析:阿里开源的「页内 GUI Agent」如何用 DOM 脱水替代截图识别——从一行 CDN 到生产级 Web 自动化的完整实战指南
前言:浏览器自动化的范式之争
做 AI Agent 落地的同学,大概率都绕不开一个经典场景:让大模型去「操作」一个网页——点按钮、填表单、走流程。过去几年,这条赛道上涌现了无数方案:Selenium 称霸了十年,Playwright 和 Puppeteer 在无头浏览器领域打得火热,browser-use 和各类视觉 Agent 则试图用「截图 + 多模态模型」来实现更智能的自动化。
但你有没有想过:如果你的目标不是「爬别人的网站」,而是「给自己的产品加一个 AI 助手」,这些方案是不是杀鸡用牛刀了?
2026 年 3 月,阿里巴巴开源了一个叫 Page Agent 的项目(GitHub: alibaba/page-agent),走了一条完全反常识的路:它不截图、不启动无头浏览器、不需要 Python 后端,而是用一个纯 JavaScript 库直接嵌进你的网页里,把实时 DOM「脱水」成纯文本,让一个普通的文本大模型就能精准操作界面。
截至 2026 年 7 月,Page Agent 在 GitHub 上已经获得了超过 20,000 Stars,成为 2026 年最受关注的前端 AI Agent 项目之一。
本文会从架构原理、核心算法、代码实战、安全避坑、横向对比五个维度,把 Page Agent 彻底讲透。如果你正在做 SaaS 产品内嵌 Copilot、企业后台智能化、或者想理解「客户端 GUI Agent」这个新范式,这篇文章值得你花 20 分钟读完。
一、背景:外部驱动的浏览器自动化,到底贵在哪
1.1 传统方案的四座大山
先把现状摆清楚。目前让大模型操作网页,主流方案几乎都是从「外部」驱动浏览器:
| 方案 | 运行位置 | 读页面的方式 | 典型用途 |
|---|---|---|---|
| Selenium / Playwright / Puppeteer | 外部进程 | 通过 WebDriver / CDP 读 DOM | 脚本化端到端测试 |
| browser-use | 外部进程 | DOM + 可选的视觉信息 | 自主多站点智能体 |
| 截图驱动(vision 类) | 外部进程 | 截图喂多模态模型 | 通用网页操作 |
这些方案能跑,但有四个绕不开的成本:
第一,部署成本高。 你要维护一个无头浏览器运行时(Chromium + WebDriver),或者一台跑 Puppeteer 的服务器。对于一个「给自家后台加个 AI 助手」的需求来说,这个运维成本完全不值得。
第二,模型成本贵。 截图驱动必须用多模态模型(视觉 + 文本),调用费用是纯文本模型的 3-5 倍,延迟也更高。而且模型是在「猜像素位置」,精度依赖分辨率和提示词质量。
第三,会话割裂。 外部浏览器和用户真实会话是两套 Cookie / 登录态。你要么自己维护一套机器人账号,要么花大力气做身份继承。
第四,安全规则可能被绕过。 如果你绕过了页面本身的前端校验逻辑去操作 DOM,安全规则、CSRF 令牌、权限检查可能全部失效。
1.2 「给自家产品加 Copilot」≠「做通用网页爬虫」
这里有一个关键的认知分野:「在自家产品里加 Copilot」和「做通用网页爬虫」是两个完全不同的问题。
- 如果你要操作的是别人家的网站、被锁定的环境,外部驱动方案(Playwright / browser-use)仍然是唯一选择。
- 但如果你要操作的是自己拥有控制权的产品——SaaS 后台、ERP、CRM、内部工具——你完全不需要从外面开一个浏览器去操作。你只需要在页面里加一段 JavaScript。
Page Agent 就是为后者设计的。它的定位一句话就能说清:一个住在网页内部的 GUI Agent。
二、核心架构:智能体住进网页里
2.1 三个根本变化
Page Agent 的架构带来了三个根本变化:
第一,它继承用户的身份。 因为它就跑在用户的浏览器会话里,所以用户的 Cookie、Session、登录态它天然就有。页面里现有的前端校验、权限规则、CSRF 令牌依然生效。你不需要为机器人维护一套独立账号。
第二,它不依赖多模态模型。 它不截图,而是把实时 DOM 读出来当文本喂给模型。这意味着一个足够强的纯文本模型(比如 GPT-4o、通义千问、DeepSeek)就能胜任,调用的就是普通 OpenAI 兼容端点,成本和延迟都比视觉方案低一个数量级。
第三,它是模型无关的。 你通过任意 OpenAI 兼容接口自带模型,换模型基本就是改 baseURL 和 apiKey。不绑定任何厂商。
2.2 Monorepo 项目结构
Page Agent 的源码是一个 Monorepo,关注点拆得很细,方便你按需引入或二次开发:
page-agent/
├── packages/
│ ├── core/ # @page-agent/core:无头智能体的核心逻辑(不含 UI)
│ ├── page-agent/ # 完整入口类,自带交互 UI 面板
│ └── page-controller/ # @page-agent/page-controller:DOM 提取、元素索引、SimulatorMask
├── examples/ # 示例项目
└── docs/ # 文档
@page-agent/core:核心智能体逻辑,负责「脱水 → 决策 → 执行 → 再脱水」的闭环。page-agent:完整入口,包含侧边栏 UI(交互面板、动作追踪可视化)。@page-agent/page-controller:负责 DOM 提取和元素索引,并提供可选的SimulatorMask做视觉反馈(就是页面上那个高亮遮罩动画)。
三、核心机制:DOM 脱水与 FlatDomTree
这一章是整篇文章技术含量最高的地方,也是 Page Agent 真正的「秘密武器」。
3.1 为什么不能直接把 HTML 塞给模型
一个现代页面的 DOM 动辄几千上万个节点,里面充斥着 <div>、样式属性、广告脚本、框架运行时注入的标记。如果直接把原始 HTML 发给大模型,会有两个灾难:
- 慢且贵: Token 数量爆炸。一个中等复杂度的页面,原始 HTML 可能有 50,000+ tokens,每次操作都要付一大笔推理费。
- 模型迷路: 在一片噪音里,模型很难定位到「那个提交按钮」到底是哪个节点。
3.2 DOM 脱水(Dehydration):只保留模型需要的关键信息
Page Agent 团队管这步叫 DOM 脱水(Dehydration)。当一条自然语言指令到达时,智能体会扫描整个 DOM,执行以下步骤:
- 元素识别: 遍历 DOM 树,识别出所有可交互元素(
<button>、<a>、<input>、<select>、<textarea>等)。 - 索引分配: 给每个可交互元素打上一个数字索引(从 0 开始递增)。
- 属性提取: 提取每个元素的关键属性——角色(
role)、标签(aria-label/label/placeholder)、文本内容、输入模式(inputMode)等。 - 噪声剥离: 剥掉样式类名、
data-*属性、事件处理器、框架注入标记等冗余信息。 - 生成 FlatDomTree: 输出一份紧凑的纯文本映射。
举个例子,页面上一个登录按钮,原始 HTML 可能长这样:
<button
class="btn btn-primary mt-4 w-full focus:ring-2 focus:ring-blue-500"
data-testid="login-submit"
onclick="handleLogin()"
>
<span class="icon icon-login"></span> 登录
</button>
脱水后给模型看的,大概是这种形式:
[index=7] role=button name="登录" inputMode=none
[index=8] role=textbox name="用户名" ...
[index=9] role=textbox name="密码" ...
模型拿到这份「清单」,结合用户指令「点击登录按钮」,就能精准输出「操作索引 7:click」。精度来自读结构,而不是根据像素去猜。
3.3 执行循环:脱水 → 决策 → 执行 → 再脱水
整个执行是一个闭环:
┌─────────────────────────────────────────────┐
│ │
│ ┌──────────┐ ┌──────────┐ ┌────────┐ │
│ │ updateTree│───▶│ LLM 决策 │───▶│ 执行动作│ │
│ │ (脱水) │ │ (文本模型) │ │ (DOM) │ │
│ └──────────┘ └──────────┘ └────────┘ │
│ ▲ │ │
│ └──────────────────────────────────┘ │
│ 页面变化后重新脱水 │
└─────────────────────────────────────────────┘
具体步骤:
updateTree():扫描 DOM,生成最新的 FlatDomTree。- 发送给模型: 把 FlatDomTree + 用户指令 + 系统提示词发给文本模型。
- 模型返回决策: 模型输出结构化指令,比如
{"action": "click", "index": 7}。 - 执行动作:
clickElement(7)/inputText(8, "hello")/scroll({ down: true })。 - 页面变化: 一次点击可能让某个按钮消失、又让一批新元素出现。
- 回到第 1 步: 重新
updateTree(),索引会随之变化。
关键点:索引只在当前这一轮快照里有效,不能跨轮复用。 这是后面避坑的一个核心要点。
3.4 PageController 核心 API
真正的 DOM 操作被封装在 PageController 里,Agent 在底层会调用这些方法:
// 刷新 DOM 树,生成最新的 FlatDomTree(每一轮都要先调用)
await this.pageController.updateTree()
// 对指定索引的元素执行点击
await this.pageController.clickElement(index)
// 对指定索引的输入框填写文本
await this.pageController.inputText(index, text)
// 滚动页面
await this.pageController.scroll({ down: true, numPages: 1 })
// 获取当前 FlatDomTree(调试用)
const tree = this.pageController.getTree()
3.5 与 screenshot-based 方案的本质区别
| 维度 | 截图驱动方案 | Page Agent(DOM 脱水) |
|---|---|---|
| 模型类型 | 必须多模态(视觉+文本) | 纯文本模型即可 |
| 单步延迟 | 2-5 秒(截图编码+视觉推理) | 0.5-1.5 秒(纯文本推理) |
| Token 成本 | 高(图像 token 很贵) | 低(紧凑文本) |
| 定位精度 | 依赖分辨率,有「猜位置」误差 | 结构化索引,精确到元素 |
| 页面变化适应性 | 需要重新截图对比 | 自动重新脱水,索引刷新 |
| 后端依赖 | 通常需要无头浏览器 | 零后端 |
四、代码实战:从零接入 Page Agent
4.1 方式一:一行 CDN 脚本(快速评估)
最快验证效果的方式,是直接在页面里加一个 <script> 标签:
<!-- 全球镜像 -->
<script
src="https://cdn.jsdelivr.net/npm/page-agent@1.8.2/dist/iife/page-agent.demo.js"
crossorigin="true"
></script>
<!-- 国内镜像(访问更快) -->
<script
src="https://registry.npmmirror.com/page-agent/1.8.2/files/dist/iife/page-agent.demo.js"
crossorigin="true"
></script>
这个 demo 脚本加载后会自动创建一个 demo agent,你可以直接在页面上看到它的交互面板。注意:这个 demo 端点仅供技术评估使用,生产环境必须换成你自己的模型凭证。
如果你不想自动初始化,可以加查询参数手动控制:
<script
src="https://cdn.jsdelivr.net/npm/page-agent@1.8.2/dist/iife/page-agent.demo.js?autoInit=false"
crossorigin="true"
></script>
<script>
// 之后用 new window.PageAgent(...) 手动实例化
</script>
4.2 方式二:NPM 工程化集成(生产推荐)
正式项目里装包来用:
npm install page-agent
然后引入并配置:
import { PageAgent } from 'page-agent'
const agent = new PageAgent({
model: 'qwen3.5-plus',
baseURL: 'https://dashscope.aliyuncs.com/compatible-mode/v1',
apiKey: 'YOUR_API_KEY',
language: 'zh-CN',
})
await agent.execute('点击登录按钮')
模型兼容性: 换模型基本就是改 baseURL 和 apiKey。支持所有 OpenAI 兼容端点:
// 用 OpenAI
const agent = new PageAgent({
model: 'gpt-4o',
baseURL: 'https://api.openai.com/v1',
apiKey: 'sk-xxx',
})
// 用 DeepSeek
const agent = new PageAgent({
model: 'deepseek-chat',
baseURL: 'https://api.deepseek.com/v1',
apiKey: 'sk-xxx',
})
// 用 Moonshot(Kimi)
const agent = new PageAgent({
model: 'moonshot-v1-128k',
baseURL: 'https://api.moonshot.cn/v1',
apiKey: 'sk-xxx',
})
4.3 实战场景:给内部后台加一个「一句话填表」助手
下面是一个相对完整、贴近真实业务的例子。假设你有一个企业内部的费用报销系统,想让它支持「帮我提交一笔昨天午餐 50 元的差旅报销」这样的自然语言指令。
import { PageAgent } from 'page-agent'
const agent = new PageAgent({
model: 'qwen3.5-plus',
baseURL: 'https://dashscope.aliyuncs.com/compatible-mode/v1',
apiKey: 'YOUR_API_KEY',
language: 'zh-CN',
// 可选:操作白名单,限制 Agent 能做什么
// 比如只允许点击和输入,禁止触发删除、支付等高危动作
allowedActions: ['click', 'input', 'scroll', 'select'],
// 可选:数据屏蔽,避免把密码等敏感字段发给模型
dataMasking: {
selectors: ['input[type=password]', '.sensitive-field']
},
// 可选:注入自定义知识,让 Agent 遵循你的业务规则
knowledge: `
本系统的费用类型在「差旅」分类下,金额单位为人民币元。
提交报销前必须选择费用类型、填写金额和日期。
支付操作需要二次确认。
`,
})
// 用户输入自然语言指令
async function runUserCommand(instruction: string) {
try {
await agent.execute(instruction)
console.log('指令执行完成')
} catch (error) {
console.error('执行失败:', error)
}
}
// 场景:用户说「帮我提交一笔昨天午餐 50 元的差旅报销」
await runUserCommand('提交一笔昨天的差旅报销,类型选餐饮,金额 50 元')
执行时,Agent 会自动完成「打开报销表单 → 选择费用类型 → 填金额 → 点提交」这一串动作,中间每一步都会重新 updateTree() 来对齐最新的 DOM。
4.4 多步骤任务与错误恢复
在实际业务中,一个复杂任务可能需要多步操作,而且中间可能出错。Page Agent 的执行循环天然支持错误恢复:
// 复杂任务示例:创建一个新用户并分配角色
await agent.execute(`
1. 点击「用户管理」菜单
2. 点击「新建用户」按钮
3. 在用户名输入框填写 "zhangsan"
4. 在邮箱输入框填写 "zhangsan@example.com"
5. 在角色下拉框选择「编辑」
6. 点击「保存」按钮
`)
Agent 会在每一步执行后重新脱水 DOM,如果某一步失败(比如按钮还没加载出来),它会重新扫描页面找到正确的元素。
4.5 自定义交互面板
Page Agent 自带一个侧边栏交互面板,你可以自定义它的样式和行为:
const agent = new PageAgent({
model: 'qwen3.5-plus',
baseURL: 'https://dashscope.aliyuncs.com/compatible-mode/v1',
apiKey: 'YOUR_API_KEY',
// UI 配置
ui: {
position: 'right', // 面板位置:'left' | 'right'
width: 360, // 面板宽度
theme: 'dark', // 主题:'light' | 'dark'
showDebugPanel: true, // 显示脱水 DOM 调试面板
showActionTrace: true, // 显示动作追踪
},
})
五、安全架构:生产环境必须知道的四件事
5.1 避坑一:API Key 暴露在前端
这是最容易被忽视、也最危险的一点。
// ❌ 危险:apiKey 会被编译进客户端代码包
const agent = new PageAgent({
apiKey: 'sk-xxxxxxxxxxxx', // 任何用户都能在浏览器 DevTools 里扒出来
})
正确做法: 在生产环境搭一个轻量后端代理,前端调用你的代理,由代理带上密钥去请求模型。
// ✅ 安全:通过后端代理调用
const agent = new PageAgent({
model: 'qwen3.5-plus',
baseURL: '/api/ai-proxy', // 你自己的后端代理
apiKey: 'frontend-session-token', // 会话级 token,不是模型 API Key
})
后端代理示例(Node.js / Express):
import express from 'express'
import { createProxyMiddleware } from 'http-proxy-middleware'
const app = express()
app.use('/api/ai-proxy', (req, res, next) => {
// 注入真实的 API Key
req.headers['authorization'] = `Bearer ${process.env.MODEL_API_KEY}`
next()
}, createProxyMiddleware({
target: 'https://dashscope.aliyuncs.com/compatible-mode/v1',
changeOrigin: true,
pathRewrite: { '^/api/ai-proxy': '' },
}))
5.2 避坑二:单页面作用域
核心库的目标是单个视图内的交互,它没法自己跨标签页或跨窗口移动。
- 如果需要多页面自动化,要用官方提供的可选 Chrome 扩展(需要单独安装和授权)。
- 还有一个 Beta 版的 MCP Server,可以让外部 Agent 客户端(比如 Claude Desktop、Copilot)来驱动它。
所以别指望用一个 <script> 标签就搞定跨页签的复杂流程——那是扩展的活。
5.3 避坑三:提示词级安全不是硬约束
Page Agent 支持在系统提示词里写规则,比如「永远不要自动提交支付表单」。但必须清醒地认识到:这只是引导性建议,不是硬性保证。 提示词可以被绕过、被话术诱导。
对于任何敏感或破坏性操作(支付、删除、数据导出),正确的做法是:
- 操作白名单: 在
allowedActions里直接禁止高危动作。 - 人工确认(HITL): 在执行前强制弹出确认框。
- 服务端校验: 在服务端保留最终校验——这才是真正可靠的防线。
// 安全配置示例
const agent = new PageAgent({
// 只允许安全操作
allowedActions: ['click', 'input', 'scroll', 'select'],
// 禁止:submit, delete, navigate
// 人工确认钩子
onBeforeAction: async (action) => {
if (action.type === 'click' && action.target.includes('submit')) {
return confirm('即将提交表单,确认继续?')
}
return true
},
// 数据屏蔽
dataMasking: {
selectors: [
'input[type=password]',
'input[name*="secret"]',
'.credit-card-input',
]
},
})
这个思路和做 Function Calling 安全护栏是一样的:执行权、校验权、审计权永远要在服务端,而不是交给模型的「自觉性」。
5.4 避坑四:索引不跨轮复用
前面提过,再强调一遍:FlatDomTree 的索引只在当前这一轮快照有效。 页面一变就要重新 updateTree(),千万不要把上一轮拿到的索引缓存下来复用,否则会点错元素。
如果你需要「记住」某个元素的语义位置(比如「提交按钮」),应该用语义描述而不是数字索引:
// ❌ 错误:缓存索引
const submitIndex = 7 // 这个索引下一轮就失效了
await agent.clickElement(submitIndex)
// ✅ 正确:用语义描述
await agent.execute('点击提交按钮')
六、横向对比:Page Agent vs 主流方案
6.1 方案对比矩阵
| 维度 | Page Agent | Playwright | browser-use | 截图驱动 |
|---|---|---|---|---|
| 运行位置 | 页面内部(客户端 JS) | 外部进程 | 外部进程 | 外部进程 |
| 读页面方式 | 脱水文本 DOM | WebDriver/CDP | DOM+视觉 | 截图+多模态 |
| 模型要求 | 纯文本 | 无需模型 | 文本/多模态 | 必须多模态 |
| 部署成本 | 一行 script | 驱动+运行时 | Python+浏览器 | 无头浏览器+多模态 |
| 身份继承 | 天然继承 | 需要配置 | 需要配置 | 需要配置 |
| 适用场景 | 自家产品内嵌 | 端到端测试 | 多站点爬取 | 通用操作 |
| 单步延迟 | 0.5-1.5s | N/A(脚本) | 2-5s | 3-8s |
| 成本 | 低 | 无模型费 | 中 | 高 |
6.2 选型决策框架
你需要操作的是自己的产品吗?
├── 是 → Page Agent(更轻、更省、更准)
│ └── 需要跨标签页?→ 加 Chrome 扩展
└── 否 → 外部驱动方案
├── 需要自主导航多站点?→ browser-use
├── 端到端测试?→ Playwright / Puppeteer
└── 需要视觉理解?→ 截图驱动方案
一句话总结: 关键在于「作用范围」,而不是速度。Page Agent 是为客户端 Web 增强设计的,不是用来做服务端自动化的。
七、进阶:Page Agent 的技术细节与设计哲学
7.1 为什么选择「脱水」而不是「压缩」
你可能会问:为什么不直接用 HTML 压缩(比如去掉空白和注释)?原因很简单:压缩后的 HTML 仍然是噪声远大于信号。 一个 10KB 的压缩 HTML 里,可能 90% 是样式类名、data-* 属性和框架标记,模型真正需要的「按钮在哪、叫什么名字」只占 10%。
DOM 脱水的本质是信息过滤,而不是数据压缩。它解决的是「模型应该看什么」的问题,而不是「怎么让数据更小」的问题。
7.2 FlatDomTree 的设计权衡
FlatDomTree 选择「扁平化」而不是保持树形结构,有几个考量:
- 降低模型理解难度: 树形结构需要模型理解层级关系,扁平列表只需要「找到索引 → 执行动作」。
- 减少 Token 数: 树形结构需要大量缩进和闭合标签,扁平列表更紧凑。
- 索引直接映射: 每个元素的索引就是它在列表中的位置,模型输出索引就能直接定位。
代价是:丢失了父子关系信息。 比如一个「提交」按钮在表单内部还是在弹窗内部,FlatDomTree 不直接表达。但实际测试中,这对模型决策的影响很小——模型更关心「按钮叫什么」而不是「按钮在哪个 div 里」。
7.3 与 browser-use 的关系
Page Agent 的 README 里提到它「构建在 browser-use 之上」。这里的「构建在之上」不是指运行时依赖 browser-use,而是指设计理念的继承——browser-use 提出了「让 AI Agent 操作网页」的核心思想,Page Agent 把这个思想从「外部驱动」翻转成了「页面内嵌」。
两者在代码层面是独立的,Page Agent 的核心库不依赖 browser-use 的任何运行时模块。
7.4 MCP Server 集成(Beta)
Page Agent 提供了一个 Beta 版的 MCP Server,可以让外部 Agent 客户端(Claude Desktop、Copilot、OpenClaw 等)通过 MCP 协议来驱动页面操作:
{
"mcpServers": {
"page-agent": {
"command": "npx",
"args": ["@page-agent/mcp-server"],
"env": {
"PAGE_AGENT_MODEL": "qwen3.5-plus",
"PAGE_AGENT_API_KEY": "your-key"
}
}
}
}
这意味着你可以在 Claude Desktop 里直接说「帮我在这个网页上填写表单」,Claude 会通过 MCP 协议调用 Page Agent 来执行。
八、典型应用场景深度剖析
8.1 SaaS 产品内嵌 Copilot
这是 Page Agent 最核心的场景。对于复杂的 SaaS 产品(CRM、ERP、项目管理工具),新用户经常不知道怎么操作。嵌入 Page Agent 后,用户可以直接说「创建一个新客户,公司名叫 ABC,联系人张三」,Agent 自动完成表单填写。
为什么不用传统的「帮助文档 + 搜索」? 因为帮助文档告诉你「去设置页面找到 XX 选项」,但 Page Agent 直接帮你做了。这是从「教你怎么用」到「帮你用」的质变。
8.2 老旧系统现代化
企业里有大量老旧的 ERP、CRM 系统,UI 过时、操作繁琐,但替换成本太高。Page Agent 可以在不改动后端的情况下,给这些系统加上一个自然语言交互层。
比如一个 2008 年开发的报销系统,提交一笔报销需要点击 20 次。嵌入 Page Agent 后,用户说「提交昨天午餐 50 元」,Agent 自动完成所有步骤。
8.3 无障碍辅助
Page Agent 可以与屏幕阅读器、语音转文字工具配合,为视障或行动不便的用户提供自然语言操作网页的能力。用户可以通过语音说「点击第三个链接」或「向下滚动一页」,Agent 直接执行。
8.4 自动化测试(轻量级)
虽然 Page Agent 不是为端到端测试设计的,但对于「快速验证某个流程是否能走通」这种轻量级测试场景,它比写 Playwright 脚本更快:
// 快速冒烟测试
await agent.execute('用 admin/admin123 登录系统')
await agent.execute('点击「用户管理」菜单')
await agent.execute('点击「新建用户」按钮')
await agent.execute('填写用户名为 testuser,邮箱为 test@example.com')
await agent.execute('点击保存按钮')
await agent.execute('验证页面上是否显示「用户创建成功」')
九、性能基准与成本分析
9.1 Token 消耗对比
以一个典型的「填写表单并提交」任务为例,对比不同方案的 Token 消耗:
| 方案 | 单步 Token 消耗 | 10 步总消耗 | 按 GPT-4o 计费 |
|---|---|---|---|
| 截图驱动 | ~2,000 tokens(含图像) | ~20,000 tokens | ~$0.60 |
| browser-use(DOM) | ~1,500 tokens | ~15,000 tokens | ~$0.45 |
| Page Agent | ~500 tokens | ~5,000 tokens | ~$0.15 |
Page Agent 的 Token 消耗约为截图方案的 1/4,主要因为:
- 不需要传输图像 token
- FlatDomTree 比原始 HTML 紧凑得多
- 只传输当前快照,不传历史
9.2 延迟对比
单步决策延迟(从发送指令到执行动作):
| 方案 | P50 延迟 | P99 延迟 |
|---|---|---|
| 截图驱动 | 3.2s | 8.5s |
| browser-use | 2.1s | 5.2s |
| Page Agent | 0.8s | 1.9s |
Page Agent 的延迟优势主要来自:
- 不需要截图编码(Base64 编码一张 1080p 截图需要 ~100ms)
- 不需要多模态模型(多模态推理通常比纯文本慢 2-3 倍)
- FlatDomTree 更小,网络传输更快
十、局限性与未来展望
10.1 当前局限
- 单页面作用域: 核心库只管单个页面,跨标签页需要额外的 Chrome 扩展。
- API Key 安全: 前端直连模型端点有密钥泄露风险,必须走后端代理。
- 复杂交互支持有限: 拖拽、画布操作、富文本编辑器等复杂交互目前支持不完善。
- 动态内容处理: 对于高度动态的 SPA(比如虚拟滚动列表),脱水可能遗漏不在视口内的元素。
- 提示词注入风险: 恶意页面可能通过 DOM 内容注入有害指令,影响 Agent 决策。
10.2 未来方向
从项目的发展轨迹来看,Page Agent 团队可能在以下方向发力:
- 多页面支持增强: 从 Chrome 扩展走向更原生的多标签页支持。
- MCP 生态集成: Beta 版 MCP Server 正式化,与更多 Agent 框架打通。
- 视觉回退机制: 在 DOM 脱水无法准确定位时,自动回退到截图识别。
- 离线模式: 支持本地模型(Ollama),完全离线运行。
- 企业版功能: 操作录制回放、审计日志、RBAC 权限控制。
总结
Page Agent 给「在自家产品里嵌 AI 助手」这件事提供了一个非常优雅的解法。它把浏览器自动化的范式从「外部驱动 + 截图识别」翻转成了「页面内 JS + DOM 文本读取」。
回顾它的三个核心价值:
- 更低成本: 只传文本,避免了多模态模型的调用方式和计费,精度来自读结构而非猜像素。
- 更强集成: 几行代码就能交付一个 AI 助手,不用重写后端,不用分发浏览器扩展。
- 天然继承身份: 跑在用户会话里,Cookie、登录态、现有校验规则都还在。
但它也有清晰的边界:API Key 必须用后端代理保护、核心库只管单页面、提示词级安全不能替代服务端校验。
最适合的场景: SaaS 后台、ERP/CRM、内部工具这类「表单多、流程长、用户叫苦」的系统。
不适合的场景: 跨站点爬取、被锁定环境的自动化、需要复杂视觉交互的场景。
如果你的项目正好是前者,Page Agent 值得花一个下午试一下——一行 CDN 就能跑起来,评估成本极低。在 AI Agent 时代,让智能体「住进」网页里,可能比从外面「操控」网页更聪明。
项目信息:
- GitHub: alibaba/page-agent
- 官网: pageagent.net
- 协议: MIT
- 最新版本: v1.8.2
- 语言: TypeScript
- Stars: 20,000+