返回博客

AI Agent 网页任务不稳定的四类来源与工程做法

Agent 做网页任务时,失败常常发生在定位元素、等待超时、状态保存和环境拦截这四类环节。把步骤做成幂等、失败可重试、状态落盘、按任务隔离环境,成功率会稳得多。

刚开始做网页自动化,思路往往很直接:把流程写出来,让脚本跑起来。逻辑看着没问题,任务却总是零散地失败,账号状态也时不时冒出异常。第一反应是查代码,但排查到最后会发现,问题集中在四个地方。

AI Agent 网页任务不稳定的四类来源与工程做法的关键步骤与判断维度示意图

页面一改,定位就失效

多数脚本靠选择器找元素。选择器一旦写死,页面上任何一次调整都可能让它落空:按钮换了类名、文案改了一个字、某个区块从服务端渲染改成异步加载、元素被包进新的容器。运营侧做一轮 A/B 测试,同一个页面在不同账号那里看到的结构甚至都不一样。

表现通常是元素找不到、点击打偏,或者点到了同名但位置不同的控件。这类失败不是网络抖动,重试几次也不会好。

可行的做法是少依赖绝对路径:优先使用可访问性属性、稳定的业务 ID,或者元素之间的相对关系来定位;对同一类页面准备备选选择器,主选择器失效时自动降级。页面里存在 iframe 或 Shadow DOM 时,要先把上下文切对,否则定位一定失败。

等待和超时定错了区间

等待时间设得太短,元素还没渲染出来就被判失败,看上去像脚本有 bug;设得太长,单条任务耗时被无限拉长,吞吐掉下来,超时还会把真正的错误盖住。

比固定 sleep 更靠谱的是显式等待:等一个具体条件成立,比如目标元素出现、某个请求返回、加载动画消失。超时预算要分层设置,单步的、单页面的、整个任务的各有一套,并且逐层收敛,不要所有环节都用同一个值。

还要区分页面可用和业务结果已生成这两种等待。前者等 DOM 就绪通常够用;后者得等接口回调或者页面上的状态文案变化,等错了就会出现操作看着成功、数据其实没写入的情况。

多步任务走到一半,进度丢了

注册、下单、发布这类任务动辄十几步。进程中途退出(超时被终止、浏览器崩溃、宿主机重启)时,如果状态只放在内存里,下次执行要么从头再来,要么把上一步重复提交一遍。

重复执行的后果比单纯失败更难查:同一笔操作被执行两次,上游系统多出一条记录,还找不到来源。

办法是让每一步都有落点。每完成一步,就把进度写进一个可以持久化的位置,带上任务的唯一标识;重启之后从最后一次成功的地方继续。这一步用不上复杂框架,一个文件或一条状态记录就够。

环境侧被拦下,表现和代码错误一样

前三类问题出在任务内部,还有一类来自环境侧。站点会综合浏览器特征、访问行为、网络来源判断访问来源,一旦判定可疑,可能返回验证页、返回空内容,或者直接超时。从任务日志上看,这和执行错误几乎没有区别。

常见诱因有这么几个:

  • 出口 IP 的归属地、时区、语言三者对不上
  • 所有任务都从同一个浏览器环境发出请求,单位时间的请求密度明显高于真实用户
  • 环境频繁更换,或者账号反复重新登录

四件把成功率抬起来的事

  1. 每一步都做成幂等。执行前先确认前置条件是否已满足,动作重复执行不产生额外副作用。查询类操作天然幂等,写操作要靠唯一标识或去重键兜底。
  2. 把失败分类。临时性的(元素还没渲染、网络抖动、接口返回 5xx)可以退避重试;确定性的(账号被限制、参数不合法、目标资源不存在)重试多少次都一样,直接标记终止,别让它一直占用并发额度。
  3. 状态定期落盘。进度、中间产物、当前步骤都持久化,任务重启后接着跑,而不是从第一步重来。
  4. 按任务隔离运行环境。每个账号或每条任务对应一个独立的浏览器环境,Cookie 与本地存储互不共享,指纹特征有合理差异,时区与语言跟出口 IP 的地区保持一致。

第四件事在任务规模上来以后尤其关键。几十上百条任务并发跑的时候,环境这一层决定了稳定性的上限,也决定了出问题时影响面有多大。PurpleMark 在这类场景里提供的就是按需创建、批量回收独立环境的能力,每个账号一套自己的环境,任务之间的状态不会互相污染。

以上内容仅用于技术研究与开发实践分享,请在合法合规的前提下使用相关技术,并遵守目标平台的服务条款。