1. 项目概述与核心价值
最近在折腾一个自动化项目,需要让程序能像真人一样在网页上操作,比如自动填表、点击按钮、提取数据。传统的方案,像用 Playwright 或 Puppeteer 写脚本,虽然功能强大,但有个硬伤:太“脆”了。页面结构稍微一变,比如一个按钮的 CSS 类名改了,或者一个输入框的 ID 变了,整个脚本就挂了,得手动去改代码里的选择器。这种维护成本,对于需要长期运行或者处理大量不同网站的任务来说,简直是噩梦。
就在我头疼的时候,发现了 HyperAgent。它的定位非常清晰:给 Playwright 加上 AI 大脑。简单说,它让你可以用自然语言(比如“点击登录按钮”、“搜索笔记本电脑并提取前五个结果的价格”)来驱动浏览器,而不是去写那些脆弱的 CSS 或 XPath 选择器。这背后的核心,是把大型语言模型(LLM)的理解能力,与 Playwright 强大的浏览器控制能力结合了起来。LLM 负责“看懂”页面,理解你的指令,并规划操作步骤;Playwright 则负责精准地执行这些操作。这样一来,脚本的健壮性大大提升,因为 LLM 能根据页面的实际内容和语义来定位元素,而不是依赖那些容易变化的底层代码标识。
HyperAgent 适合谁呢?我觉得有三类人特别需要它。第一类是自动化测试工程师,尤其是做端到端(E2E)测试的,他们经常要应对频繁变化的 UI,HyperAgent 的 AI 驱动方式能显著降低测试脚本的维护成本。第二类是数据工程师或分析师,需要从各种结构不一的网站上爬取数据,手动写解析规则太费时,用自然语言描述需要什么数据,让 AI 去识别和提取,效率高得多。第三类是任何需要构建复杂网页自动化工作流的开发者,比如自动完成一系列表单填写、内容发布、监控报警等任务。HyperAgent 提供了一个更高抽象层的 API,让你专注于“做什么”,而不是“怎么做”。
2. 核心设计思路与两种操作模式解析
HyperAgent 的设计哲学很务实:不是所有场景都需要动用“重型”的 AI 模型。因此,它提供了两种互补的操作模式,page.perform()和page.ai(),让你可以根据任务的复杂度和对性能、成本的要求进行灵活选择。理解这两种模式的差异和适用场景,是高效使用 HyperAgent 的关键。
2.1page.perform():精准快速的单步操作
page.perform()是为单一、明确的动作设计的。比如“点击登录按钮”、“在搜索框输入‘笔记本电脑’”、“勾选同意条款复选框”。它的工作流程非常直接:
- 理解指令:将你的自然语言指令(如“fill email with user@example.com”)发送给 LLM。
- 解析页面:LLM 会分析当前页面的可访问性树(Accessibility Tree)和 DOM 文本内容。这里有个关键优化:它会自动过滤掉广告 iframe 等无关内容,让分析更聚焦。
- 定位与执行:LLM 判断出需要操作的元素(如一个
type="email"的输入框),并生成一个精确的定位指令(通常是 XPath)。然后,HyperAgent 通过 Chrome DevTools Protocol (CDP) 原生驱动,使用这个定位信息去执行点击、输入等操作。
注意:
page.perform()默认不启用视觉模式(即不截图),完全基于文本和可访问性信息进行分析。这带来了几个显著优势:
- 速度极快:省去了截图、上传图片、视觉模型推理的时间,通常响应在秒级以内。
- 成本极低:每次调用只产生一次 LLM 的文本交互费用,对于 OpenAI GPT-4o 这类模型,单次调用成本可能只有几分钱。
- 可靠性高:对于有明确文本标签或语义清晰的元素(按钮、链接、输入框),基于文本的定位非常准确。
实操心得:对于登录、表单填写、导航菜单点击这类标准化操作,page.perform()是首选。它的执行路径非常确定,调试起来也简单。我建议在编写自动化流程时,先把所有能明确用page.perform()描述的步骤都写出来,这能构成一个稳定、低成本的操作骨架。
2.2page.ai():处理复杂多步骤任务
当你的指令变得复杂,比如“在航班搜索网站上,查找从迈阿密到新奥尔良、7月16日出发的航班,并筛选出价格低于500美元的选项”,这时page.perform()就力不从心了。page.ai()正是为这类需要多步骤决策和视觉上下文理解的任务而生。
page.ai()的工作模式更像一个自主智能体(Agent):
- 任务分解:LLM 首先会理解你的复杂指令,并将其分解成一系列原子操作步骤。
- 环境感知:对于每一步,它可能需要结合视觉信息。当
enableVisualMode: true时,HyperAgent 会截取页面截图,并可能生成元素叠加层,帮助模型理解元素的相对位置和视觉特征。 - 规划与执行:模型根据当前页面状态(文本+视觉)规划下一步最佳操作,然后执行。执行后,页面状态更新,模型再次评估,循环此过程,直到任务完成或无法继续。
它的优势在于:
- 处理模糊指令:能理解“那个蓝色的按钮”、“右边栏的第一个商品”这类依赖视觉或相对位置的描述。
- 自动纠错与适应:如果某一步失败了(比如元素没找到),模型可能会尝试替代方案,比如滚动页面、点击其他标签页,或者重新表述查找条件。
- 端到端自动化:你只需要给出最终目标,中间的所有点击、输入、等待、翻页等操作,都由 AI 自动完成。
参数详解:
useDomCache: boolean:这是一个性能优化选项。设置为true时,HyperAgent 会在一次ai()调用中缓存 DOM 快照,后续步骤复用,避免重复获取和解析 DOM,能大幅提升复杂任务的速度。enableVisualMode: boolean:默认为false。设置为true会启用截图和视觉分析。这能极大提升对复杂、非标准或图形化界面的理解能力,但代价是速度变慢(需要截图和视觉模型推理)和成本增加。
实操心得:page.ai()非常强大,但也更“重”。我的经验是,不要一上来就对整个流程使用ai()。更好的策略是“混合模式”:用perform()处理明确的、结构化的步骤(如导航到特定URL,填写已知字段),用ai()处理其中复杂的、需要“智能”判断的子任务。例如,先perform(“goto product listing page”),再ai(“sort by price from low to high and click the second item”)。
3. 环境搭建与基础使用实战
理论讲完了,我们动手把环境搭起来,跑几个实实在在的例子。我会从安装开始,带你一步步体验 HyperAgent 的核心 API。
3.1 安装与初始化
首先,确保你的 Node.js 环境在 18 或以上版本。然后通过 npm 或 yarn 安装 HyperAgent:
# 使用 npm npm install @hyperbrowser/agent # 使用 yarn yarn add @hyperbrowser/agent安装完成后,我们来创建一个最简单的智能体。你需要一个 LLM 的 API 密钥,这里以 OpenAI 为例(它也支持 Anthropic、Google Gemini、DeepSeek 等)。
import { HyperAgent } from "@hyperbrowser/agent"; // 初始化智能体,指定 LLM 提供商和模型 const agent = new HyperAgent({ llm: { provider: "openai", // 也可以是 "anthropic", "gemini", "deepseek" model: "gpt-4o", // 根据提供商选择对应模型,如 "claude-3-5-sonnet-20241022", "gemini-2.0-flash" apiKey: process.env.OPENAI_API_KEY, // 建议从环境变量读取 }, // 可选:启用调试模式,会输出详细的执行日志 debug: false, }); // 记得在任务结束后关闭智能体,释放浏览器资源 // await agent.closeAgent();这里有几个关键点需要注意:
- API 密钥管理:永远不要将 API 密钥硬编码在代码中。使用
process.env或类似的机密管理服务。 - 模型选择:
gpt-4o在视觉和理解能力上很强,但成本也高。对于纯文本操作,gpt-4o-mini是性价比很高的选择。Anthropic 的 Claude 3.5 Sonnet 在长上下文和复杂指令遵循上表现优异。根据你的任务需求和预算做权衡。 - 调试模式:在开发阶段,将
debug设为true非常有用。你会在控制台看到 LLM 的思考过程、它尝试定位的元素、执行的命令等,这对于排查为什么 AI 没有按预期操作至关重要。
3.2 执行第一个自动化任务:executeTask
executeTask是最高阶的 API,你只需要告诉它最终目标,它就会自动管理页面生命周期(打开、导航、执行、关闭)。
const result = await agent.executeTask( "Navigate to amazon.com, search for 'wireless headphones', and extract the titles and prices of the first 3 results" ); console.log('任务输出:', result.output); console.log('任务是否成功:', result.success); console.log('执行步骤详情:', result.steps);执行这段代码,你会看到 HyperAgent 自动打开浏览器,访问亚马逊,在搜索框输入“wireless headphones”,点击搜索,然后从结果页中提取前三项的商品标题和价格,最后以结构化的格式返回。result.steps里包含了它分解和执行的所有子步骤,是理解 AI 工作流程的绝佳材料。
踩坑记录:在我第一次使用executeTask时,指令是“去谷歌航班查票”。结果 AI 打开了google.com,然后在首页的搜索框里输入了“flights”,这显然不对。问题在于指令不够精确。修改为“Navigate to the websiteflights.google.com”后,它就能正确导航到目标网站了。所以,给 AI 的指令要尽可能清晰、无歧义,包含关键网址和具体的操作对象。
3.3 精细控制:使用page.ai()和page.perform()
对于需要更多控制权的场景,我们可以手动创建页面对象,并混合使用ai()和perform()。
const page = await agent.newPage(); // 创建一个新的浏览器页面 // 第一步:导航到目标网站,使用 perform 进行明确的导航操作 await page.goto("https://flights.google.com", { waitUntil: "load" }); // 第二步:执行一个复杂的多步骤任务,让 AI 自动处理 const aiResult = await page.ai("search for flights from New York to London in next month", { useDomCache: true, // 启用 DOM 缓存加速 // enableVisualMode: true, // 如果页面很复杂,可以开启视觉模式 }); console.log('AI 任务完成,最终页面状态或输出:', aiResult.output); // 第三步:在 AI 操作后的页面上,进行一个明确的单步操作 await page.perform("click the 'flexible dates' checkbox"); // 第四步:从当前页面提取结构化数据 import { z } from "zod"; const extractionSchema = z.object({ availableFlights: z.array( z.object({ airline: z.string(), departureTime: z.string(), arrivalTime: z.string(), price: z.number(), stops: z.number(), }) ).describe("List of available flight options"), }); const extractedData = await page.extract( "get all the flight options shown on the page", extractionSchema // 使用 Zod 定义期望的数据结构 ); console.log('提取到的航班数据:', extractedData); // 最后,别忘了关闭页面或智能体 // await page.close(); // await agent.closeAgent();这个例子展示了典型的混合编程模式:
goto是标准的 Playwright 方法,用于初始导航。ai()处理了“搜索航班”这个包含多个潜在步骤(选择出发地、目的地、日期、点击搜索)的复杂任务。perform()用于执行一个非常明确的后续操作(点击“灵活日期”复选框)。extract()是 HyperAgent 的另一个强大功能,它利用 LLM 理解页面内容,并按照你定义的 Zod Schema 将非结构化的网页信息转换成结构化的 JSON 数据。这对于数据爬取和整合工作流来说,是革命性的。
重要提示:
page.extract()非常依赖 LLM 对页面内容的理解。为了提高提取准确性,最好在指令中明确指出你要提取的数据位于页面的哪个部分(例如,“从左侧的搜索结果列表中提取...”)。同时,Zod Schema 的定义要尽可能详细,使用.describe()方法为每个字段添加描述,这能极大地引导 LLM 找到正确信息。
4. 高级特性与生产级应用
当你掌握了基础操作后,HyperAgent 的一些高级特性可以帮助你将自动化脚本提升到生产级别,应对更复杂、更稳定的需求。
4.1 动作缓存:实现零成本回放
这是 HyperAgent 最让我惊艳的功能之一。每次page.ai()执行时,它都会在后台默默记录下所有操作步骤的“指纹”,包括点击元素的 XPath、所在的 iframe 索引、输入的文字等。这个记录被称为actionCache。
为什么需要这个功能?想象一下,你有一个每周需要运行一次的报表自动化流程,它需要登录系统、导航到某个复杂报表页面、设置一堆筛选条件、然后导出数据。每次都用ai()跑,不仅慢(需要 AI 重新思考),而且贵(每次都要花 LLM 的调用费)。有了动作缓存,你可以把第一次成功执行的动作序列保存下来,以后直接“回放”这些精确的物理操作,完全绕过 LLM,速度极快且成本为零。
// 1. 记录一次 AI 操作 const page = await agent.newPage(); await page.goto("https://example.com/complex-workflow"); const { actionCache } = await page.ai("perform the monthly sales data extraction workflow"); // actionCache 现在包含了所有步骤的详细信息 // 2. 将缓存保存到文件 import fs from 'fs/promises'; await fs.writeFile('monthly_report_cache.json', JSON.stringify(actionCache, null, 2)); // 3. 下次需要执行相同任务时,直接回放 const savedCache = JSON.parse(await fs.readFile('monthly_report_cache.json', 'utf-8')); const samePage = await agent.newPage(); await samePage.goto("https://example.com/complex-workflow"); const replayResult = await samePage.runFromActionCache(savedCache, { maxXPathRetries: 2, // 如果页面结构微调导致 XPath 失效,重试2次后会自动回退到 LLM 模式 }); if (replayResult.status === 'completed') { console.log('缓存回放成功!未使用 LLM。'); } else { console.log('部分步骤回放失败,已自动使用 LLM 补全。'); }生产环境建议:将动作缓存集成到你的 CI/CD 流程中。对于核心的自动化流程,先由人工或在一个稳定环境下执行一次,生成“黄金标准”缓存。然后在自动化测试或定时任务中,使用这个缓存进行回放。这既保证了操作的确定性,又极大降低了运行成本和提高了速度。
4.2 结构化数据提取与模式验证
page.extract()配合 Zod 库,将非结构化网页数据转换为强类型 TypeScript 对象的过程变得异常优雅和可靠。
import { z } from "zod"; const productSchema = z.object({ name: z.string().describe("The full name/title of the product"), price: z.number().describe("The current price in dollars, as a number"), isInStock: z.boolean().describe("Whether the product is currently available for purchase"), rating: z.number().min(0).max(5).optional().describe("Average customer rating out of 5"), features: z.array(z.string()).describe("List of key features or bullet points"), }); const page = await agent.newPage(); await page.goto("https://www.example-electronics.com/product/xyz123"); const data = await page.extract( `Extract the product information from the main product detail section. Ignore any customer reviews or related products.`, productSchema ); // TypeScript 会自动推断 data 的类型为 { name: string; price: number; ... } console.log(data.name); // 字符串 console.log(data.price); // 数字 console.log(data.features); // 字符串数组 // 你可以安全地将 data 存入数据库或进行后续处理深度解析:这里的魔法在于 Zod Schema 不仅定义了数据类型,还通过.describe()为 LLM 提供了额外的上下文。当你说“price”,LLM 可能找到 “$299.99” 或 “299.99”。Zod 的z.number()会确保最终输出是数字299.99。z.boolean()会让 LLM 去判断页面上是否有“Out of Stock”或“Add to Cart”按钮来推断库存状态。这种“声明式数据提取”大大减少了后续数据清洗的工作量。
4.3 连接外部工具:MCP 客户端集成
HyperAgent 内置了 MCP(Model Context Protocol)客户端支持。MCP 是一种让 LLM 安全、可控地使用外部工具和数据的协议。通过集成 MCP 服务器,你的 HyperAgent 可以突破浏览器的限制,与数据库、API、文件系统、甚至其他软件(如 Google Sheets)进行交互。
一个典型的场景是:从网页抓取数据,然后自动写入 Google 表格。
const agent = new HyperAgent({ llm: { provider: "openai", model: "gpt-4o" }, debug: true, }); // 初始化 MCP 客户端,连接到一个 Google Sheets 的 MCP 服务器 await agent.initializeMCPClient({ servers: [ { command: "npx", args: [ "@composio/mcp@latest", "start", "--url", "YOUR_COMPOSIO_GOOGLE_SHEETS_CONNECTION_URL", // 需要从 Composio 等平台获取 ], }, ], }); // 现在,你可以给 AI 一个包含跨工具操作的复杂指令 const result = await agent.executeTask(` 1. Go to https://news.ycombinator.com 2. Extract the top 10 story titles and their points. 3. Open (or create) a Google Sheet named "Hacker News Top Stories". 4. Write the extracted data into the first two columns of the sheet. `); console.log(result.output); // 可能会输出类似“数据已成功写入 Google Sheets,链接是...”这个例子展示了 HyperAgent 作为自动化“中枢”的潜力。它不仅能操作浏览器,还能通过 MCP 协调其他工具,完成端到端的业务流程自动化。目前,除了 Composio,社区也在为 Slack、Notion、GitHub 等开发 MCP 服务器,生态正在快速扩展。
4.4 云端扩展与隐身模式
对于大规模爬取或需要高并发执行的场景,在本地运行浏览器实例很快就会遇到资源瓶颈。HyperAgent 可以与 Hyperbrowser 云服务无缝集成。
const agent = new HyperAgent({ browserProvider: "Hyperbrowser", // 切换到云浏览器提供商 // llm 配置... // 环境变量中需要设置 HYPERBROWSER_API_KEY }); // 接下来的所有操作都会在云端浏览器中执行 const result = await agent.executeTask("Scrape product listings from 10 different e-commerce sites");云端模式的好处是显而易见的:弹性伸缩、无需管理本地浏览器环境、更好的 IP 匿名性(对于防屏蔽很重要)。Hyperbrowser 还提供了内置的隐身模式,通过一系列技术手段(如修改 WebGL 指纹、字体列表、Canvas 指纹等)来让自动化浏览器更难以被网站的反爬虫机制检测到。
关于隐身模式的思考:虽然这个功能很强大,但必须负责任地使用。请务必遵守目标网站的robots.txt协议,并控制请求频率,避免对对方服务器造成压力。自动化工具赋予我们能力,也要求我们承担相应的伦理和责任。
5. 常见问题、调试技巧与性能优化
在实际使用中,你肯定会遇到 AI 不按预期执行的情况。别担心,这是常态。下面是我踩过无数坑后总结出的排查清单和优化建议。
5.1 AI 执行失败或行为怪异
问题现象:page.ai()执行后没达到效果,或者点击了错误的元素。
排查步骤:
- 开启调试模式:初始化
HyperAgent时设置debug: true。控制台会输出 LLM 的思考链(Chain-of-Thought),你能看到它是如何理解你的指令、如何分解步骤、以及它认为当前页面上有哪些可操作元素。这是最重要的调试信息。 - 检查页面加载状态:在调用
ai()或perform()前,确保页面已经完全加载。使用await page.goto(url, { waitUntil: 'networkidle' })或await page.waitForLoadState('networkidle')。AI 是基于当前 DOM 快照做决策的,如果页面还在加载,它的决策依据就是错误的。 - 简化并精确化指令:AI 不是人,它需要清晰无歧义的指令。将“找一下便宜的商品”改为“在页面左侧的筛选器中,找到‘价格’滑块,将上限设置为100美元,然后点击‘应用筛选’按钮”。多用名词,少用代词。
- 启用视觉模式:如果页面元素没有清晰的文本标签(比如一个图标按钮),或者布局非常复杂,尝试在
page.ai()中设置enableVisualMode: true。这会让 AI 看到页面截图,从而根据视觉特征定位元素。 - 分而治之:如果一个复杂的
ai()指令失败了,尝试把它拆分成几个更小的ai()或perform()指令。先让 AI 完成第一步,你检查结果,再执行第二步。
5.2page.extract()提取数据不准确
问题现象:提取到的字段为空、错位,或者格式不对。
解决方案:
- 优化 Schema 描述:Zod Schema 中的
.describe()是你的好朋友。尽可能详细地描述每个字段。例如,不要只写price: z.number(),而是写price: z.number().describe(“The product’s current price, usually a number with a dollar sign like $29.99, ignore any strikethrough or original prices”)。 - 限定提取范围:在给
extract()的指令中,明确指定从页面的哪个区域提取。例如,“从 id 为search-results的 div 容器中提取所有产品信息”,或者“只提取主内容区域(main标签内)的表格数据”。 - 后处理验证:对于关键数据,可以在提取后加入简单的验证逻辑。比如,检查价格是否为正数,日期格式是否符合预期。如果验证失败,可以尝试重新提取或记录错误。
5.3 性能优化与成本控制
HyperAgent 的消耗主要在两方面:LLM API 调用和浏览器资源(本地或云端)。
优化策略:
- 优先使用
page.perform():对于所有明确的、单一的操作,坚决用perform()代替ai()。这是降低成本和提升速度最有效的方法。 - 善用
useDomCache: true:在单个page.ai()调用中,如果涉及多个步骤,务必开启此选项。它能避免重复的 DOM 获取和解析。 - 合理选择 LLM 模型:对于不需要复杂推理的简单指令(如点击、输入),可以使用更小、更便宜的模型,如
gpt-4o-mini。只在处理复杂视觉任务或逻辑时使用gpt-4o或claude-3-5-sonnet。 - 实现动作缓存:对于需要重复执行的稳定流程,务必使用前面介绍的 Action Caching 功能。第一次生成缓存后,后续执行几乎零成本。
- 管理页面生命周期:避免频繁创建和关闭浏览器页面。如果有一系列任务要在同一个网站进行,尽量复用同一个
page对象。任务全部完成后,再调用agent.closeAgent()来清理资源。
5.4 稳定性与错误处理
自动化脚本需要长期稳定运行,良好的错误处理机制必不可少。
async function robustAiTask(page, instruction, maxRetries = 2) { let lastError; for (let i = 0; i < maxRetries; i++) { try { const result = await page.ai(instruction, { useDomCache: true, // 可以在这里根据重试次数调整超时等参数 }); if (result.success) { return result; } // 如果 AI 返回了 success: false,也视为一种需要重试的失败 lastError = new Error(`AI task failed: ${result.error}`); } catch (error) { lastError = error; console.warn(`Attempt ${i + 1} failed:`, error.message); // 可以在这里加入一些恢复操作,比如刷新页面 // await page.reload(); await page.waitForTimeout(2000); // 等待2秒再重试 } } throw lastError; // 重试多次后仍失败,抛出错误 } // 使用示例 try { await robustAiTask(page, "complete the checkout process"); } catch (error) { console.error("关键自动化流程失败:", error); // 发送警报邮件、记录日志、触发备用流程等 }这个简单的重试包装函数可以处理网络波动、页面临时性加载问题以及 AI 偶尔的“抽风”。对于关键业务流,结合动作缓存和重试机制,能构建出相当鲁棒的自动化解决方案。
经过几个月的实战,HyperAgent 已经成了我处理网页自动化任务的首选工具。它并没有完全取代传统 Playwright 脚本,而是提供了一种更高维度的互补方案。对于快速原型、处理变化频繁的页面、或者需要自然语言交互的场景,它的价值无可替代。而它的 Action Caching 和 MCP 集成等特性,又让它具备了支撑生产级应用的能力。如果你也在为脆弱的自动化脚本而烦恼,或者想探索 AI 如何改变人机交互的方式,HyperAgent 绝对值得你花时间深入尝试。