ARTICLE · 1239094
AI Agent 到底在哪跑?豆包云电脑 VM 沙箱架构实测拆解
AI Agent 到底在哪跑?豆包云电脑 VM 沙箱架构实测拆解
AI 的“手”和“脑”正在被拆开,放进了不同的地方。 过去半年,AI Agent 到底跑在哪、模型的 key 放在哪,成了不少人真正在意的问题。 我没满足于看资料,直接在自己机器上把豆包云电脑的沙箱拆开看了一遍:查进程、看端口、翻环境变量和配置文件、再翻源码。 这篇就是把实测结果整理出来。沙箱(OpenHands 服务化裁剪版,下面简称 OH)到底怎么组织,一条条写清楚。凡是我实测过的,和基于证据推断的,会分开标注,不把推测当事实。 很多人把云电脑想成“一台能远程用的电脑”。这个说法没错,但解释不了一个现象:豆包侧这些 AI 能力,看着很强,又好像一直被管着。 因为豆包只负责“想”,沙箱只负责“做”。推理在豆包后端,执行在 VM 沙箱——跑代码、开浏览器、读写文件。两边靠 MCP 协议连起来,豆包把沙箱当作工具集里的一项能力来调用。 这个前提清楚了,后面那些端口、进程、脚本就好看了。 VM 沙箱:一个隔离的执行环境,AI 在里头跑代码、动浏览器,污染不到宿主系统。 MCP(Model Context Protocol):连接模型和工具的标准协议,在这里就是豆包后端和沙箱之间的通道。 OH(OpenHands):开源的 agent 运行时框架,豆包把它裁剪后再服务化,塞进 VM 当沙箱的中枢。 简单记:豆包想,OH 把“想”翻成“做”,VM 给“做”一个安全的地方。 实测下来,VM 里就六层:入口路由、OH MCP 服务、工具后端、网络代理、桌面 GUI、控制运行时。全都跑在同一个会话对应的独立 VM(veFaaS pod)里。 请求的实际链路:豆包 → MCP 进沙箱 → nginx 入口 → OH MCP 服务(python-server :8091)→ 各工具后端。 
这张图按实测数据画的,端口、进程、脚本都标在上面,密钥已脱敏,PID 以实测为准。看的时候抓住一条主线:豆包在外头想,沙箱在里头做。 vendored 的 openhands 只留了 core/events/llm/runtime/utils 这些局部模块,storage、core.config、llm_registry 都没了——一 import 就报 ModuleNotFoundError。所以源码里 settings.llm_api_key 那几行根本走不到,是“死代码”。 结论:OH 在这套环境里不推理,也不消费 ANTHROPIC、ARK、CODEX、OPENCODE 里任何一个 key。 codex 和 opencode 都是 tmux 按需拉起来的,key 的注入点写在渲染脚本里:render-codex-config.sh 按 CODEX_API_KEY、ARK_API_KEY、OPENAI_API_KEY 的优先级挑一个;render-opencode-config.sh 用 OPENCODE_API_KEY 渲染 provider 配置。 想验证自定义 key 有没有生效,得在启动对应 CLI 后,去读 /proc//environ 和渲染产物,而不是去看 OH 的配置。 
这张图画的是 key 的流向:豆包后端握着 key,沙箱里的 OH 不碰它,真正的注入发生在 codex/opencode 启动时。 所有出口流量统一经 gost 代理(8118/18080,转发到 vortex egress)审计;飞书、豆包域名的登录态和凭据由 lark_hijack_proxy 注入,token 落盘权限 600。 NO_PROXY 白名单把本地回环、pypi/npm/maven/go 这些开发源和飞书域放过去,白名单内直连、不经过审计代理。 几组线索对得上:环境变量 SESSION_ID 与会话目录名一致;chrome 的会话 cookie 文件叫 Cookie_;DOUBAO_OFFICE_LOG_ID 也是同一前缀;PID 1 的命令带 BYTEFAAS 运行时参数,跟“函数即 pod”的形态对得上。 方向很顺,但严格说这还是“合理推断”:证据够、成立,平台侧的确认我还没拿到。 
把这几组同源的证据摆在一起,指向就很清楚了——一个会话,一个独立 VM。

先说结论
豆包把沙箱当作自己工具集里的一项能力,通过 MCP 协议暴露;模型推理和 key 都在豆包后端,不进沙箱。 沙箱里的 OH 不推理,也不消费任何模型 key;key 真正落进去的地方,是 codex、opencode 的启动脚本。 沙箱出口流量统一走代理审计,飞书、豆包的登录态由劫持代理注入;证据都指向“一个会话一个独立 VM”。
先搞清一个前提:想和做是分开的
三个词,先对上号
整个沙箱,其实就六层
入口层:nginx 0.0.0.0:8080、127.0.0.1:8081,公网/内网入口,按路径转发。 OH MCP 服务:python-server :8091,读 mcp-hub.json,向豆包暴露沙箱工具。 工具后端:tmux/bash、chrome:9222、codex/opencode、jupyter(未运行),负责 bash、浏览器、代码执行、file。 网络代理:gost :8118/:18080、lark_hijack_proxy,出口审计、登录态注入。 桌面 GUI:Xvnc:5900、websocat:6080、openbox、fcitx5,可视化桌面、noVNC、窗口与输入法。 控制运行时:vm_runtime_hook:10080、mcp_vm_server:10000、gem.sh、browser-supervisor,容器生命周期、能力网关、配置渲染、浏览器守护。

三个和常识不太一样的发现
发现一:沙箱里的 OH,其实没有 LLM 层
发现二:key 真正落进的地方,是 codex/opencode 的启动脚本

发现三:出口统一走代理审计,登录态由劫持代理注入
一项推断:一个会话,一个独立 VM
















































































