ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

AI操作员:大模型驱动的浏览器智能代理实战解析

AI操作员:大模型驱动的浏览器智能代理实战解析

先说结论:这个「AI 操作员」本质上是一个运行在浏览器里的智能代理,它把自然语言指令翻译成连续、可验证的浏览器操作序列。我在实际开发与长期使用过程中,完整走通了需求拆解、动作执行、结果校验这一整套闭环,也踩了不少坑。下面把整个项目的思考过程、核心技术点、落地实操和排错经验一次性讲清楚。

很多人第一次听说「给浏览器装 AI 操作员」时,第一反应都是:这不就是个浏览器自动化脚本吗?还真不是。脚本要提前把每一步写死,AI 操作员则是你用自己的话说需求,它自己去理解页面、决定怎么操作、执行并确认结果。拿我自己的例子来说,有一次需要把某个行业数据后台里的几百条记录逐条导出并整理成表格,过去这种活至少手动折腾两小时,纠结就纠结在那些反人类的翻页按钮和加载延迟上。把需求描述清楚后,我只需要在旁边看它自己一步步点下去,偶尔在聊天框里补一句“下一页加载完再取数据”,它就能继续执行。

这个项目最适合三类人:一是每天要在网页里做重复性信息整理和表单操作的普通上班族,二是做爬虫和自动化测试但被页面结构频繁变动折腾到头秃的开发人员,三是想理解大模型如何跟真实世界交互的学习者。它不追求完全取代人类操作,而是把那些“有套路但不复杂”的网页操作接管过去,让人只做判断和输入需求。

1. 项目起源与需求拆解

1.1 为什么需要“AI 操作员”而不是传统自动化工具

传统自动化方案的核心问题是脆。用 xpath 或 css 选择器写死的脚本,只要前端布局一改动就全军覆没。这种脆弱性不仅体现在定位元素上,更体现在流程上:真实用户操作页面时,会遇到弹窗遮挡、内容异步加载、按钮状态变化等各种突发情况。写脚本的人得穷举这些分支,工作量巨大。

AI 操作员则换了一条思路。它不依赖固定的选择器和预定义流程,而是依赖对页面语义的理解。面对一个页面,它看到的是这个页面的文字内容、按钮含义、区块结构,以及当前视口里最重要的信息。基于这个理解,它把用户的那句“帮我找到最近的几家供应商并整理联系方式”转化成一系列具体动作。这种方案的描述性非常强:页面怎么变,模型就去理解变化后的新页面,而不是死守着某个已经失效的旧路径。

我在项目里做过一次对比:让传统脚本和 AI 操作员分别去完成同一个“提取搜索结果第一页所有标题链接并打开前两条详情页”的任务。脚本的方案跑了两个月后,因为目标网站改版直接失效;AI 操作员从头到尾没有改过一行代码,只是每次执行时多花了一两秒去理解新页面结构,照样顺利跑完。这个对比基本说明了存在价值。

1.2 技术方案选型:为什么选择“大模型驱动浏览器”路线

做这类工具,市面上能走的路大概有四条。第一条是纯模拟鼠标键盘坐标的 RPA 方案,优点是可以操作任意桌面软件,但致命缺点是屏幕分辩率一变、窗口位置一变就可能错位,在浏览器这种动态渲染的环境里太不稳定。第二条是纯 DOM 注入方案,直接在页面里执行 JS 找元素,操作速度快,但难点在于大模型只能看到文本化的 DOM 摘要,多框架渲染出来的复杂页面动辄上万个节点,超长文本容易让模型“读晕”。第三条是视觉方案,让模型看截图,理解页面像人看屏幕一样,直观但速度慢、识别精度受图像质量影响。第四条就是把 DOM 摘要和视觉理解结合起来,这也是我最终采用的混合路线。

具体做法是:先通过浏览器扩展在页面侧提取可访问性树和主要 UI 区块,将其压缩成结构化的文本描述;同时截取当前视口的图片交给多模态模型判断整体布局。动作决策层则交给大语言模型,它根据用户指令、文本化页面结构、最新截图和历史操作记录,输出一条格式化的动作指令。底层操作层用浏览器开发者协议来执行点击、输入、滚动等动作。这套组合的最大优势是把“理解”和“执行”彻底分离:理解出错时我能快速替换模型,执行出错时我能单独调试操作层,互不干扰。

1.3 目标边界:哪些任务适合交给 AI 操作员

做任何工具都得先明确不做什么,不然就是给自己挖坑。经过长期实测,任务边界大致可以按下面这张表划分:

适合交给 AI 操作员暂时不建议交给它
信息检索、筛选、摘要整理需要登录关键账号的高风险敏感操作
表单填写、选项选择、提交涉及大额支付的交易流程
多页面翻页遍历、数据采集需要上传本地敏感文件的场景
定时监控页面变化并推送提醒验证码密集且必须人工识别的页面
内容发布、日程预订强依赖人类主观判断的决策
页面状态对比、异常检测需要处理物理操作之外的其他任务

这个边界判断不是凭空拍的,而是在实际使用中总结出来的。比如表单操作确实很适合,但前提是提交前的最终确认必须交给用户:AI 操作员把表单填好之后,不直接点“提交”,而是停下来聊天框里问我“信息已填好,请核对后回复继续”,我再确认后才执行提交。通过这种权限控制,既保留效率,又避免灾难性误操作。

2. 核心技术原理与架构设计

2.1 从一句话到一系列操作:任务是如何被拆解的

一句“帮我整理这个列表页的所有文章并生成摘要”看似简单,但在系统内部至少要拆成六个子决策:

  • 目标识别:用户说的“文章”指的是页面上哪个区块?标题还是正文?
  • 边界约束:所有文章是多少条?分页到什么程度算结束?
  • 执行路径:先滚动页面收集列表?还是直接读取可见区域的链接?
  • 验证条件:怎么判断一篇文章已经成功打开?
  • 输出格式:摘要是存成 Markdown 文件还是直接在聊天窗口里列出?
  • 异常处理:遇到打不开的链接怎么处理?跳过还是重试?

我的做法是把这六个子决策写成一个结构化的任务规划模板。大模型拿到用户自然语言后,先根据模板生成一张任务清单,然后逐项执行。任务清单是动态的,执行过程中如果发现用户指令有歧义,系统会在聊天框里明确提问,而不是瞎猜。

比如我最初测试时让它在电商页面“找到性价比高的蓝牙耳机”,它真的就只点了排序“价格从低到高”,完全忽略“性价比”这个主观判断。后来改成策略:遇到模糊主观描述,先回聊天框确认澄清条件,比如追问“是否需要在评分 4 星以上再选价格最低的”。这一改动让任务完成准确率提升了非常多。

2.2 浏览器的“眼睛”:AI 如何读懂网页内容

这是整个项目里最有技术含量也最容易被低估的部分。大模型并不知道网页在屏幕上长什么样,它只能看到我塞给它的 token 文本。所以我必须把网页翻译成模型能高效理解的语言。

最开始我试过直接把整段 HTML 源码丢给模型。效果非常差,几千行 HTML 里有大量样式类名、事件绑定、注释噪声,模型很快就被无关信息淹没。后来改用可访问性树的序列化,只保留元素角色、名称、值、可见状态和层级关系,一个复杂页面能被压成几百行结构化文本。但这个摘要天然依赖前端语义化的程度,如果页面里到处是 div 套 div,没有语义标签时,可访问性树的质量也会下降。

所以我又叠加了视觉理解。截图由多模态模型负责,每两到三步截一次当前视口,结合文本来判断页面真实状态。这套方案落地后遇到的最大问题是 token 消耗严重,截图按像素算费用,跑一个复杂任务可能要调用几十次视觉接口。优化办法是降低截图频率,只在页面发生明显变化且需要理解布局时才调用视觉模型,常规的下一步动作主要靠文本摘要完成。

2.3 系统架构与数据流设计

项目整体架构可以分成四层。最外层是人机交互层,也就是聊天面板;第二层是任务编排层,负责接收用户指令、调用大模型、维护任务状态;第三层是浏览器控制层,负责跟浏览器通信,执行具体动作;最底层是页面感知层,负责生成文本摘要和截图。

数据流是一个循环。用户聊天输入进入任务编排层,编排层调用大模型生成当前动作指令;动作指令下发到浏览器控制层,浏览器执行并在页面产生变化;变化后的页面重新被页面感知层采集,生成新的观察结果回传给编排层。编排层把观察结果累积进记忆池,让大模型在决定下一步动作时能参考前面几步的状态。整个循环一直持续到大模型认为任务目标已经达成,或需要用户介入确认。

这里有一个很容易被忽略的设计点:记忆池必须按轮次管理,而不是一股脑堆积所有历史信息。我一开始把所有历史观察都塞进上下文,导致模型注意力被大量旧信息分散,经常执行过时动作。后来给每条记忆加了时间戳和任务阶段标签,每轮决策时只检索跟当前阶段相关的近几轮记忆,效果立竿见影。

3. 关键模块实现与实操要点

3.1 整体目录结构与依赖准备

先看目录结构,这里给出我在项目中实际使用的组织方式:

ai-operator/ ├── chat_panel/ # 聊天面板 UI │ ├── chat_box.py │ └── message_queue.py ├── orchestration/ # 任务编排层 │ ├── task_state.py # 任务状态机 │ ├── planner.py # 任务规划与拆解 │ └── memory.py # 上下文记忆管理 ├── perception/ # 页面感知层 │ ├── accessibility_snapshot.py │ ├── screenshot.py │ └── layout_summarizer.py ├── control/ # 浏览器控制层 │ ├── action_executor.py │ ├── selector_strategy.py │ └── wait_conditions.py └── utils/ └── json_schema.py

依赖方面主要有三类:浏览器开发者协议的客户端库用于控制浏览器,负责和浏览器独立进程通信;大语言模型接口针对文本决策和视觉理解两个场景分别接入;扩展开发工具用于挂载聊天面板到浏览器。开发环境我用的是 Python 后端配合 JavaScript 扩展前端,前后端通过 WebSocket 通信。

3.2 任务状态机:从“执行”到“验证”的闭环

状态机是整个系统的定海神针。没有状态机的时候,大模型输出什么动作就执行什么动作,执行完就直接进入下一轮,中间缺了一个“验证”环节,导致经常出现“动作做了但没生效”还继续往下的情况。

我设计的任务状态机包含七个状态:

状态名含义进入条件
INIT等待用户下达初始指令会话开始
CLARIFY向用户提问澄清信息任务描述有歧义
PLAN生成任务执行计划用户指令明确
EXECUTE执行具体浏览器动作计划中的下一步就绪
VERIFY验证上一步动作是否生效动作执行完成
ADJUST发现动作失败,调整策略验证结果不符合预期
DONE任务完成,汇报结果所有计划项验证通过

循环核心是 EXECUTE 到 VERIFY 再到 EXECUTE 的转换。比如大模型决定点击“下一页”按钮,点击动作完成后先不急着采页面数据,而是验证当前页面里是否出现了新一轮列表项,如果没有出现,就回到 ADJUST 状态,尝试滚动到按钮位置再点击一次或更换点击方式。这个闭环把准确率提升到了可以正式使用的水平。

3.3 动作执行器的动作封装与安全控制

动作执行器把所有浏览器能力封装成七种原子操作:导航、点击、输入、滚动、提取、悬停、按键。大模型只能通过这七种操作和页面交互,不能直接触发脚本命令。这样做的好处是安全可控,不破坏性动作没法被模型调用。

每种原子操作都有统一的调用格式:

{ "operation": "click", "target": { "ref": 12 }, "description": "点击列表中的第三条搜索结果链接", "expected_outcome": "当前标签页跳转到详情页面" }

这里重点说一下 target.ref 这个字段。早期我让模型直接输出 css 选择器,结果经常触发无效动作。原因是前端框架生成的动态类名每次刷新都不一样,模型基于旧的页面摘要给出的选择器没有多大意义。后来改成给每个可交互元素分配唯一 ref 编号,页面摘要里直接写着“ref 12:链接:{标题文字}”,模型只需输出对应的 ref,执行时才去查找具体元素。这一改不仅提升了动作准确率,也大幅降低了 token 开销,模型不再需要记住冗长选择器。

3.4 页面感知层:如何把网页压缩成有效摘要

页面感知层的核心函数是生成可被模型高效理解的页面摘要。我给摘要设置了几个固定区块:页面标题和 URL、当前主要区域描述、可交互元素列表、当前可见区域的文本片段、以及与任务可能相关的数据表格结构。

可交互元素列表的生成规则是:优先采集链接、按钮、输入框、下拉框和复选框五类元素;每类元素只保留前 N 条;对列表页类的重复结构,按模板压缩成一条摘要记录。这样能避免一个页面上几十条类似链接全部罗列导致的 token 浪费。

生成这个摘要的过程需要特别留意动态渲染的页面。有些前端框架是等数据加载完成才生成交互元素,感知层必须在合适的时机触发采集。我在采集前加了等待策略,如果一个页面在滚动后内容变化,会等待网络空闲后再采集,避免摘要采到半渲染状态。

3.5 聊天面板与任务执行的交互设计

聊天面板不只是输入框,它是整个操作过程的透明面板。除了接收用户指令,还要展示每一步动作的理由和结果。每执行一个动作,面板上都会出现一条操作记录,格式是:动作说明、执行时间、验证结果。用户可以随时在面板中输入“停止”“撤销上一步”“换个排序方式”等意图,系统会把这些即时指令当作对任务计划的一次修正。

这种设计解决了自动化工具“黑箱执行”的天然信任问题。用户看着操作记录一步步执行,能清楚知道系统在哪一步做了什么,也方便在出错时准确介入。我特意在面板底部加了“暂停执行”按钮,点击后所有浏览器动作立刻挂起,模型当前决策也被冻结。这个按钮在关键表单提交前是最安全的保障,强烈建议任何实现都保留类似的急停机制。

4. 实操过程:五个典型任务完整走一遍

4.1 任务一:在资讯网站上筛选文章并生成摘要

这个任务是纯信息检索加内容提炼,最能体现 AI 操作员的价值。我给它的指令是:“在这个新闻网站的科技频道里,找出今天发布的关于人工智能行业的五篇文章,打开每篇文章提取核心观点,最后汇总成一段概述。”

执行过程大致是这样的:系统先导航到科技频道列表页,摘要生成当前页全部文章标题和发布时间,将发布时间过滤出来;发现今天的文章不够五篇,继续点击下一页;每找到一篇目标文章就点击打开,在详情页里提取导语和标题关键词,然后返回列表继续。整个流程耗时不到三分钟。人工做的话至少是十分钟起步。

这里有一个值得说的细节:在判断文章是否为“今天发布”时,系统并没有去解析具体时间字符串,而是依据页面摘要里相对时间的语义理解,比如标题下的“2 小时前”或“今天 10:30”。模型对这种自然语言时间的判断非常稳定,反而是硬编码解析绝对时间经常被各种时区格式搞乱。

4.2 任务二:填写表单与预订类操作

表单填写是效率提升最明显的场景,也是最需要安全控制的场景。我的测试任务是在某个活动报名页面上填写报名信息并提交。

系统先读取页面所有输入框和标签,生成对应的表单摘要;然后根据我聊天中提供的姓名、职位、手机号等字段开始逐个填写。遇到下拉框选项时,它读选项列表后选择对应项。遇到必填而我没提供的字段,它不会乱填,而是明确在聊天框里问我。全部字段填完后,它不是直接提交,而是把填好后的表单摘要发给我确认,我说“没问题”之后才执行提交。

这个流程走下来能明显感受到交互设计的重要性。如果系统自顾自地填完就提交,我绝不会放心让它处理含个人信息的表单。把确认权留在用户手里但不打断整体流程,是这类工具能够进入实际生产环境的关键分水岭。

4.3 任务三:多页面信息整理与导出

这个任务考验的是跨页面信息聚合和格式结构化能力。我让它去某个企业信息查询平台,按指定行业和地域筛选企业,列出前十条企业名称、联系人、电话和地址,然后输出成表格。

执行时系统在列表页把十条企业链接全部采集下来,逐条打开详情页提取联系信息,每完成一条就更新目标列表。这个任务最麻烦的不是跳转,而是页面时不时弹出的广告弹窗。系统每次打开新详情页后,先判断当前页面是否被弹窗覆盖,如果是,就找到关闭按钮点击,然后再正常提取信息。

这个任务让我意识到一个问题:上下文累积非常快,十家企业的联系信息逐条累积下来,模型上下文可能越来越长。解决办法是把已经提取成功的结构化信息固化到任务输出文件里,从记忆池中移除原文细节,模型只保留“已完成前 N 条,剩余 M 条”的状态。这样即使任务执行上百步,上下文长度都能保持稳定。

4.4 任务四:定时监控与页面变化提醒

监控类任务是 AI 操作员里“长跑型”的典型。我把某个商品价格监控页配置成每三十分钟检查一次,对比当前价格和上次记录,如果价格波动超过设定阈值,就通过聊天面板发送提醒。

执行逻辑非常简单,但有个工程上的坑:定时监控不能重复加载整个扩展的上下文,否则模型消耗会持续累积。正确做法是每次监控检查用全新会话,只携带监控任务描述、上次状态快照和当前页面摘要。这样每次运行的成本几乎恒定,不受监控时长影响。

做监控方案时还会遇到另一个问题:有些页面在无操作状态下会自动要求重新登录。因此长时间监控必须在感知层之外加一个会话保持机制,定期刷新访问凭证。否则跑到半夜突然全部任务中断,第二天一看全红了。

4.5 实操中的性能优化与成本控制

性能优化主要体现在 token 成本控制和时间开销上。如果你计划长期使用,下面几个优化策略一定要落实。

第一,页面摘要的 token 预算要设上限。我用的方案是把摘要分成低中高三个档位,普通操作只用低档位摘要;只有当模型判断当前阶段需要评估全局布局时才请求高档位摘要。第二,截图要经过预处理。原始截图像素范围太大,模型视觉需要分辨的细节反而不多,截取后先压缩尺寸,再把与任务无关的空白区域裁掉。第三,动作执行时合理使用浏览器缓存,尽量避免重复加载相同静态资源。第四,针对高频操作路径建立动作模板缓存,比如翻页、回到列表页这类固定动作,模型不需要每次从头推理。

成本方面,一次中等复杂度任务(拆成二十个左右动作)按当前模型接口的市场价来算,大致在几角钱到一两块钱之间。这个成本对个人用户来说完全可以接受,比请人手工操作便宜太多。

5. 常见问题与排查技巧实录

5.1 问题一:AI 误解指令导致错误操作

这是遇到频率最高也最难排查的问题。表现是大模型理解的任务目标和用户真实意图存在偏差,而且偏差往往在执行几步之后才暴露。有一次我说“把结果按更新时间排序”,系统却按发布日期排序,因为在页面摘要里“更新”和“发布”两个字段非常相似,模型没有意识到它们本质上是不同含义。

排查思路是回归还原。先打开那一步时刻的页面摘要快照和模型决策原文,确认模型依据了什么信息判断;然后可以在聊天面板里直接追加一句更精确的约束,比如“注意排序字段是更新时间不是发布日期”。之后我发现,在任务指令里主动给出精确字段名和页面元素名的对应关系,远远比让模型自己猜效果好。一句话的差别,准确率可能直接从六成升到九成。

5.2 问题二:页面元素定位失败

页面元素定位失败的典型表现是:模型明明输出了一个存在的 ref 编号,但执行器报错找不到元素。原因通常有两种。一种是页面是动态渲染的,摘要生成时元素在 DOM 里,执行时元素被重新渲染导致引用失效。另一种是元素在视口之外,浏览器要求元素可见才能点击。

解决思路分两步。第一步,在执行点击前先做元素状态检查,发现元素没有出现在当前视口就自动滚动。第二步,如果元素在渲染后被替换成新节点,就在执行层加一层重试逻辑,重新请求页面摘要再定位一次。这个重试机制要求模型在首次定位失败时不要盲目换策略,先刷新观察结果再判断是否还是同一个目标。

5.3 问题三:动态加载内容与无限滚动页面

无限滚动页面在传统爬虫脚本里是个老大难,对 AI 操作员同样存在。列表页下拉到一定高度就会加载新内容,AI 一开始不知道什么时候该停止,很容易一路滚到底,浪费大量 token 在采集重复数据上。

我的解决思路是在任务计划阶段就明确“采集退出条件”。如果是固定列表,直接以列表项总数作为退出条件;如果是无限流,就以连续几次滚动后新增内容条数是否低于阈值作为判断标准。验证逻辑用自然语言描述给模型比硬写一个检测函数更灵活,但为保证稳定性,还是会在感知层配合一个重复内容检测函数,防止模型被重复数据误导。

5.4 问题四:登录墙与验证码

登录墙是 AI 操作员目前最难过的一道坎。视觉模型虽然能识别验证码图片,但识别精度达不到生产级水准,尤其是各种变形扭曲的滑块验证码,成功率很低。我的处理原则是:凡是遇到验证码,一律放弃当前动作,把验证码截图发给用户,请求人工处理。

真实场景里我见过不少人硬着头皮让 AI 去解验证码,结果不是账号被风控就是任务卡死。务实的做法是把验证码环节处理成一个人机协作点:验证码出现自动暂停,用户在聊天面板上手动确认通过后继续。实测下来,这种协作模式既满足自动化效率,又把安全风险控制住,稳定性反而比全自动方案高。

5.5 问题五:任务突然中断与执行状态恢复

浏览器页面崩溃、网络波动、模型接口超时都可能导致任务执行中断。任务重启后如果从零开始跑,成本高且容易重复执行破坏性操作。所以任务编排层必须支持检查点恢复。

我的方案是每完成一个计划步骤,就把当前任务状态(已完成步骤、关键数据、当前页面 URL)持久化到本地存储。重启时读取最近的检查点,从最近一个未验证状态继续执行。这个功能实现难度不大,但对使用体验的提升最关键。有了它,你才敢让任务在无人值守时长时间运行,不然凌晨跑挂一次,第二天回来看到进度全丢,心态直接崩。

5.6 安全清单:权限模型设计

最后必须要给所有想复现这个项目的人一套安全底线。AI 操作员本质上是把浏览器控制权交给了大模型,权限控制做得不够,后果很严重。我的安全模型由五条规则构成:

  • 第一,凡是涉及提交、删除、转账、发送等高风险动作,必须经过用户确认。
  • 第二,敏感信息字段的读取结果,不在模型上下文里全文保留,只保留摘要。
  • 第三,所有下载、上传操作默认禁止,需要用户显式开启。
  • 第四,操作记录全程留痕,便于事后审计每一步决策。
  • 第五,页面跳转到未知域名时,切换为新会话或主动提醒,避免模型被钓鱼页面诱导。

这些规则不一定面面俱到,但缺了任何一条都可能在实际使用中翻车。做这类工具不是把功能做得越多越好,而是要把操作边界定义得足够安全。

我个人在实际使用中体会最深的一点是:AI 操作员的真正价值不在于它能否像人一样完成所有操作,而在于它把人和机器的能力重新做了分工。机器负责重复点击、信息遍历、格式整理,人负责目标定义、关键决策和异常介入。未来如果能进一步降低模型决策成本,把操作速度和稳定性再做提升,这类工具可能会逐渐成为浏览器的标配组件。最后再分享一个实用小技巧,任务开始前先花一分钟把目标页面的关键区块和按钮在实际摘录里的显示方式摸透,在聊天指令里准确描述这些区块特征,你的任务成功率会有质的变化。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进