做直播运营最崩溃的时刻是什么我自己的答案是大促当天三个平台的后台同时开着商品要上下架、库存要改、优惠要设置弹幕里还在不断有人问“还有货吗”客服那边又在催我回复。一个人恨不得拆成八个用。所以我做这个项目的初衷其实很朴素——把这一摊重复的网页操作交给Agent自己去跑。项目做到后面我发现真正的难点不在于“调用大模型”而在于Agent怎么访问Web、怎么像人一样看懂网页并操作也就是“Agent的Web访问架构”和“GUI Agent”这两件事。这篇文章就围绕这个项目来写。我会先拆解为什么直播运营场景必须自建一套Web访问架构再讲清楚我把Web访问拆成哪些层然后重点聊GUI Agent如何做到“不用API也能操作页面”最后把实操过程和踩坑实录一起放出来。不管你是做Agent开发、搞自动化还是想给重复的网页操作找一个更聪明的解法这套思路都能直接参考。1. 项目背景直播运营的琐事为什么非要靠 Agent1.1 直播运营的真实痛点平台多、系统杂、全是手工活我服务的直播运营团队同时管理好几个平台每个平台都有独立的商家后台商品中心、订单中心、营销工具、数据报表以及随时需要盯着的弹幕和客服消息。粗略统计一下一场三个小时的直播运营要完成的操作包括但不限于开场前把秒杀商品从“待上架”改成“已上架”对应库存从总仓调到直播间直播过程中根据弹幕反馈随时改价格、加库存、上下架商品下播之后把数据中心里的观看人数、转化率、成交额导出整理成复盘表。这些操作的特点是单看每一项都不难但数量多、频率高、时间窗口短。人在高度紧张的时候特别容易点错比如把“改库存”点成“下架”或者设置优惠时错过一个单位导致整场活动价格异常。以前团队想过写脚本可脚本是按固定的页面结构来的平台改版一次脚本就废掉一次维护成本比请人还高。1.2 不是所有系统都能接 API为什么必须考虑 Web 访问一开始我和很多人想的一样直接用官方API不就行了现实是直播运营涉及的系统里只有一部分提供了完整稳定的API很多关键操作只有网页后台才有。比如直播间秒杀活动的报名入口、部分平台的活动价格设置、弹幕互动指令这些要么API文档缺失要么权限申请流程漫长有的接口就算拿到了也经常限流。这种情况下必须要让Agent具备“直接访问Web”的能力。说白了就是让Agent替人打开浏览器、替人登录系统、替人点击按钮、替人读取页面上的数据。这正是Web访问架构要解决的它不像传统爬虫那样只拿数据还要能做“操作闭环”——看到页面、理解状态、执行动作、确认结果。1.3 从“网页没关”到“Agent 会自己用网页”团队以前也用过半自动化工具本质是把人的操作录下来再回放属于“网页没关脚本照着走”。这套方案脆弱得很只要页面元素的位置稍微变一下回放就断了。而且它不理解页面状态弹窗出来了也不会关页面加载慢了几秒就以为自己点错了。我这次想做的 Agent 是另一条路线它不依赖“录制好的坐标路径”而是理解当前页面在干什么、自己要干什么然后决定下一步怎么点。这就要把“Web访问架构”和“GUI Agent”结合起来。Web访问架构负责解决数据通不通、登录稳不稳、请求顺不顺的问题GUI Agent负责解决“像人一样看屏幕、操作界面”的问题。两者各有分工缺一不可。2. 整体架构设计把 Web 访问拆成两层而不是一条路走到黑2.1 分层设计结构化读取层与非结构化操作层在设计整个系统时我第一件事就是问自己Agent访问Web目标到底有几种答案其实只有两种——拿信息和做操作。拿信息的情况包括查询商品当前库存、读取实时销量、拉取直播间数据报表。这些信息有明确的结构适合走“结构化读取层”。这一层优先走官方APIAPI拿不到就写轻量解析脚本解析网页里的 JSON 数据接口或HTML标签把页面变成干净的字段返回给Agent。这样Agent处理数据时非常高效不用跟大段的HTML较劲。做操作的情况则完全不同比如把一个商品改为“已上架”、把运费模板切换一下、点击报名活动的按钮。这些动作很难通过简单请求模拟因为页面有大量交互逻辑点了按钮后还有二次确认、状态回显、权限校验。这种场景我归到“非结构化操作层”用GUI Agent去做也就是让模型看屏幕截图、识别元素位置、模拟键鼠操作像人一样完成整个流程。这个分层的核心收益是能用简单方式解决的不要拖到复杂方式里。数据读取大多走结构化层速度又快又准而操作类任务交给GUI Agent灵活但不需要频繁执行性能也扛得住。2.2 指挥 Agent任务的拆解、编排与回退光有两层还不够上面必须有一个调度的大脑。我把它叫指挥Agent。它的职责是接收自然语言任务比如“开播前15分钟把A链接设为仅直播间可见库存改成500”然后把它拆成子任务先读取当前商品状态结构化读取层再跳转到商品编辑页非结构化操作层修改可见范围GUI操作确认保存结果结构化读取层。执行中一旦某一步失败由它决定是重试、换条路还是叫人。指挥Agent的引入解决了两个大问题。第一是任务的粒度直播运营的一次任务往往包含多个页面跳转和多次校验如果每次只让底层Agent执行一个动作任务链条很容易断如果让底层Agent一口气做完整件事又要给太多上下文模型容易糊涂。拆成“意图-子任务-动作”三级每一级边界清晰。第二是错误恢复有一次执行商品改价底部“保存”按钮被右侧的悬浮客服窗口挡住了GUI Agent点了好几次都没生效。如果没人管任务就卡死了有了指挥Agent它检测到连续失败后会先让GUI Agent尝试关闭悬浮窗再重新定位保存按钮最后成功通过。2.3 Web 访问架构的选型考量搭建Web访问架构时我对比了不少方案最终的核心选型考量说穿了就三条状态维护、并发隔离、指纹稳定。状态维护指的是登录态和Cookie。直播后台必须有登录态不能让Agent每次都重新扫码登录。我在架构里单独做了一个登录态模块专门维护每个平台账号的Cookie、LocalStorage等会话数据定期验证有效性失效时通过通知提醒人扫码而不是让Agent硬闯登录页。并发隔离指的是多个直播间同时跑任务时相互之间不能干扰。每个直播间对应一套独立的浏览器上下文Browser Context上下文之间Cookie、缓存、LocalStorage完全隔离资源独立。这个设计在后面实际运行时帮了大忙有一场直播在跑B平台任务时A平台任务出了故障不影响另一边的正常执行。指纹稳定是为了降低平台风控误杀的概率。这里不是要对抗任何系统而是说如果Agent每天用不同的浏览器指纹访问后台平台很容易判定异常。我把浏览器指纹User-Agent、Canvas、WebGL等特征固定下来让Agent看起来像一个正常工作的人这样触发风控的概率大幅下降。团队最怕的不是“操作被拒绝”而是操作到一半账号被限制。2.4 为什么不能只用 Playwright要引入 GUI Agent聊到这里有人会问你说得这么复杂Playwright一套不就够了吗它确实能做浏览器自动化点击、输入、跳转、抓取都很成熟。但实际用下来纯靠Playwright有两个绕不过去的坎。第一个坎是元素定位。传统自动化依赖page.click(#submit-btn)这类选择器可直播平台的前端经常改版改一次类名、改一次结构脚本就全挂了。而且很多页面是Canvas渲染或者组件动态渲染DOM里根本没有可用的文本节点你拿XPath怎么写都定位不到。第二个坎是动态变化。直播间的页面状态实时变库存数字在跳、弹幕在滚、秒杀倒计时在走。传统自动化脚本只会按预设流程走页面一出现预期之外的东西就容易崩。GUI Agent解决的就是这件事它不再依赖固定的DOM选择器而是直接把页面截图给视觉模型看模型“看到”页面上哪里有“保存”按钮、哪里有“库存”输入框然后计算出要点击的坐标再通过自动化框架执行鼠标键盘动作。页面结构怎么改只要视觉上还是那个按钮Agent就能继续点。这一步是质的区别——从“脚本在跑”变成了“Agent在用”。3. GUI Agent 的核心实现细节3.1 视觉识别与元素定位不用 DOM怎么看页面GUI Agent最核心的问题就是怎么把一张网页截图变成可操作的动作指令。我实践下来的做法是“层级降维”不要一上来就让模型看整张页面。整张4K截图上元素太多模型容易看漏、看错而且响应速度很慢。我一般先把页面按区域切分顶部导航栏、左测商品列表、中央编辑区、右侧辅助面板、底部操作栏每个区域单独裁剪再交给视觉模型识别。比如要改商品库存时只需要让模型看“中央编辑区”这一块它就能准确找到“库存数量”输入框。这种裁剪后的局部图片识别准确率比整页截图高很多速度也能控制在毫秒级别。定位方式也不只一种我根据场景混用了几类策略定位策略适用场景我的使用频率视觉模型点击截图坐标动态渲染、Canvas页面主力方式DOM文本匹配按钮、链接上有明确文字高占位符/ARIA标签输入框、下拉菜单中图像模板匹配固定图标、品牌Logo低用于补充这个“视觉为主、DOM兜底”的双通道定位方式是我做GUI Agent遇到最有效的组合。直播后台上有些“确认”按钮完全没有文字只有一个小图标纯视觉模型也能认出来但偶尔会把相似图标搞混这时再用DOM附近的title属性辅助判断一下准确率就能拉满。3.2 行动策略点击、输入、滚动、等待动作要稳识别到元素后接下来是动作执行。这个环节看着简单实际上坑最深。点击不是单纯移动鼠标过去按下它涉及到先滚动到元素可见、再判断元素是否被遮挡、然后点击后确认页面状态变化。我为GUI Agent写了一套标准的“行动协议”定位元素坐标后先把对应区域滚动到视口中心避免页面上下偏移导致坐标不准。用自动化框架执行一次“模拟悬停”截一张实时图让模型确认这一步指向的元素是对的。确认无误后执行点击然后等待500到800毫秒截一张点击后的页面图让模型确认“页面状态是否发生了预期变化”。如果状态没有变化自动进入重试逻辑先检查是否有弹窗遮挡、页面是否在加载中最多重试3次超过就上报指挥Agent。这个“动作前确认、动作后校验”的闭环让我在直播场景里的操作成功率从最初的60%左右提升到了92%以上。实测下来慢这半秒钟是非常值得的一次误操作在大促场景造成的损失比这半秒钟宝贵得多。3.3 与浏览器自动化的结合视觉优先DOM 兜底GUI Agent不是凭空在操作系统上点鼠标它仍然要建立在浏览器自动化基础上。我的技术栈是Playwright做底层控制在上面包一层“视觉决策层”。视觉决策层的输入是截图输出是动作目标而真正的执行交给Playwright这样既保留了视觉的灵活性又有了自动化框架的稳定性。这套组合的一个关键优化是“局部刷新截图”不每次截全屏而是滚动或操作后只截变化区域的截图。切换Tab时截新页面点击按钮后只截按钮所在区域这样既能给模型更精准的上下文又能降低接口调用成本。一次完整操作下来我平均只调用视觉模型6到8次比逐像素扫描的方式省钱太多。另外还有一个细节输入文本时不要用type一次性键入要模拟真实的键盘输入节奏。有些直播间后台对快速输入有校验粘贴一串字符很容易触发“疑似脚本操作”的提示而按一定间隔逐个输入字符就稳定得多。3.4 Agent 记忆在 GUI 操作中的作用这里要提一下Agent记忆它和GUI Agent的关系比很多人想象中紧密。做GUI操作时Agent经常需要记住“上一步我在哪、这一步我要去哪、这个页面的哪种元素形态是我上次见过的”。没有记忆纯靠模型看当前截图它每次都是“第一次进这个页面”效率会低很多。我的方案是分两层记忆短期工作记忆和长期页面经验记忆。短期记忆存在任务执行期间记录当前页面URL、已点击过的元素、已填写的表单值保证多步操作不断线。长期记忆则由一次一次成功的操作中沉淀出来同一个平台的商品编辑页我见过它三种不同的“保存按钮”样式全部记录下来下次再遇到类似页面Agent可以直接复用经验不用重新试错。“记忆框架以及选型”这个方向我单独踩过项目结论是如果只是GUI操作记忆不需要上多复杂的向量数据库一个Redis存短期状态一个SQLite存长期经验完全够用。只有当你做跨任务、跨会话的复杂记忆推理时才需要考虑更重的记忆框架。3.5 安全与登录态处理GUI Agent权限很大它能像人一样操作网页这意味着安全隐患也很大。我的处理办法是“最小权限原则”。每个子Agent只被允许访问它该访问的页面路径比如“库存Agent”只能访问商品编辑类URL不能访问财务页面“弹幕Agent”只能访问消息中心不能访问账号设置。这个白名单在浏览器上下文层就做好控制URL不匹配直接拒绝执行。登录态我统一做在一个“账户中心”模块里所有子Agent通过它获取带登录态的浏览器上下文。密码和Cookie加密存放运行时解密后注入浏览器不在日志中留下明文信息。每次从外部接收新任务时指挥Agent会先做一次意图校验明显越权的任务比如“导出所有用户手机号”直接拦截。这个做法在安全合规方面给自己留了很大余地也避免Agent被提示词注入后乱执行。4. 实操过程让 Agent 完整跑通一个直播前中后的流程4.1 直播前定时上架、改库存、设置优惠我先说直播前的场景这个场景最适合做验证。因为时间点固定、流程固定、页面相对稳定很能测出系统的稳定性。我配置了三类直播前任务。第一类是“T-30分钟上架任务”指挥Agent在开播前30分钟启动对每个秒杀商品执行“设为已上架”。GUI Agent进入商品列表找到目标商品点击“上架”等待状态变为“售卖中”再继续下一个。第二类是“T-15分钟库存任务”把每个SKU的直播间库存调整到预设值这个步骤涉及填写数字GUI Agent会先清空输入框、逐个输入字符、再点击保存保存后读取页面回显的库存数字做比对。第三类是“T-5分钟优惠任务”核对优惠券是否已生效、活动价是否设置正确如果发现异常指挥Agent会直接把人从企业微信里拉出来报警。4.2 直播中弹幕监控与自动回复直播开始后最考验架构的高频场景来了弹幕监控。弹幕是持续滚动变化的传统爬虫方式很难处理因为页面不断在刷新。这里我让GUI Agent在一个固定区域反复截屏识别新的弹幕内容。这个方法听着笨实际效果却出奇地好直播间弹幕区域的视觉特征很稳定截一块固定区域做OCR和语义识别基本不会漏。收到弹幕后指挥Agent会判断意图如果是“怎么买”“还有货吗”这类常见问题直接调用话术库回复如果是“我要退款”这类复杂问题标记给人工客服处理。回复动作同样是GUI Agent完成点击输入框、输入文本、按回车。这个闭环在高峰期实测能撑住每分钟上百条弹幕的处理量比人工盯屏从容很多。4.3 直播后数据回收与复盘统计直播结束后工作是另一套节奏。运营需要把多平台的数据报表导出、汇总、对比。我让指挥Agent在直播间正式结束后自动触发“数据回收”逐个平台进入数据中心筛选本场直播的时间段读取各项核心指标观看人数、平均观看时长、互动率、成交总额、客单价、退款率。结构化读取层在这里能复用的价值非常大。数据页面虽然也是网页但信息本身是结构化表格我直接通过解析页面的数据接口拿到JSON字段再统一格式回传。整场数据回收全程不到2分钟就能完成人工去拉报表再整理一般要15到20分钟。整理完的数据会写入一个汇总表运营第二天直接打开就能看。4.4 一次真实跑批中的执行流水举一个真实的例子。上周三晚上8点开播前系统执行了一次“晚8点直播准备”任务流水记录大致是这样的19:30 任务启动指挥Agent读取预设的直播计划提取出6个商品、3个需要改库存的SKU、1个需要设置优惠券的活动。19:31 指挥Agent调用库存Agent进入商品编辑页识别当前库存值并记录。19:32 修改SKU-112库存为800页面回显确认成功。19:33 修改SKU-113库存为500遇到页面弹窗尝试关闭弹窗后继续成功。19:35 优惠券Agent进入营销中心发现目标优惠券状态为“未生效”点击“立即生效”校验状态变为“生效中”。19:36 全部子任务完成指挥Agent生成汇总报告并推送到运营群。整个过程6分钟人完全没有参与。放在以前运营从19:30开始就得放下手里的饭去手动点中间还容易漏。5. 常见问题与排查技巧实录5.1 登录态莫名失效这个是我遇到最频繁的问题。表面现象是Agent在操作途中突然跳到登录页或者接口直接返回401。排查后发现大部分情况不是真正的会话过期而是页面在前台操作时执行了“重新校验”逻辑或者多上下文并发时Cookie串了。我的解决思路是两层第一每个平台维护一个独立的Cookie池一次任务执行期间锁定使用禁止其他任务复用第二在“动作前确认”环节加入登录态检测如果检测到页面跳转到登录页立即中止当前操作并触发重新登录流程。加了这层检测后任务的无效重试少了80%以上。5.2 元素识别准确率不稳定视觉模型识别元素时出现“看着像但实际不对”的概率并不低。最典型的是把“保存”按钮错认成旁边的“保存并上架”这两个按钮颜色相同、间距很近稍不注意就点错。后来我把识别策略调整得很严格先让模型输出“我看到的按钮完整文字”再做精确匹配文字包含目标关键词才允许点击。还有一类情况是页面上的字体太小或对比度不够模型看不清楚。这种时候我会先用Playwright的截图接口做一次2倍放大再去识别准确率能提升很多。如果放大后还是不行就改用DOM文本匹配去定位。5.3 页面弹窗、蒙层遮挡页面弹窗是GUI Agent的头号敌人。直播后台尤其喜欢弹各种运营活动、公告、升级提示一个不留神就覆盖在目标按钮上方。以前遇到这种情况Agent会直接点击被遮挡的坐标区域结果点到的是弹窗而不是目标进而导致一连串错误。我的处理方式是在行动协议里加了两条规则第一执行点击前先检测目标区域是否有蒙层如果有先尝试按“Esc”关闭或点击蒙层的关闭按钮第二每次点击后校验页面是否出现新弹窗如果出现暂停当前操作先把弹窗处理干净再继续。这套规则让任务中断率降了非常多。5.4 风控与反爬的触发规避平台风控是所有网页自动化逃不开的话题。除了前面说的指纹固定我还有一些亲测有效的经验。一是控制操作频率不要像机器一样每步都精确到同一种间隔把点击之间的等待时间做成随机区间变化更接近真人操作。二是避免在极短时间内做大量高频操作比如一分钟内连续修改十几个商品这类行为在平台看来非常可疑我给同一账号的任务加了速率限制。三是页面停留时间要合理改完一个商品后不要立刻跳转停个几秒再动模拟人在看页面。这里也强调一句这套系统的目的不是绕过平台的合理风控而是让自动化任务在合规的范围内稳定执行尽量避免误带宽。团队一直要求所有平台账号操作都遵守平台规则不做任何违规动作。5.5 Agent 状态不同步与任务中断恢复GUI Agent执行时间一长会出现“页面实际状态”和“Agent心理预期”不一致的情况。比如它以为已经成功点击了提交但页面因为网络原因还在转圈又或者它以为某个输入框还是空白的其实是上一次的输入没清干净。解决这个问题我觉得最有效的思路是“把状态校验显式化”每次关键动作完成后都要强制截一张图让视觉模型根据截图输出当前页面状态和预期状态做比对。比对一致才算完成不一致就进入补偿逻辑。如果任务执行到一半因为页面崩溃或网络断了指挥Agent会把当前进度持久化到Redis重启任务时直接从中断点接着跑而不是从头开始。在这个领域折腾了大半年我最大的体会是Agent能不能干活核心不在于模型有多聪明而在于工程底座有多稳。Web访问架构解决的是“Agent和互联网之间的高速公路”GUI Agent解决的是“到了网页面前会不会动手操作”。两者配合好原本需要人蹲在电脑前盯一整天的运营琐事才能真的放手交给Agent去跑。如果你也准备在自己项目里引入类似的能力我的建议是先不要铺太大挑一个最重复、最耗人的网页操作场景把一个链路完整打通再慢慢扩展。这个项目的后续我目前正在加“多Agent协作”的调度优化让不同平台的Agent能共享一套记忆开始跑跨平台的直播复盘。这一块等有稳定成果了我再来单独写一篇。