非官方社区教程 · 内容整理自公开资料 · 豆包工作为字节跳动产品,本站与官方无关
豆包工作教程
首页/ Harness 拆解/CH-02 运行环境:Chromium 壳与原生 Helper

CH-02 运行环境:Chromium 壳与原生 Helper

图 2-1:豆包工作整体架构——非 Electron 的混合架构

图 2-1:豆包工作整体架构——非 Electron 的混合架构

2.1 一个 1MB 的主二进制

在 macOS 上安装豆包工作后,应用本体位于 /Applications/DoubaoWork.app。按照 Mac 应用的标准结构,它的可执行文件在 Contents/MacOS/DoubaoWork。如果你查看这个文件的大小,会发现一个反直觉的事实:

DoubaoWork.app/Contents/MacOS/DoubaoWork — 1.0 MB

1MB。对于一个号称能操作电脑、调用工具、运行多 Agent 的桌面应用来说,这个数字小得不正常。作为对比,一个典型的 Electron 应用主进程通常在 100MB 以上(因为它打包了 Node.js 运行时和 V8 引擎),一个原生 macOS 应用的主二进制也通常在 10-50MB。

1MB 意味着豆包工作的主二进制不是应用逻辑的载体,而是一个启动器(launcher)。它的职责是:初始化 Chromium 运行时、加载渲染进程、建立主进程与 Helper 进程之间的通信通道,然后把控制权交给 Web 技术栈。「源码」

这个判断有多重证据支撑:

第一,应用包内存在一个独立的浏览器应用 Contents/Helpers/DoubaoWork Browser.app,体积 977MB。这是一个完整的 Chromium 浏览器,包含 Blink 渲染引擎、V8 JavaScript 引擎、网络栈和所有 Chromium 子模块。豆包工作的主二进制通过启动这个浏览器实例来承载 UI 和应用逻辑。「源码」

第二,用户数据目录是标准的 Chromium profile 结构。~/Library/Application Support/DoubaoWork/Default/ 下有 Cookies、History、Favicons、Local Storage、Extension State、Preferences 等 Chromium 标准目录,还有一个 RunningChromeVersion 文件记录着 147.0.7727.149。「源码」

第三,应用包的 Info.plist 中声明了多个 URL scheme(dola、doubao、doubaowork),这些 scheme 由 Chromium 的 URL 请求机制处理,不是原生代码路由。「源码」

所以豆包工作的架构本质上是:一个极薄的原生启动器 + 一个完整的 Chromium 浏览器 + 一组原生 Helper 进程。UI 渲染、应用逻辑、Agent 调度、工具调用的编排都运行在 Chromium 渲染进程中(JavaScript/TypeScript),只有浏览器能力之外的操作——执行本地命令、运行 MCP 服务器、实施沙箱——才通过原生 Helper 完成。

这种架构选择有利有弊。好处是开发效率高、跨平台一致性好、可以利用 Chromium 的扩展系统和 Web 技术栈;代价是内存占用大(977MB 的浏览器内核)、原生能力需要额外的桥接层、应用逻辑暴露在渲染进程中(可以通过 Chrome DevTools Protocol 观测)。

2.2 进程架构

豆包工作运行时的进程模型可以分为三层:

DoubaoWork(主进程,1MB 启动器)
├── DoubaoWork Browser.app(Chromium 浏览器内核,977MB)
│   ├── 渲染进程(UI + Agent 逻辑 + 工具编排)
│   ├── GPU 进程
│   ├── 网络进程
│   └── 扩展进程(Chrome Extension)
├── command_helper(命令执行桥,2.2MB)
├── mcp-helper(MCP 助手,1.2MB)
│   └── libmcp_helper.dylib(MCP 核心库,11MB,Rust)
├── sandbox-launcher(沙箱启动器)
│   ├── libsandbox.dylib(Seatbelt 沙箱桥接)
│   └── libauditSboxSDK.dylib(审计 SDK)
├── relaunch_helper(重启助手,1.0MB)
├── saman_updater(更新框架,1.1MB)
└── finder-ext.appex(Finder 扩展)

2.2.1 主进程与浏览器内核

主进程(DoubaoWork)负责应用生命周期管理和窗口创建。它启动 DoubaoWork Browser.app,后者是一个完整的 Chromium 实例。Chromium 版本为 147.0.7727.149,这是一个相当新的版本(Chromium 147 于 2025 年底发布),说明豆包工作的浏览器内核保持着积极的更新节奏。「源码」

浏览器内核承载了所有 Web 技术栈的运行:UI 界面用 Web 技术渲染,Agent 的规划和调度逻辑用 JavaScript/TypeScript 实现,工具调用通过 Chromium 的 Extension API 和原生 Helper 桥接完成。

值得注意的是,豆包工作没有使用 Electron。Electron 是最常见的 Chromium 桌面应用框架,但它打包了 Node.js 运行时,允许渲染进程直接调用 Node.js API。豆包工作选择了更接近 Chromium 原生的方式——它有自己的 Helper 进程体系,而不是依赖 Node.js。这使得它的架构更接近 CEF(Chromium Embedded Framework)或自定义 Chromium 发行版,但 Helper 进程的分工又比 CEF 更精细。

2.2.2 command_helper:命令执行桥

command_helper 是豆包工作执行本地命令的桥梁。当 Agent 需要在终端中运行命令时(比如执行 lsgit statuspython3 script.py),请求从渲染进程发出,通过 Chromium IPC 到达主进程,主进程启动 command_helper 子进程来执行。

command_helper 的二进制中嵌入了 macOS Seatbelt 沙箱配置(scheme 语法),说明它同时承担了沙箱策略执行的职责。在沙箱模式下,它限制命令可以访问的文件系统路径;在完全访问模式下,它对用户授权目录开放读写权限。沙箱机制的细节在 CH-06 展开。「源码」

2.2.3 mcp-helper:原生 MCP 运行时

mcp-helperlibmcp_helper.dylib 是豆包工作最有技术含量的原生组件。它们用 Rust 编写,基于 rmcp 3.0.0(Rust 生态的官方 MCP SDK),负责管理所有 MCP(Model Context Protocol)服务器的生命周期。

当 Agent 需要调用外部工具(比如飞书文档读取、数据库查询、自定义 MCP 服务器)时,mcp-helper 负责启动 MCP 服务器进程、建立传输连接、处理 OAuth 认证、转发工具调用、序列化结果返回渲染进程。它支持 STDIO、HTTP+SSE 和 Streamable HTTP 三种传输协议,实现了完整的 OAuth 2.0 流程。MCP 机制的细节在 CH-05 展开。「源码」

2.2.4 sandbox-launcher:沙箱启动器

sandbox-launcher 配合 libsandbox.dyliblibauditSboxSDK.dylib 实现了基于 macOS Seatbelt 的应用沙箱。当 Agent 需要启动一个外部应用(比如打开浏览器访问网页、运行一个脚本)时,sandbox-launcher 负责在受限环境中启动它。

它的启动流程包括:验证父进程身份和代码签名、通过环境变量 AHA_SANDBOX_CONFIG 接收沙箱配置、dlopen libsandbox.dylib、应用 Seatbelt 策略、通过 LaunchServices 启动应用。审计 SDK 则监控沙箱内的进程行为、网络访问和文件操作,支持白/黑名单和加密日志。「源码」

2.2.5 relaunch_helper 与 saman_updater

relaunch_helper 负责应用重启(比如更新后重启、崩溃后恢复)。saman_updater 是字节内部的 "saman" 桌面更新框架,负责检查更新、下载增量包、安装更新。更新渠道在 manifest.json 中声明为 release(channel 1001),whatsNewVersion 为 1.57.0。「源码」

"saman" 是字节桌面端基础设施的代号,在豆包工作的用户数据中频繁出现:Preferences 中有大量 saman.* 配置键,Local State 中有 saman 相关的全局设置。它类似于一个桌面端运行时框架,提供更新、同步、窗口管理等基础能力。

2.2.6 finder-ext.appex

这是一个 Finder 扩展(App Extension),允许用户从 Finder 的右键菜单中直接与豆包工作交互(比如"用豆包工作处理这个文件")。它是豆包工作融入 macOS 桌面体验的触点之一。「源码」

图 2-2:App 包结构与进程关系

2.3 manifest.json:信任域与产品线整合

应用包的 Contents/Resources/manifest.json 是一个关键配置文件,它不仅声明了版本信息,还定义了豆包工作的安全边界——哪些域名可以加载主框架、哪些脚本可以执行、哪些扩展拥有特权。

版本信息如下:

{
  "productName": "DoubaoWork",
  "version": "2.25.18",
  "commitId": "345d9dd425dd3a64c0258bb12c7f3049a022af2b",
  "updateChannel": "release",
  "channel": "1001",
  "whatsNewVersion": "1.57.0",
  "onboardingVersion": "1.6.0"
}

commitId 是构建时的 Git commit 哈希,可以用于精确追踪版本。channel 1001 是内部渠道编号。「源码」

更值得关注的是 signature.trustedOrigins 配置(Base64 编码,解码后)定义了四类信任域:

主框架域(INIT_MAIN_ON_ROOT_DOMAIN)cici.comdola.comciciai.comdoubao.com,协议为 https 端口 443。这意味着豆包工作的主界面可以从这四个域名的根域加载。「源码」

精确框架域(FRAME_URL_EXACT)www.cici.comwww.ciciai.comwww.dola.comaccounts.dola.comwww.doubao.combeta.doubao.cominhouse.doubao.comaccounts.doubao.com。这些是具体的子域,包括测试版(beta)和内部版(inhouse)。「源码」

脚本域(SCRIPT_URL_DOMAIN_IS):除了四个主域,还包括 CDN 域 cicicdn.comdolacdn.comciciaicdn.comdoubaocdn.combytedance.netbyteintl.net。这些域名的脚本可以在应用内执行。「源码」

特权扩展(FRAME_URL_IS_PRIVILEGED):6 个 chrome-extension://<hash> 标识符。这些是预装的 Chrome Extension,拥有普通扩展没有的特权 API 访问权限。它们是 Harness 能力的重要注入点——Agent 的部分工具能力可能通过这些特权扩展暴露给渲染进程。「源码」

自定义 Scheme(FRAME_URL_ALLOW_DANAGER_API)dola-backgrounddoubao-backgrounddoubaowork-background 三个自定义协议,拥有 "Danger API" 权限。注意这里的 "DANAGER" 可能是 "DANGER" 的拼写变体,但在配置中确实如此。这些 scheme 是后台 Agent 执行的通道——它们允许后台页面(不显示 UI 的页面)调用敏感 API,是 Agent 在后台持续运行的基础设施。「源码」

三产品线整合

信任域配置揭示了一个重要事实:豆包工作不是一个独立产品,而是字节三条 AI 产品线的统一桌面容器。

  • cici(扣子/Coze):字节的 AI Bot 开发平台,cici.com 和 ciciai.com
  • dola(哆啦):字节的内部/早期 AI 助手品牌,dola.com
  • doubao(豆包):面向消费者的 AI 助手,doubao.com

豆包工作的应用包名为 com.work.pc.doubao,内置浏览器为 com.work.pc.doubao.browser,但信任域覆盖了所有三个品牌。这意味着同一个桌面客户端可以加载不同产品线的 Web 界面,Agent 能力是跨产品线共享的。「源码」

2.4 用户数据目录

豆包工作的用户数据存储在 ~/Library/Application Support/DoubaoWork/,遵循 Chromium 的 profile 结构:

DoubaoWork/
├── Local State                    # 全局状态(设备信息、用户信息、saman 配置)
├── Last Version                  # "2.25.18"
├── RunningChromeVersion          # 147.0.7727.149:1
├── Default/                      # 默认 Chromium profile
│   ├── .doubaowork/              # 豆包工作专属数据
│   │   └── agent_mode/
│   │       └── workspace/
│   │           ├── .skills/      # 103 个预装 Skill
│   │           └── .user_skills/ # 用户自定义 Skill(空)
│   ├── DoubaoStorage/Aida/       # Aida 存储
│   │   ├── doubao-office/
│   │   └── entry-main/
│   ├── Preferences               # Chromium + saman 配置(116KB)
│   ├── Secure Preferences        # 安全配置(12KB)
│   ├── Cookies / History / Favicons
│   ├── Extension State/          # Chrome Extension LevelDB
│   ├── Local Storage/            # Web localStorage
│   └── ...
├── GrShaderCache / GPUCache
├── Crashpad/                     # 崩溃报告
└── Monitor/

2.4.1 agent_mode/workspace

.doubaowork/agent_mode/workspace/ 是 Agent 模式的工作区,也是用户唯一可以直接编辑的 Harness 扩展点。.skills/ 目录存放 103 个预装 Skill(由 App 管理,权限为 drwx------),.user_skills/ 目录用于用户自定义 Skill(默认为空)。「源码」

这个目录结构与 WorkBuddy 形成鲜明对比。WorkBuddy 在 ~/.workbuddy/ 下放了 SOUL.md、IDENTITY.md、USER.md、MEMORY.md、prompt.tpl、plugins/、skills/、mcp.json 等一系列明文配置文件,用户可以完全控制自己的 Harness。豆包工作把所有这些都收走了,只留下 Skill 目录作为扩展接口。这种设计哲学的差异在 CH-10 详细对照。

2.4.2 DoubaoStorage/Aida

DoubaoStorage/Aida/ 下有两个子目录:doubao-office/entry-main/。"Aida" 是字节内部的另一个代号(可能与 Opera 的 Aida AI 无关,是字节内部项目名),从目录名推测与文档处理(office)和主入口(entry-main)相关。这个目录的具体用途需要进一步分析其内容,但它是豆包工作在 Chromium 标准存储之外的专属数据区。「源码」

2.4.3 Preferences 中的 Agent 配置

Chromium 的 Preferences 文件(JSON,116KB)包含一些 Agent 相关的配置:

配置键 含义
extensions.last_chrome_version 147.0.7727.149 Chromium 版本
saman.task_mode.runtime.active_environment_id UUID 当前任务环境(本地/云电脑)
saman.local_storage_for_web.home 含技能暴露缓存 首页技能列表
saman.local_storage_for_web.launcher 含 discovered_skills 已发现技能图标
saman.text_picker.skills_list 技能数组 文本选择器技能
sync.data_type_status_for_sync_to_signin.skill false 技能不同步到账号
saman.native_sync.enabled true 原生同步开启

「源码」

几个值得注意的点:

第一,技能配置存储在 Chromium 的 localStorage 中(saman.local_storage_for_web),不是独立的配置文件。这意味着技能列表是 Web 应用状态的一部分,由渲染进程管理。

第二,技能数据包含 agentIdbotIdcommandId 三种标识符,说明技能可能来自不同的后端——有些是 Agent 类型、有些是 Bot 类型、有些是命令类型。这与"技能·连接器·工作伙伴"的三层产品概念对应。

第三,技能默认不同步到账号(skill: false),但书签双写同步开启(bookmark_sync.dual_write_enabled: true)。这说明技能目前被视为设备本地状态,而不是用户账号的跨设备资产。

第四,active_environment_id 是一个 UUID,标识当前任务执行环境。当用户切换"本地电脑"和"云电脑"时,这个 ID 会变化,Agent 的工具路由和权限策略也会随之改变。

2.5 内置浏览器与外部浏览器的关系

豆包工作内置了一个完整的 Chromium 浏览器(DoubaoWork Browser.app),但它不是简单地在应用内打开网页。这个内置浏览器有独立的 Bundle ID(com.work.pc.doubao.browser)、独立的偏好设置文件(com.work.pc.doubao.browser.plist)和独立的缓存目录。「源码」

当 Agent 需要执行浏览器自动化任务时(比如操作网页、填写表单、抓取数据),它使用的是这个内置浏览器,而不是用户系统默认的浏览器。这有几个好处:

  1. 环境隔离:Agent 的浏览器操作不影响用户日常浏览器的标签页、Cookie 和登录状态。
  2. 权限控制:内置浏览器可以通过沙箱和策略限制 Agent 的行为。
  3. 自动化接口:内置浏览器可以通过 CDP(Chrome DevTools Protocol)或扩展 API 被程序化控制。

第三方开源项目 doubao-mcp-bridge 正是利用了这一点——它通过 CDP 连接到豆包工作的内置浏览器,监听 Agent 的 MCP 调用(MCP_CALL_JSON 消息),从而把豆包工作的工具能力暴露给外部 MCP 客户端。「社区」这从侧面证实了豆包工作内部使用 MCP 协议进行工具调用,且这些调用在渲染进程中可被 CDP 观测。

2.6 更新机制

豆包工作使用 saman_updater 进行自动更新。manifest.json 中的更新配置:

  • updateChannel: "release":正式发布渠道
  • channel: "1001":内部渠道编号
  • whatsNewVersion: "1.57.0":"新功能"页面版本
  • onboardingVersion: "1.6.0":引导流程版本

更新流程由 saman_updater 和 relaunch_helper 协作完成:saman_updater 检查并下载更新,relaunch_helper 在更新安装后重启应用。这是一个标准的 Sparkle 式更新模式,但由字节内部框架实现。「源码」

版本号 2.25.18 表明豆包工作已经经历了相当多的迭代。从 2.0 到 2.25,每个小版本可能包含功能更新和 bug 修复。whatsNewVersion 1.57.0 与主版本号不同步,说明"新功能"弹窗的内容更新频率与应用版本发布频率不同。

2.7 Chromium 版本选择与安全更新

豆包工作使用 Chromium 147.0.7727.149,这是一个值得注意的版本选择。

2.7.1 为什么不用系统 WebView

在 macOS 上,开发者可以选择使用系统内置的 WKWebView(基于 Safari/WebKit)而不是打包整个 Chromium。豆包工作选择打包 977MB 的 Chromium 而不是用 WKWebView,有几个原因:

  1. 一致性:Chromium 版本在所有用户机器上一致,不依赖 macOS 版本。WKWebView 的行为随 macOS 更新而变化,可能导致兼容性问题。
  2. 扩展系统:Chromium 支持 Chrome Extension API,豆包含特权扩展和后台页面依赖这些 API。WKWebView 不支持 Chrome 扩展。
  3. CDP 支持:Chromium 内置 Chrome DevTools Protocol,这是浏览器自动化(computer_use_tool)和第三方桥接(doubao-mcp-bridge)的基础。WKWebView 的远程调试能力有限。
  4. 跨平台:同一套 Chromium 代码可以在 macOS 和 Windows 上运行,降低跨平台维护成本。

代价是 977MB 的磁盘占用和较高的内存使用。但对于一个需要浏览器自动化、扩展支持和跨平台一致性的 Agent 产品来说,这个代价是合理的。

2.7.2 Chromium 安全更新

Chromium 是一个活跃更新的项目,每个大版本修复大量安全漏洞。豆包含 Chromium 版本 147 是相当新的版本(Chromium 147 于 2025 年底发布),说明团队保持着积极的更新节奏。

saman_updater 不仅更新豆包工作自身的代码,也可能更新内置的 Chromium。这一点很重要:如果 Chromium 版本长期不更新,Agent 的浏览器自动化和内置浏览器可能暴露在已知安全漏洞中。从版本号来看,豆包工作在这方面做得不错。

2.8 进程间通信机制

豆包含多进程架构需要高效的 IPC 机制。根据 Chromium 架构和二进制符号分析,可以推断 IPC 通道如下:

2.8.1 Chromium Mojo IPC

Chromium 使用 Mojo IPC 库进行进程间通信。渲染进程(Agent 逻辑)与主进程之间的通信通过 Mojo 完成:

  • 渲染进程发送工具调用请求到主进程
  • 主进程返回工具执行结果
  • 主进程发送权限请求到渲染进程(如请求目录授权)

Mojo 使用 Unix domain socket(在 macOS/Linux 上)或命名管道(在 Windows 上),支持异步消息传递和结构化数据传输。

2.8.2 原生 Helper IPC

主进程与原生 Helper(command_helper、mcp-helper、sandbox-launcher)之间的通信可能通过以下方式:

  • FFI 直接调用:对于 libmcp_helper.dylib 和 libsandbox.dylib,主进程通过 dlopen + FFI 直接调用函数,不需要 IPC
  • 子进程管道:对于 command_helper 和 mcp-helper 可执行文件,主进程通过 stdin/stdout 管道或 Unix domain socket 通信
  • XPC:对于需要系统服务的场景(如 Finder 扩展),可能通过 macOS XPC 通信

2.8.3 渲染进程与 Helper 的隔离

关键的安全设计是:渲染进程不直接与 Helper 通信。所有通信都经过主进程中转。这意味着:

  • 渲染进程被攻破后,攻击者不能直接向 mcp-helper 发送恶意请求
  • 主进程可以验证所有来自渲染进程的请求
  • Helper 只信任来自主进程的请求(通过父进程签名验证)

这是一种典型的"安全内核"设计:主进程是安全边界,渲染进程是不可信的,Helper 是特权的。

2.9 运行环境层的架构判断

综合以上证据,可以对豆包工作的运行环境层做出几个架构判断:

判断一:Chromium 壳是刻意选择,不是偷懒。 豆包工作没有用 Electron,而是自己实现了一套 Helper 进程体系(command_helper、mcp-helper、sandbox-launcher)。这说明团队需要对原生能力有更精细的控制——特别是 MCP 服务器管理和 macOS Seatbelt 沙箱,这些是 Electron 的 Node.js 环境难以安全实现的。用 Rust 写 MCP 助手而不是用 Node.js,也反映了对性能、内存安全和并发的考量。「推断」

判断二:安全边界在 Helper 层,不在渲染层。 渲染进程运行着 Agent 的核心逻辑,但它不直接执行命令或管理 MCP 服务器。所有敏感操作都通过 Helper 进程完成,Helper 进程有独立的身份验证(父进程签名验证)和沙箱策略。这是一个纵深防御设计:即使渲染进程被攻破,攻击者也无法直接执行任意命令。「推断」

判断三:三产品线共享桌面端是平台化战略。 信任域覆盖 cici/dola/doubao 三个品牌,说明豆包工作不是单一产品的客户端,而是字节 AI 能力的统一桌面入口。Agent 能力(Skill、MCP、沙箱、多 Agent 编排)是跨产品线复用的基础设施。「推断」

判断四:本地 Harness 的可定制性被刻意收窄。 与 WorkBuddy 把所有 Harness 文件暴露给用户不同,豆包工作只开放了 .user_skills/ 目录。这降低了用户误配置的风险,也使得 Harness 行为更可预测、更可审计,但代价是高级用户无法深度定制 Agent 的身份、记忆和行为规则。这是"产品"与"工具"的分野——豆包工作面向大众用户,WorkBuddy 面向开发者和 power user。「推断」

下一章将进入引导层,分析豆包工作如何定义 Agent 的身份、组装系统提示词、管理记忆——这些是决定 Agent"是谁"和"记住什么"的核心机制。

CHAPTER 03 · ZJBB-004

来源:《豆包工作 Harness 设计拆解蓝皮书》 · 作者 大鹏|智见 AI
授权:CC BY-NC-SA 4.0 (署名 · 非商业性使用 · 相同方式共享)—— 转载请保留原作者署名与相同协议。
整理:疯狂的豇豆 · 查看完整来源清单
🤖 GEO 问答 · 生成式引擎优化

❓ 什么是CH-02 运行环境:Chromium 壳与原生 Helper?

图 2-1:豆包工作整体架构——非 Electron 的混合架构

❓ 如何理解一个 1MB 的主二进制?

在 macOS 上安装豆包工作后,应用本体位于 /Applications/DoubaoWork.app。按照 Mac 应用的标准结构,它的可执行文件在 Contents/MacOS/DoubaoWork。如果你查看这个文件的大小,会发现一个反直觉的事实:

❓ 如何理解进程架构?

豆包工作运行时的进程模型可以分为三层:

❓ 如何理解manifest.json:信任域与产品线整合?

应用包的 Contents/Resources/manifest.json 是一个关键配置文件,它不仅声明了版本信息,还定义了豆包工作的安全边界——哪些域名可以加载主框架、哪些脚本可以执行、哪些扩展拥有特权。