Chrome 浏览器多实例隔离(一):Session 劫持、配置冲突与内存污染
多个 agent-browser 实例同时运行时会互相 hijack 对方的 session。同一配置文件下 localStorage 被覆盖,CDP Target 互相干扰。
一个典型的混乱场景
两个 AI 智能体同时在跑。智能体 A 在填一个电商订单表单,已经填到了支付页面。智能体 B 在同一个浏览器实例里打开了一个新标签页去抓取竞争对手的价格。
然后智能体 A 的标签页突然跳转到了一个完全不相关的页面。填了一半的支付表单丢失了。智能体 A 报错,任务失败。
这不是假设。agent-browser 的 Issue #326 描述了完全相同的场景:多个 agent-browser 实例同时运行时,它们会互相 hijack 对方的 session。
根因 1:CDP Target 共享
Chrome DevTools Protocol 的设计假设是一个调试者控制一个浏览器。当你通过 CDP 连接到一个浏览器时,所有标签页(Target)都对调试者可见。
当两个独立的 agent-browser 实例连接到同一个 CDP 端口时,它们看到的是同一个 Target 列表。这意味着:
- 实例 A 创建的标签页对实例 B 可见
- 实例 B 可以对实例 A 的标签页进行操作
- 实例 B 意外关闭了实例 A 的标签页,A 的任务直接失败
CDP 端口 (localhost:9222)
│
├── Target 1 (标签页 A, 智能体 A 在使用)
├── Target 2 (标签页 B, 智能体 B 在使用)
└── Target 3 (空白页面)
智能体 A 调用 Target.attach 附加到 Target 1
智能体 B 调用 Target.attach 附加到 Target 2
智能体 B 误操作关闭了 Target 1 → 智能体 A 的任务中断根因 2:localStorage 和 Cookie 共享
即使两个智能体通过不同的配置文件启动浏览器,如果它们指向同一个用户数据目录,localStorage 和 Cookie 是共享的。智能体 A 写入了一个 token 到 localStorage,智能体 B 在另一个任务中覆盖了它。智能体 A 的下一次操作因为认证失效而失败。
磁盘上的同一个 Chrome 用户数据目录
│
├── 默认 Storage
│ ├── localStorage (智能体 A 写入 token_A)
│ └── Cookies (智能体 A 的会话 Cookie)
│
├── 智能体 B 写入 token_B → 覆盖了 token_A
│
└── 智能体 A 的下次请求使用过期的 token → 认证失败根因 3:内存相互污染
多个智能体在同一个浏览器进程中的操作会影响彼此的性能。智能体 A 打开了一个包含大量 JavaScript 的 SPA,占用了 500MB 内存。智能体 B 的操作因为 GC 暂停而变慢。
更隐蔽的问题是:智能体 A 的页面中注入的 JavaScript 变量可能污染全局作用域,影响智能体 B 的页面中的脚本执行。
实际案例:Playwright MCP 的 21 小时记忆体泄漏
之前分析过的 Playwright MCP Issue #1636 中,一个长期运行的 MCP 会话在 21 小时 28 分钟内消耗了 24.6GB 虚拟内存。核心原因是:当一个智能体持续使用同一个浏览器实例时,每次工具调用都创建一个新的 BrowserContext/Page/Frame/JSHandle,但这些对象不会被完全释放。
对于多智能体场景,问题更严重。如果有 N 个智能体共享同一个浏览器实例,泄漏速度是 N 倍。这意味着一台 16GB 内存的服务器,可能几个小时内就被多个智能体的累积泄漏耗尽。
什么时候会发生
根据社区反馈和自己的排查经验,以下三种场景最容易触发多智能体隔离问题:
场景 1:CI/CD 中的并行测试 多个测试用例在同一个 CI runner 上并行执行,每个测试用例启动一个 agent-browser 实例。所有实例默认连接到同一个 Chrome 实例。测试用例 A 创建的标签页被测试用例 B 误关闭。
场景 2:多账号管理 一个智能体管理多个社交账号,每个账号打开一个标签页。不同的账号操作在不同的标签页中进行,但由于 Cookie 共享,账号 A 的登录态可能被账号 B 的页面覆盖。
场景 3:生产环境中的并发任务队列 多个后台任务被分发到同一个浏览器集群中的节点,每个任务在一个独立的智能体实例中执行。如果任务调度器没有做 session 隔离,任务 A 和任务 B 可能被分配到同一个浏览器实例,互相干扰。
初步解决方案
下一篇文章会详细分析三种上下文隔离方案的具体实现。这里先给出每种方案的适用场景:
| 方案 | 隔离程度 | 资源开销 | 适用场景 |
|---|---|---|---|
| 独立 Chrome Profile | 中 | 中 | 多账号管理、长期运行任务 |
| 容器化(每实例一个容器) | 高 | 高 | 生产环境、安全性要求高 |
| CDP Target.createTarget | 低 | 低 | 临时隔离、开发测试 |
选择隔离方案的核心不是选隔离程度最高的,而是选和你的业务场景匹配的。下一篇文章会详细对比这三种方案的具体实现、成本和坑点。
需要企业代理方案?
我们可根据目标站点、并发规模与稳定性目标提供定制方案。