在多数团队里,真正吃掉时间的不是写代码,而是每天重复的网页手工操作:登录后台、翻页筛选、导出报表、再粘到表格里核对,一套动作十几分钟,一天重复好几轮。
传统 Playwright 自动化脚本解决过一部分问题,但它把对页面的假设写死在选择器里,一次改版就全线崩;商业 RPA 又要学流程设计器、买授权,零散的临时需求根本排不上队。
本文分享一套用 Codex 驱动浏览器完成自动化任务的落地路径:任务指令结构化 + MCP 浏览器工具接入 + 产物级校验与批量编排,配置与脚本可直接落地。
一、痛点:重复网页操作正在吞掉整块时间
先看看日常里最烧时间的那类工作到底长什么样:
- 手工链路长:登录、筛选、导出、粘贴、核对,单次十来分钟,每天重复多次。
- 脚本太脆:用Playwright写死的选择器,页面一改版就全线崩,维护成本甩回业务侧。
- RPA 太重:商业 RPA 的授权与流程设计器成本高,小团队养不起每个临时需求一条流程。
打开页面 → 筛选条件 → 导出文件 → 人工核对 → 重复执行
核心结论:重复、可描述、有明确验收标准的网页任务,最适合交给能读懂页面语义的智能体。
二、选型对照:三条路线的成本结构差在哪
同样是让程序去点页面,三条路线的长期成本完全不同:
| 维度 | Codex + MCP 浏览器 | Playwright 脚本 | 商业 RPA |
|---|---|---|---|
| 上手成本 | 一句自然语言即可起跑 | 需写选择器与等待逻辑 | 需学流程设计器 |
| 改版适应 | 读页面语义自行调整 | 选择器失效即报错 | 流程节点易断裂 |
| 过程可解释 | 每步决策留日志与快照 | 只有执行轨迹 | 有录制回放 |
| 适合场景 | 少量多变的临时任务 | 高频稳定的固定流程 | 跨系统企业流程 |
- 判断准则:流程稳定且跑几万次,写死脚本更划算;需求多变、一周换三回,交给智能体更省心。
核心结论:别用智能体替代高频固定流水线,也别用脚本硬扛多变的临时需求。
三、环境准备:CLI 安装与浏览器工具注册
动手前先把运行时和浏览器工具链接好,分两步完成:
# Node.js 18+ 环境下安装 Codex CLI 并完成账号授权npminstall-g@openai/codex codex login codex--version再在Codex的配置文件里注册 Playwright MCP,让智能体拿到浏览器操作能力:
# ~/.codex/config.toml:把 Playwright MCP 注册为可调用的浏览器工具 [mcp_servers.playwright] command = "npx" args = ["-y", "@playwright/mcp@latest", "--browser", "chromium", "--headless"]- 依赖前置:首次运行会拉取浏览器内核,提前执行
npx playwright install chromium可避免超时。 - 认证方式:
codex login走浏览器授权,token 落在本机配置目录,不要提交进 Git。
核心结论:工具能力由 MCP 提供,Codex 只负责决定何时调用哪个工具。
四、任务描述:把模糊需求写成可执行指令
把一句业务需求变成智能体能独立跑完的指令,通常要补齐这几块:
- 目标与终点:写清任务完成的判定物,例如「生成
./data/orders.csv且行数大于 0」。 - 前置状态:是否已登录、用哪个账号、需要哪些筛选条件与时间范围。
- 动作边界:允许点击的范围,以及支付、删除、群发这类按钮一律禁止触碰。
- 失败处理:遇到验证码或未知弹窗时暂停并回报,不允许自行绕过风控。
核心结论:写清楚「验收标准」,比写清楚「怎么点」更能让智能体一次跑通。
五、链路拆解:一次任务的工具调用循环
一次浏览器任务在底层是一条不断收敛的工具调用循环:
# 非交互执行,适合放进 cron 或 CI;--sandbox 限制可写目录codexexec--sandboxworkspace-write\"打开 https://admin.example.com 订单页,筛选本月已支付订单, 导出 CSV 到 ./data/orders.csv,并报告行数"读取任务 → 调用 MCP 打开页面 → 抓取页面快照 → 决策下一步 → 执行动作 → 校验结果 → 收敛或重试
- 工具层:MCP 暴露
navigate、click、snapshot等能力,Codex 负责选哪个、按什么顺序。 - 沙箱层:
workspace-write把写入范围锁在工作目录内,防止任务越权改系统文件。
核心结论:决策在模型,能力在工具,边界在沙箱,三者缺一任务就会失控。
六、状态校验:用断言确认任务真做对了
智能体说「完成了」不等于真做对了,需要一段独立于执行链路的校验:
# 独立校验导出产物,任务结束后单独运行,避免智能体自证清白importcsv,pathlib p=pathlib.Path("data/orders.csv")assertp.exists()andp.stat().st_size>0,"导出文件缺失或为空"rows=list(csv.DictReader(p.open(encoding="utf-8-sig")))assertlen(rows)>0,"没有读到任何数据行"assertall(r.get("状态")forrinrows),"存在状态为空的记录"print(f"校验通过:{len(rows)}行")- 产物校验:文件存在、编码可读、字段齐全、行数达标,四项全过才算成功。
- 状态校验:页面出现成功提示或跳转到预期 URL,作为执行侧的辅助证据。
核心结论:产物校验与页面状态校验双保险,任一失败就触发重写,绝不静默通过。
七、异常兜底:高频翻车点排错表
浏览器任务的翻车点高度集中,先按这张表对症下药:
| 现象 | 可能原因 | 处理动作 |
|---|---|---|
| 打开页面即跳回登录 | Cookie 未持久化 | 用持久化用户目录启动浏览器 |
| 点击无反应 | 弹窗遮挡或元素在视口外 | 先关弹窗,再滚动后重试 |
| 找不到目标元素 | 页面改版 | 让智能体重抓页面快照再决策 |
| 弹出验证码 | 触发风控 | 暂停任务转人工,不要反复硬试 |
| 导出文件为空 | 筛选条件填错 | 回查筛选参数,校验通过再重跑 |
- 重试策略:同一动作最多重试 3 次,连续失败就带着最后一步快照退出,把现场留给人。
核心结论:把异常收敛成有限的几种,重试策略才有意义。
八、权限边界:只放行必要站点与动作
给智能体开浏览器之前,先把权限关进笼子里:
- 域名白名单:只放行业务站点,拦截跳转出来的第三方与广告域名。
- 凭据隔离:使用只读或独立测试账号,禁止保存支付信息与超管凭据。
- 动作黑名单:删除、付款、对外发送这类不可逆操作,一律要求人工二次确认。
核心结论:权限给到刚好够完成任务的最小集合,宁可多一次人工确认。
九、批量与落盘:任务清单驱动循环执行
单个任务跑通后,把它变成可批量重复的作业:
# 逐行读取任务清单,每个任务独立日志,失败可单独重跑mkdir-plogswhileIFS='|'read-rname prompt;do[-z"$name"]&&continuecodexexec--sandboxworkspace-write"$prompt">"logs/$name.log"2>&1\&&echo"$nameOK"||echo"$nameFAIL"done<tasks.txt- 任务清单:
tasks.txt一行一个任务,形如orders|导出本月订单CSV到./data/,失败只重跑那一行。 - 日志落盘:每次执行写独立日志,成功与失败分开统计,方便日报与回归。
核心结论:外层脚本负责调度与重跑,Codex 负责单个任务内的网页决策,两层各管一段。
十、可观测性:留足快照才能快速复盘
线上跑起来之后,出问题时最值钱的是可回放的现场:
- 全量留痕:保留每步的页面快照、点击坐标与工具调用耗时,形成完整时间轴。
- 失败定位:先看最后一步快照,区分是页面改版、网络抖动还是指令本身有歧义。
- 版本对齐:任务清单、提示词与配置文件一起进版本库,改动能追溯到具体提交。
核心结论:没有留痕的智能体任务,出错时只能靠猜。
结语
这套链路的价值在于把「人盯页面」换成了「指令 + 校验 + 留痕」的闭环:环境与 MCP 接入一次配好,任务指令按目标、边界、验收三段式来写,产物校验独立于执行链路,外层脚本再把单点任务串成批量作业。落地时优先挑 2~3 个高频且验收标准清晰的任务试跑,跑稳后再逐步扩到更多页面。
真正决定成败的不是模型多聪明,而是权限边界、异常兜底与产物校验这三道闸门有没有装上。