okay,不是调用 Playwright,而是我们自己 runtime 把 cdp 包装的一层 api(也有点类似于 Playwright 吧),可以参考一下 egolite,大概就按照它那样弄的

回复 群友 7309: 那就清楚了:模型生成的是调用你们自己 CDP API 层的代码,并非 playwright 的 python 脚本。这种情况下隔离边界的选择会变,bubblewrap 不再是首选,得看这层 API 跑在哪。 分两种架法: 一、runtime 跑在宿主,生成代码只作为参数传入。如果你的 API 层本质是“发指令”,模型输出的是调用序列(像 JSON 或某个 DSL),由宿主的 runtime 解析后执行 CDP 操作,那么生成代码根本不落地执行,就不需要重量级沙箱。你只需要校验指令白名单(能点哪些域名、能不能下载、能不能读剪贴板),成本最低,隔离也最干净。egolite 这类给 agent 用的浏览器接口,实质上就是这么做的:把能力面收窄成结构化动作,而不是让模型随便写代码。 二、runtime 跑在沙箱里,生成代码真的执行。这时 bubblewrap 依然是合适的一层:--ro-bind 挂 runtime 和依赖,--bind 一个可写工作目录,profile 单独可写挂载(或拷贝一份),--unshare-net 后 CDP 走 unix socket 挂进沙箱,或者放开网络但只允许连 127.0.0.1 的调试端口。这里有个好处:CDP 是回环端口时,用 --unshare-net 加一个 bind 进去 unix socket 就能完全断外网,比 browser 场景好收口。 wasm 在这个形态下比上一轮稍微有一点空间,但也只限第二种里“代码纯逻辑、API 通过 host function 暴露进来”的那种,也就是 WASI 风格:把 CDP 调用做成 host import,沙箱内只跑逻辑,没有真实 fs 和 net。这样能防住代码乱写文件,但不防 CPU 耗尽和无限循环(那要靠超时和 fuel 计量)。个人本地部署要复用登录态、还要接真浏览器,为了这点收益自己搭一套 host function 桥接不划算,除非你本来就打算把它做成可插拔的 plugin 执行环境。 所以我建议你先定一件事:模型输出的到底是“代码”还是“动作序列”。如果是动作序列,别上沙箱,做指令校验和额度控制就够了;如果确实是任意代码执行(比如它要写循环、解析页面数据、组合多步逻辑),再走 bubblewrap,profile 拷一份,网络走 unix socket 或 loopback 收口。 你现在的设计里,模型是生成 JS/py 片段丢给 runtime 跑,还是生成结构化指令?这个定了我再把挂载和网络收口的具体参数给你写细。