本文首发于 斯晨的AI笔记(note.sichenai.cc),原文链接:https://note.sichenai.cc/articles/agent-browser-sandbox-limits,作者:斯晨。

结论先行(不想看过程的看这里)

我想让 AI 自动把 3 个 Skill 上架到 SkillHub 平台——登录、填表、上传文件、提交,全让 AI 干。

结果卡在第一步:AI 能打开浏览器、能导航、能截图、能交互,但窗口我看不见。没法在窗口里输 GitHub 密码,登录这步就死了。

排查了 4 条路,最后搞清一件事:不是 agent-browser 这个工具坏了,是它跑在我的 AI 编程助手的沙箱里,沙箱不让浏览器窗口持续显示。

但排查不是白费。过程中我拿到了三个真正有用的东西:

  • 纠正了一个流传的错误配置写法(AGENT_BROWSER_HEADED=1 环境变量根本没用,正确是 --headed 命令行标志);
  • 摸清了这套工具的能力边界:headless 模式(无窗口)完全可用,headed 模式(有窗口、需要你输密码登录)在这个环境走不通
  • 搞清了归因:是沙箱的 GUI 限制,不是工具 bug,也不是系统问题。

一句话结论:AI 工具"能不能用",不能只看工具本身,要看「工具 × 环境 × 任务」的组合。同一个工具,在 A 环境能用,在 B 环境可能就卡边界。判断方法:分层排查(工具层 → 环境层 → 系统层),别一上来就怪工具。


一、我想做什么

背景:我有个 Skill 分发项目,要把 3 个自己写的 Skill(new-convo-handoff / first-principles / clarify-until-clear)上架到 SkillHub([www.skillhub.club)这个平台。
流程很简单:登录)→ 进发布页 → 填表 → 上传 SKILL.md → 提交。每个 Skill 5 分钟,3 个 15 分钟。

但我懒。我想让 AI 替我干——我之前用 AI 操作浏览器登录过 5 个平台(那是另一篇手记),跑通过登录态复用。这次想如法炮制:AI 打开浏览器,我输个 GitHub 密码登录,剩下的填表/上传/提交 AI 接管。

用的工具是 agent-browser(一个给 AI 用的浏览器自动化 CLI)。我项目里的启动指令记着"8/13 上午测过,窗口弹不出来,沙箱问题"。我不信邪,想再试一次。


二、4 条路全试过(排查全程)

路 1:按启动指令记的环境变量(失败)

启动指令里写着:用 AGENT_BROWSER_HEADED=1 环境变量启动,窗口就能显示。

AGENT_BROWSER_HEADED=1 agent-browser open https://www.skillhub.club/app/skills

结果:浏览器启动了,能导航、能截图。但我查 Chrome 进程参数——--headless=new还是无窗口模式。环境变量压根没生效。

第一个坑:启动指令里记的 AGENT_BROWSER_HEADED=1错误写法。我查 agent-browser 的 open --help,正确写法是 --headed 命令行标志,不是环境变量。这个错误写法不知哪来的,但它是 8/13 上午"窗口时有时无"的真因之一——环境变量没生效,Chrome 一直无窗口,我所谓的"看到窗口"可能是看到了别的 Chrome 窗口。

路 2:用正确的 --headed 标志(失败)

agent-browser open --headed https://www.skillhub.club/app/skills

这次标志用对了。但我屏幕上还是没看到 Chrome 窗口。

诊断:查 Chrome 进程参数,还是有 --headless=new。说明 --headed 标志传了,但 Chrome 没切到有窗口模式——沙箱阻断了 Chrome 连接系统的窗口服务(WindowServer)。

第二个坑:agent-browser 还有个导航 bug——对 SPA 站点(像 SkillHub 这种动态渲染的页面),open <url> 后页面停在 about:blank,要用 eval "location.href='<url>'" 绕过。这个 bug 跟窗口可见性是两个独立问题,但都得出了 workaround。

路 3:绕过沙箱——dangerouslyDisableSandbox(窗口出现了,但很快关闭)

我的 AI 编程助手有个沙箱(sandbox),限制 AI 执行的操作。有个逃生舱:dangerouslyDisableSandbox=true,理论上能绕过沙箱。

# Bash 工具设 dangerouslyDisableSandbox=true
agent-browser open --headed https://www.skillhub.club/login

这次窗口出现了! 但几秒后自己关闭了。

诊断:Chrome 进程还活着(我能用 eval 连上后台 daemon,查到页面还在 GitHub 登录页),但窗口没了。说明不是进程被杀,是窗口的可见性被收回了。

第三个坑dangerouslyDisableSandbox 的 GUI 放行是调用级(call-scoped)的——只在单次命令执行期间有效,命令返回就收回。Chrome 窗口在命令执行时可见,命令结束就关闭。但 Chrome 进程没死,继续无窗口跑。

路 4:后台保活——background + sleep 600(还是失败)

既然 call-scoped,那让命令一直不结束不就行了?我用后台任务(background)跑一个长命令,保活 10 分钟:

# run_in_background=true + dangerouslyDisableSandbox=true
agent-browser open --headed https://www.skillhub.club/login && sleep 600

窗口又出现了,然后又关闭了。

诊断:后台任务确实在跑(sleep 600 保活),Chrome 进程也活着。但窗口还是关了。说明沙箱的 GUI 放行重置不依赖"任务是否在跑",而依赖"沙箱状态"——沙箱状态在命令返回时就重置了,跟后台任务保活无关。

4 条路全失败。 但失败得很有规律——窗口都能在 dangerouslyDisableSandbox 启动瞬间出现,但都无法持续。这指向同一个根因。


三、归因:三方排查

工具不能用,无非三个嫌疑方:工具本身、运行环境、操作系统。我逐个排除:

嫌疑方是否有责依据
agent-browser(工具)⚠️ 文档缺陷,非功能缺陷--headed 标志本身正确,功能没错。但 troubleshooting.md 只覆盖安装类问题,没说沙箱环境下 headed 可能失效。文档有盲区,不是 bug
AI 编程助手沙箱(环境)✅ 主因GUI 窗口可见性限制是 call-scoped 的,dangerouslyDisableSandbox 放行只在单次调用有效。daemon+Chrome 进程存活但窗口关闭,证明是 WindowServer 连接被切断,不是进程被杀
macOS(系统)❌ 无责我日常 Chrome 正常显示窗口,macOS 不限制 Chrome 连 WindowServer。限制在沙箱层,不在系统层

根因:headless 能用 = 沙箱放行了网络和渲染(CPU 计算);headed 窗口不能用 = 沙箱不放行 GUI(WindowServer 连接),且放行是 call-scoped 不能持续。

这不是 bug——沙箱限制 AI 执行 GUI 操作是合理的安全设计。只是让"AI 自动化 + 需要用户在窗口里输密码"这种混合场景走不通。


四、踩坑清单(4 个,全部实测)

#现象解决/结论
1错误配置写法流传AGENT_BROWSER_HEADED=1 环境变量启动,Chrome 仍 headless正确是 --headed 命令行标志(查 open --help 确认)。环境变量写法不知哪来的,但没用
2SPA 导航 bugopen <url> 后页面停在 about:blank,snapshot 是 emptyagent-browser eval "location.href='<url>'" 绕过,eval 后 sleep 3-4s + wait 再 snapshot
3沙箱 GUI 放行是 call-scopeddangerouslyDisableSandbox 启动时窗口出现,命令返回后窗口关闭(进程存活)无法绕过。需用户输密码的登录场景走不通,回退手动
4后台保活无效background + sleep 600 保活任务,窗口仍关闭沙箱状态重置不依赖任务是否在跑,依赖命令返回。保活 Bash task 没用

一个诚实的说明:这 4 个坑都不是我预先知道的,是 AI 报错、查进程参数、一次次试出来的。报错和现象不是失败,是诊断信息。 遇到"不能用",把现象原样记下来,逐层排除,比反复试同一个命令有用得多。


五、能力边界清单(这次真正的成果)

排查完,我拿到了一份明确的能力边界:

模式状态适用场景
headless(无窗口)✅ 完全可用导航、抓取、截图、表单交互(不需用户输密码的场景)
headed(有窗口)❌ 登录场景不可用需用户在窗口输密码/2FA 的场景(如 OAuth 登录)

headless 能干什么:AI 打开页面 → 读内容 → 点按钮 → 填表单 → 截图。全程不需要你看窗口。适合已登录 session 的批量操作、数据抓取、截图存证。

headed 不能干什么:需要你亲自在窗口里输密码、扫码、过 2FA 的登录环节。这种场景,AI 自动化走不通,老老实实手动。

关键操作前置:每次启动前 pkill -f agent-browser 清残留 daemon(不清的话,可能复用上次的无窗口 daemon,窗口永远不出现)。


六、成本与数据

数据
时间约 40 分钟(4 条路排查 + 归因 + 文档更正)
费用0 元
成果摸清能力边界 + 纠正 1 个错误配置写法 + 更新启动指令和日志
遗憾SkillHub 上架没自动化成功,回退手动(5-10 分钟)

判断标准:这次"跑通了"≠ 自动化上架成功,而是搞清了能力边界——知道哪里能用、哪里不能用、为什么。这比强行跑通一个不稳定的结果更有价值。


七、为什么这篇值得写:AI 工具的"能用"不是非黑即白

大多数人遇到"AI 工具不能用",要么放弃,要么反复试同一个命令。但工具"能不能用"不是非黑即白——同一个工具,在 A 环境能用,在 B 环境可能卡边界;同一个环境,headless 能用,headed 不能用。

这次最大的收获不是"跑通了什么",而是学会了一套排查方法

  1. 分层归因:工具层 → 环境层 → 系统层,逐个排除,别一上来就怪工具;
  2. 看进程参数:Chrome 是 headless 还是 headed,看进程参数(--headless=new)就知道,别靠猜;
  3. 区分进程存活 vs 窗口可见:进程活着但窗口没了 = WindowServer 连接被切断,不是进程被杀,解决方向完全不同;
  4. call-scoped 放行:沙箱的"逃生舱"可能是调用级的,不是持续的,别以为开了就一劳永逸;
  5. 诚实记录边界:工具不是"能用"或"不能用",是"在什么条件下能用"。把边界记清楚,比假装全能更有用。

一个诚实的说明:这次我没"修复"agent-browser——它是上游开源工具,我没改源码。我修复的是自己的认知和文档:纠正了错误配置写法,摸清了能力边界,更新了启动指令。这算不算"修复"?我觉得算——搞清一个工具的真实边界,比盲目"修好"它更值钱。


附:agent-browser 是 vercel-labs 开源工具(github.com/vercel-labs/agent-browser),headless 模式优秀,本文记录的是在特定沙箱环境下的 headed 限制,不影响工具本身的价值。
站点:note.sichenai.cc · 把 AI 工具,真正跑通。

Logo

小龙虾开发者社区是 CSDN 旗下专注 OpenClaw 生态的官方阵地,聚焦技能开发、插件实践与部署教程,为开发者提供可直接落地的方案、工具与交流平台,助力高效构建与落地 AI 应用

更多推荐