从 Page-Agent 到浏览器插件:打造你的第一个 AI 网页助手
为什么我们需要一个浏览器 Agent你有没有遇到过这种场景刷到一个不错的技术文章想提取关键内容结果要手动复制粘贴半天想在某个网站填个表单同样的信息要输三遍看到一个弹窗不知道怎么关瞎点半天差点误操作。这些都是人适应机器的典型症状。传统网页自动化工具Selenium、Puppeteer本质上是在用代码模拟人的操作——你要告诉它「点哪里、填什么」它才能执行。本质上你还是在写代码。但用户不应该需要写代码。Page-Agent 给了我一个完全不同的思路让 AI 直接理解网页结构用自然语言控制界面。用户说「帮我填写这个表单」AI 自动识别表单字段、理解你的意图、执行操作。这才是「所想即所得」该有的样子。核心技术原理从 DOM 到自然语言1. DOM 分析让 AI 读懂网页传统自动化靠截图OCRPage-Agent 的做法更聪明——直接解析 DOM 结构。classDOMAnalyzer{analyze(){constelements[];constiterdocument.createTreeWalker(document.body,NodeFilter.SHOW_ELEMENT);while(iter.nextNode()){consteliter.currentNode;// 提取可交互元素的元信息if(this.isInteractable(el)){elements.push({tag:el.tagName,text:el.textContent.trim(),type:el.type||el.getAttribute(role),placeholder:el.placeholder,selector:this.getUniqueSelector(el)});}}returnelements;}}关键在于语义提取——不仅拿到元素还要理解它是什么。按钮输入框链接有了这些元信息LLM 才能做出正确的决策。2. 意图解析理解用户真正想要什么用户说「登录」可能是找到并点击「登录」按钮填写登录表单完成整个登录流程意图解析器要做的是消歧义constintentawaitllm.decideAction({userInput:帮我登录,pageElements:elements,pageContext:{title:用户中心,hasForm:true}});// 返回{ action: CLICK, target: 登录按钮, confidence: 0.92 }如果置信度不够比如页面上有多个可疑按钮可以要求用户确认或者列出候选让 LLM 再分析一次。3. 操作执行模拟人类行为执行操作不是简单的element.click()——真实用户操作有延迟、有轨迹、有随机性。classActionExecutor{asyncclick(element){// 模拟人类延迟awaitthis.humanDelay(100,300);// 计算目标位置加入微小偏移模拟真实点击constrectelement.getBoundingClientRect();constxrect.leftrect.width/2(Math.random()-0.5)*10;constyrect.toprect.height/2(Math.random()-0.5)*10;// 触发点击事件element.dispatchEvent(newMouseEvent(click,{bubbles:true,cancelable:true,view:window,clientX:x,clientY:y}));}}这个细节很重要——很多网站会检测自动化脚本通过事件特征、时序等加入随机延迟和位置偏移能显著降低被检测的概率。浏览器插件让 AI 真正住在网页里Page-Agent 是一个框架但要把它变成用户能随手使用的工具需要一个载体——浏览器插件就是最好的选择。为什么不是独立应用独立 Electron 应用需要用户下载安装维护多平台兼容处理系统权限浏览器插件呢一行命令chrome load unpacked搞定。核心架构MV3 通信模型Chrome Extension Manifest V3 有三个主要组件┌─────────────┐ chrome.runtime.sendMessage ┌──────────────────────┐ │ Popup │ ──────────────────────────────→ │ Background Worker │ │ 弹出面板 │ │ 后台脚本 │ └─────────────┘ chrome.tabs.sendMessage └──────────┬───────────┘ ┌─────────────┐ ←───────────────────────────────────────────┘ │ Content │ HTTPS 请求 │ Script │────────────────────────────────────────────────→ LLM API │ 注入脚本 │←────────────────────────────────────────────────┘ └─────────────┘ ↓ DOM 操作 ┌─────────────┐ │ 目标网页 │ └─────────────┘Popup用户点击插件图标看到的界面用来输入指令、查看状态Content Script注入到网页中负责提取页面内容、执行操作Background Worker处理 API 调用、消息路由样式隔离Shadow DOM 的妙用插件 UI 和宿主网页的 CSS 可能会冲突——这是个老问题了。解决方案是Shadow DOMconsthostdocument.createElement(div);host.idpage-agent-root;constshadowhost.attachShadow({mode:open});document.body.appendChild(host);// Shadow DOM 内部完全隔离shadow.innerHTMLstyle :host { position: fixed; bottom: 20px; right: 20px; } .dialog { width: 380px; height: 520px; background: white; border-radius: 12px; box-shadow: 0 10px 40px rgba(0,0,0,0.2); } /style div classdialogAI 对话界面/div;Shadow DOM 内部的样式不会泄漏出去外部样式也不会影响进来。完美隔离。消息通信让各组件协作三个组件之间通过chrome.runtime通信// Popup 发送消息chrome.runtime.sendMessage({type:CHAT,payload:{prompt:帮我填写用户名,context:pageContext}});// Content Script 监听并处理chrome.runtime.onMessage.addListener((msg,sender,response){if(msg.typeCHAT){constresultawaitllm.chat(msg.payload);response(result);}returntrue;// 保持消息通道开启});开发实战从零构建一个简化版1. 项目结构my-page-agent/ ├── manifest.json # 插件配置 ├── background.js # 后台脚本 ├── content.js # 内容脚本 ├── popup.html/css/js # 弹出面板 └── ui/ └── agent-dialog.js # AI 对话组件2. manifest.json 配置{manifest_version:3,name:My Page Agent,version:1.0.0,permissions:[storage,activeTab,scripting],host_permissions:[all_urls],action:{default_popup:popup.html},content_scripts:[{matches:[all_urls],js:[content.js],run_at:document_idle}]}3. 内容脚本提取上下文// content.jsclassPageContextExtractor{extract(){return{title:document.title,url:location.href,selectedText:window.getSelection().toString(),mainContent:this.extractMainContent()};}extractMainContent(){// 智能识别文章主体constselectors[article,main,.content,#content];for(constselofselectors){consteldocument.querySelector(sel);if(el)returnel.innerText.slice(0,5000);}returndocument.body.innerText.slice(0,3000);}}// 监听来自 popup 的消息chrome.runtime.onMessage.addListener((req,_,sendResponse){if(req.actiongetContext){sendResponse(newPageContextExtractor().extract());}returntrue;});4. Popup对话界面// popup.jsdocument.getElementById(send-btn).addEventListener(click,async(){constinputdocument.getElementById(user-input);constpromptinput.value.trim();if(!prompt)return;// 1. 获取页面上下文const[tab]awaitchrome.tabs.query({active:true,currentWindow:true});constcontextawaitchrome.tabs.sendMessage(tab.id,{action:getContext});// 2. 调用 LLMconstresponseawaitfetch(https://api.openai.com/v1/chat/completions,{method:POST,headers:{Content-Type:application/json,Authorization:Bearer${awaitgetApiKey()}},body:JSON.stringify({model:gpt-4,messages:[{role:system,content:你是网页助手根据页面内容回答问题或执行操作。},{role:user,content:页面${context.title}\n内容${context.mainContent}\n\n用户${prompt}}]})});// 3. 显示回复constdataawaitresponse.json();showMessage(ai,data.choices[0].message.content);});5. 快速测试# 1. 打开 chrome://extensions/# 2. 开启「开发者模式」# 3. 点击「加载已解压的扩展程序」# 4. 选择项目文件夹# 5. 打开任意网页点击插件图标输入「总结页面内容」进阶功能让 Agent 更智能多轮对话与上下文继承真正的 AI 助手不是「一问一答」而是能记住上下文classConversationManager{constructor(){this.history[];this.maxHistory10;}add(role,content){this.history.push({role,content});if(this.history.lengththis.maxHistory){this.history.shift();// 保留最近 N 轮}}buildPrompt(systemPrompt,newUserInput){return[{role:system,content:systemPrompt},...this.history,{role:user,content:newUserInput}];}}操作序列与回滚复杂任务需要多步骤操作还要支持撤销classActionSequence{constructor(){this.stack[];this.undoStack[];}asyncexecuteSequence(actions){for(constactionofactions){constresultawaitthis.executor.execute(action);if(result.success){this.stack.push(action);}else{// 遇到失败尝试回滚awaitthis.rollback();return{success:false,failedAt:action};}}return{success:true,executed:this.stack.length};}asyncrollback(){while(this.stack.length){constactionthis.stack.pop();awaitthis.executor.undo(action);this.undoStack.push(action);}}}本地模型支持不想把数据发送到第三方可以用Ollama在本地跑模型classOllamaClient{constructor(baseUrlhttp://localhost:11434){this.baseUrlbaseUrl;}asyncchat(messages){constresponseawaitfetch(${this.baseUrl}/api/chat,{method:POST,headers:{Content-Type:application/json},body:JSON.stringify({model:llama3,messages,stream:false})});return(awaitresponse.json()).message.content;}}局限性坦诚地说做这个项目的时候踩了不少坑有些问题是目前技术难以完全解决的1. 验证码这是最大的拦路虎。Google reCAPTCHA、Cloudflare Turnstile 这些玩意儿连人工都得仔细看半天。解决方案目前只能人工介入或者接入第三方打码服务。2. 动态内容很多现代 Web 应用用 React/Vue 构建页面内容是 JS 动态生成的。Content Script 执行时可能页面还没渲染完。解决方案监听 DOM 变化或者加个等待。3. 复杂交互拖拽排序、文件上传、Canvas 操作……这些对浏览器自动化来说都是硬骨头。AI 目前只能处理相对标准化的 UI 模式。4. 模型能力再好的框架也受限于底层模型。要让 AI 准确理解「点第三个商品下面的小字链接」需要足够强的多模态理解能力。GPT-4V 目前能做到但成本不低。未来让 AI 真正「看见」网页长期来看我认为有两个方向值得关注1. 多模态增强纯文本 DOM 分析有局限。真正「读懂」网页需要视觉理解——看到截图就能理解布局、识别按钮。GPT-4V 已经展示了这种能力未来集成进来不是问题。2. Agentic Workflow单次操作能完成的任务有限。真正的价值在于编排复杂工作流——「帮我找一篇关于 React 的最新文章总结要点发布到我的博客生成配图」。这不是一个插件能搞定的需要更复杂的 Agent 架构。但这恰恰是 Page-Agent 展示的方向。写在最后Page-Agent 让我看到了一个趋势前端智能化的浪潮正在到来。以前我们说「前端是用户界面」现在前端也可以是「AI 界面」。网页不只是给人看的也可以给 AI 看、给 AI 控制。当然路还很长。模型能力、交互范式、安全隐私……有太多问题需要解决。但至少我们现在知道了方向在哪里。你准备好打造自己的浏览器 Agent 了吗如果你觉得这篇文章有帮助欢迎关注、点赞、分享。想了解更多前端和 AI 的交叉领域欢迎在评论区交流。

相关新闻

最新新闻

日新闻

周新闻

月新闻