硅基俊宁.
← 返回文章

漫画拆解 ChatGPT App:内置浏览器藏在哪里

俊宁 · 2026-10-31
文章目录

沿用原稿记录的特定 macOS 应用版本,解释 Electron 宿主、内嵌 Chromium 与任务控制层的关系,不推导未经验证的运行时能力。

本文讨论通用机制和设计判断;示意不对应任何具体产品的已交付状态。源码阅读坐标沿用原稿,本次整理不构成新的运行时验收。

在桌面应用里打开一张网页,看起来只是多了一块浏览区域。它背后却可能是系统 WebView,也可能是一套随应用分发的浏览器内核。为了弄清这台 Mac 上的 ChatGPT 属于哪一种,这次从 ChatGPT.app/Contents 入手,检查了应用元数据、Framework 和 app.asar 中的代码。

封面:小狐和小机打开应用箱,发现里面装着完整的浏览器引擎

结论是:这个安装版本直接携带 Chromium,应用使用 Electron 和 React;内置浏览器通过 <webview> 挂载,主进程管理页面,Agent 通过 CDP 接入。

下面的角色和场景是机制示意,不是产品界面截图。分析对象为 macOS 上的 ChatGPT 26.1023.51421,build 22530,检查日期为 2026 年 10 月 31 日。这是一轮安装包静态分析,没有执行真实网页任务,也不代表其他平台或历史版本采用相同实现。

第一幕与第二幕:箱子里自带引擎,铭牌还要再核对

第一、二幕:应用包自带 Chromium;外部名称是 ChatGPT,内部仍保留 Codex 标识

小狐最先问的是:“这个浏览器是不是系统提供的?”小机没有先猜框架,而是打开安装目录。Frameworks 下存在 Codex Framework.framework,其中的版本目录为 156.0.8078.48;应用 Info.plist 中的 ChromiumBaseVersion 与它一致。

这说明内核随应用一起分发。这里的 Electron <webview> 使用内置 Chromium,不是 macOS 的 WKWebView,也不需要借用另外安装的 Chrome。 不过,自带浏览器内核不等于整个应用脱离操作系统:窗口、权限和输入等能力仍需要平台支持。

继续读铭牌,会发现一个容易忽略的细节:显示名称是 ChatGPT,Bundle ID 却是 com.openai.codex;app.asar/package.json 的包名是 openai-codex-electron。因此,文章只判断眼前的安装包,不用产品名称反推它与过去版本的实现关系。

看到的证据可以确认什么
openai-codex-electron,以及 BrowserWindow、ipcMain 调用桌面应用使用 Electron 接口
前端 bundle 中的 React runtime、Hooks 和 JSX 调用应用界面使用 React
.vite/build/ 与 Rolldown runtime存在 Vite 构建产物与 Rolldown runtime
ChromiumBaseVersion: 156.0.8078.48当前包内 Chromium 的版本
node-pty、better-sqlite3、objc-js 和原生 .node 模块本地终端、数据库与平台桥接依赖已随包分发
Sparkle.framework 和更新源配置包含 Sparkle 更新组件

依赖存在能证明组件被打包,不能单独证明每项功能都已启用或在当前账号可用。

第三幕与第四幕:把网页装进窗口,把权限留给管理层

第三、四幕:界面创建 webview,主进程管理网页;网页关闭 Node 集成并启用隔离配置

找到内核后,小狐沿着网页继续走。前端共享代码里有一个直接的入口:

document.createElement(`webview`)

同一片代码维护 browserTabId、conversationId、hostGeneration 和 rendererInstanceId。它们分别参与标签页、对话及页面宿主的识别。网页由 Electron 的 guest WebContents 承载,应用再把它与当前任务的展示位置关联起来。

随后接手的是主进程中的浏览器管理逻辑。名为 browser-sidebar-manager 的日志标识周围,可以找到标签页状态、页面挂载与转移、恢复、后台页面预算、下载和权限提示等代码。will-attach-webview 与 did-attach-webview 事件把界面的嵌入动作连接到主进程。

页面挂载配置包含以下设置。这里按字段整理展示,不是完整源码:

{
  sandbox: true,
  nodeIntegration: false,
  contextIsolation: true,
  webSecurity: true
}

主进程还为浏览器页配置 Session 和 browser-page-preload.js。Preload 是应用与页面能力之间的桥接位置,可以接入批注等受控功能;它不意味着普通网页直接获得 Node.js 权限。这些配置是已见的隔离措施,不能替代完整安全审计。

这里还有两个容易混淆的边界:

看起来相近的概念本次代码支持的结论
标签页归属于某个对话 / 每个对话拥有独立 Cookie前者有路由和标识证据;代码会配置浏览器 Session,不能仅凭 conversationId 推断后者
WebContentsView / <webview>包内都出现过;查到的 WebContentsView 用于下载辅助逻辑,浏览器页面宿主明确创建了 <webview>

所以,“用了 Electron”只是第一层答案。网页如何保存、何时挂载、怎样转移、权限由谁处理,都属于应用额外实现的管理逻辑。

第五幕与第六幕:Agent 接入页面,调查停在证据边界

第五、六幕:Agent 经 CDP 控制页面 WebContents;Owl 的接管接口可见,完整底层补丁仍未知

小狐接着问:“Agent 操作的是另一台浏览器,还是眼前这张网页?”本次代码给出的路径是:Browser Use 后端经过会话路由,找到页面的 WebContents,再使用 Electron 的 debugger 接口发送 CDP 命令。

将压缩后的变量名换成含义明确的名称,可以看到这两个关键调用:

webContents.debugger.attach(`1.3`)
webContents.debugger.sendCommand(/* CDP 方法与参数 */)

主进程还包含 Target.attachToTarget、Target.getTargets、子 Session、控制权释放和超时处理。因此,这不是只有一个“执行浏览器命令”的按钮;它需要维护任务与页面的归属,并处理控制过程的生命周期。

这条集成路径让 Agent 能接入应用承载的页面。 本次没有运行真实任务,因而不进一步宣称所有操作都成功、前后台表现一致,或全部浏览器工具都采用这条后端。包内还能看到其他浏览器后端的标识,不能把它们与内置浏览器混为一谈。

调查的最后一扇门写着 Owl。前端宿主中出现了这些属性名,页面代码中还有对应的转移方法:

owl-webcontents-adoption-lease
owl-webcontents-adopted-web-contents-id
adoptForWindowTransfer

它们与页面接管、窗口间转移逻辑同时出现;构建引用中也保留了 owl-shell.mjs 和 ensure-owl-electron-types.mjs。这些证据支持“运行时带有定制扩展,并暴露了页面接管与转移接口”的判断。

但铭牌和接口没有交出完整施工图。具体修改了哪些 Chromium/Electron 源码、对应哪个上游 Electron 版本、迁移时有哪些限制,仍不能从这次检查中确定。 漫画里把网页搬到另一扇窗口,只表达代码中的转移意图,不冒充已验证的无损迁移效果。

把线索放回原位:下次可以怎样检查

判断一个桌面应用的浏览器集成,可以沿着“分发物、页面宿主、管理逻辑、控制通道”四步走。只看应用图标或一个类名,很容易把不同层次混在一起。

下面两条只读命令足以复核本次最核心的内核证据:

/usr/libexec/PlistBuddy -c 'Print :ChromiumBaseVersion' \
  /Applications/ChatGPT.app/Contents/Info.plist

ls '/Applications/ChatGPT.app/Contents/Frameworks/Codex Framework.framework/Versions'

更深入的结论来自 Resources/app.asar。以下路径均相对于该归档;带哈希的文件名属于本次版本,升级后可能变化。

归档内位置本次查到的线索
package.json应用包名、版本、入口、依赖和构建脚本引用
webview/assets/app-shared-e9f258fd3588.js创建 <webview>、宿主标识、Owl 接管属性
.vite/build/main-UOTY8NmV.js浏览器管理、Session、安全配置、debugger 与 CDP 调用
.vite/build/browser-page-preload.js浏览器页面的 preload 产物
webview/assets/page-ce7ec66128b2.js页面宿主、窗口转移准备与接管调用

这次检查的价值,是把“内置浏览器”拆成可回查的四层:随应用分发的 Chromium,承载网页的 <webview>,管理生命周期的主进程,以及连接 Agent 的 CDP 通道。 Owl 的定制接口位于这条链路中,但底层补丁范围仍需源码或更多运行证据才能回答。

本文使用 writting-skill 辅助写作,配图使用 better-imagegen 生成。项目已开源,欢迎在 GitHub 点个 Star。