为了纠正大家都认为 ChatGPT Atlas 是 Chromium 的套壳,ChatGPT Atlas 工程团队编写本文来说明 ChatGPT Atlas 的底层有很多创新之处。虽然 Atlas 使用的是 Chromium,但它的构建方式与通常的 Chromium 不同。

Atlas 浏览器的核心创新在于其独特的 OWL 架构,该架构通过将 Chromium 引擎作为一个独立的服务层运行,从而与主应用程序进程分离。这种解耦设计不仅解决了传统浏览器架构在性能和用户体验上的瓶颈,还为实现复杂的 Agent (智能体) 功能和快速的产品迭代奠定了坚实的基础。它使得 Atlas 能够同时利用 Chromium 强大的网络兼容性与现代原生框架 (SwiftUI, AppKit) 带来的流畅体验。

关键细节

背景与挑战

  • 产品目标: 团队希望创造一款能将 ChatGPT 作为网络“副驾驶”的浏览器,拥有即时启动、支持数百个标签页而不影响性能,以及丰富的动画和视觉效果。
  • 技术选型: Chromium 因其先进的引擎、强大的安全模型和无与伦比的网络兼容性,成为自然的选择。
  • 架构难题: 直接使用或修改 Chromium 的标准架构难以实现上述产品目标,特别是快速启动和高性能。同时,深度修改 Chromium 会导致后续版本更新和维护变得极其困难和耗时。

解决方案:OWL 架构

  • 核心思想: OWL (OpenAI’s Web Layer) 是 OpenAI 的解决方案。它将 Chromium 的浏览器进程从 Atlas 主应用进程中剥离出来,使其成为一个独立的后台服务。
  • 工作模式: Atlas 应用作为 OWL Client (客户端),而 Chromium 进程作为 OWL Host (主机)。两者通过 Chromium 自家的消息传递系统 Mojo 进行通信 (IPC)。

OWL 带来的优势

  • 应用更简洁: Atlas 的用户界面几乎完全由 SwiftUIAppKit 构建,代码库更清晰、技术栈更统一。
  • 启动更快速: Chromium 在后台异步启动,用户界面几乎可以瞬间加载。
  • 隔离性更强: Chromium 引擎的卡顿或崩溃不会影响 Atlas 主应用的稳定性。
  • 维护更容易: 由于 Atlas 没有构建在 Chromium 的开源 UI 之上,与上游 Chromium 的代码差异更小,便于维护和升级。
  • 迭代更迅速: 大多数工程师无需在本地编译 Chromium (耗时数小时),而是使用预编译的 OWL 二进制文件,使 Atlas 的构建时间从数小时缩短到几分钟。

针对 Agent 功能的特殊设计

  • 渲染: 为了让 AI 模型能看到完整的页面上下文,Atlas 会将下拉菜单等在主窗口外渲染的 UI 元素重新组合到主页面图像中。
  • 输入: Agent 生成的输入事件会直接发送到渲染器,而不是通过拥有更高权限的浏览器层,以保证沙箱安全边界。
  • 数据隔离: Agent 浏览可以在临时的“登出”环境中运行。它使用 ChromiumStoragePartition 基础架构创建隔离的内存存储,确保每个 Agent 会话都是全新的,会话结束后所有数据都会被丢弃。

原文:我们如何构建OWL:我们基于ChatGPT的浏览器Atlas背后的新架构

作者:Ken Rockot,技术团队成员;Ben Goodger,ChatGPT Atlas工程主管

上周,我们发布了ChatGPT Atlas,这是一种在ChatGPT陪伴下浏览网页的新方式。Atlas不仅是一款功能齐全的网页浏览器,还让我们得以一窥未来:一个您可以带着ChatGPT畅游互联网,让它为您提问、提供建议并完成任务的世界。在这篇文章中,我们将解析产品中最复杂的工程难题之一:我们如何将ChatGPT转变为一个越用越好用的浏览器。

要让ChatGPT成为真正的网络副驾驶,意味着要重构浏览器的整个架构:将Atlas从Chromium运行时中分离出来。这需要开发一种集成Chromium的新方法,使我们能够实现产品目标:即时启动、即使打开更多标签页也能保持响应,并为“代理人”(agentic)用例奠定坚实的基础。

奠定基础

xx

Chromium是一个天然的构建模块。它提供了最先进的Web引擎、强大的安全模型、公认的性能凭证以及无与伦比的Web兼容性。此外,它由一个不断改进它的全球社区开发。它是现代桌面网页浏览器的常见选择。

重新思考浏览器体验

我们才华横溢的设计团队对用户体验有着宏伟的目标,包括为“代理人模式”(Agent mode)等功能提供丰富的动画和视觉效果。这就要求我们的工程团队在用户界面(UI)上利用最现代的原生框架(SwiftUI、AppKit和Metal),而不是简单地为开源的Chromium UX“换肤”。因此,Atlas的UI是对整个应用程序UX的全面重建。

我们还有其他产品目标,比如快速的启动时间,以及支持数百个标签页而不影响性能。这些目标很难通过开箱即用的Chromium来实现,因为它对从启动序列、线程模型到标签页模型等许多细节都有固定的设定。我们曾考虑在此处进行重大更改,但我们希望保持对Chromium的补丁集有针对性,以便我们能快速集成新版本。为确保我们的开发速度得到最大程度的提升,我们需要想出一种不同的方式来集成和驱动Chromium运行时。

对我们技术投资的一项试金石是,它不仅能让我们更快地实验、迭代和交付新功能——它还能让我们保持OpenAI工程文化的核心部分:在第一天就发布(shipping on day one)。每位新工程师在他们入职第一天的下午都会进行并合并一个小更改。我们需要确保这一点是可能的,即使Chromium的检出(check out)和构建可能需要数小时。

我们的解决方案:OWL

我们应对这些挑战的答案是构建一个我们称之为**OWL(OpenAI’s Web Layer)**的新架构层。OWL是我们对Chromium的集成,它需要将Chromium的浏览器进程运行在Atlas主应用进程之外

xxx

可以这样想:Chromium通过将标签页移至单独的进程中,彻底改变了浏览器。我们正在将这一理念推得更远,将Chromium本身从主应用程序进程中移出,并放入一个隔离的服务层。这一转变带来了一系列好处:

  • 一个更简洁、现代的应用程序: Atlas几乎完全用SwiftUI和AppKit构建。一种语言,一个技术栈,一个简洁的代码库。
  • 更快的启动速度: Chromium在后台异步启动。Atlas无需等待——像素几乎瞬间就能显示在屏幕上。
  • 与卡顿(jank)和崩溃隔离: Chromium是一个强大而复杂的Web引擎。如果它的主线程挂起,Atlas不会。如果它崩溃了,Atlas仍能保持运行。
  • 更少的合并麻烦: 因为我们没有在Chromium开源UI的基础上构建那么多东西,所以我们与上游Chromium的差异(diff)要小得多,也更容易维护。
  • 更快的迭代速度: 大多数工程师永远不需要在本地构建Chromium。OWL作为预构建的二进制文件在内部分发,因此Atlas的构建只需几分钟,而不是几小时。

因为我们团队中的大多数工程师不经常从源代码构建Chromium,开发速度可以快得多——即使是新团队成员也可以在他们入职的第一个下午合并简单的更改。

OWL的工作原理

从高层次上讲,Atlas浏览器是OWL客户端(OWL Client),而Chromium浏览器进程是OWL宿主(OWL Host)。它们通过IPC(进程间通信)进行通信,特别是Mojo(在新窗口中打开),这是Chromium自己的消息传递系统。我们为Mojo编写了自定义的Swift(甚至TypeScript)绑定,因此我们的Swift应用程序可以直接调用宿主端的接口。

OWL客户端库暴露了一个简单的公共Swift API,它抽象了宿主服务层暴露的几个关键概念:

  • Session(会话): 全局配置和控制宿主
  • Profile(配置文件): 管理特定用户配置文件的浏览器状态
  • WebView(网页视图): 控制和嵌入单个网页内容(例如渲染、输入、导航、缩放等)
  • WebContentRenderer(网页内容渲染器): 将输入事件转发到Chromium的渲染管线,并从渲染器接收反馈
  • LayerHost/Client(图层宿主/客户端): 在UI和Chromium之间交换合成信息

xxx

此外还有一系列广泛的服务端点,用于管理书签、下载、扩展和自动填充等高级功能。

渲染:让像素跨越进程边界

WebView在客户端应用程序中共享一个互斥的表示空间,它们在一个共享的合成容器(compositing container)中换入和换出。例如,一个浏览器窗口通常有一个可见的共享容器,在标签页栏中选择一个标签页会将该标签页的WebView换入该容器。在Chromium端,此容器对应一个gfx::AcceleratedWidget,它最终由一个CALayer支持。我们将该图层的上下文ID(context ID)暴露给客户端,客户端中的一个NSView使用私有的CALayerHost API将其嵌入。

xxx

<select>下拉菜单或颜色选择器这样的特殊情况,Chromium会在单独的弹出窗口小部件(popup widgets)中渲染它们,它们使用相同的方法。它们没有content::WebContents,但它们确实有自己的content::RenderWidgetHostViewgfx::AcceleratedWidget,因此同样的委托渲染模型(delegated rendering model)也适用。

OWL在内部保持视图几何形状(view geometry)与Chromium端同步,因此GPU合成器(compositor)可以相应更新,并始终能生成正确尺寸和设备缩放比例的图层内容。

我们还重用此技术,将Chromium自己的原生Views UI元素选择性地投射到Atlas中(这对于快速引导(bootstrapping)权限提示等功能,而无需在SwiftUI中从头构建替代品也很有用)。这项技术在很大程度上借鉴了Chromium现有的用于macOS上可安装Web应用的基础设施。

输入事件:解析和转发

Chromium UI在将平台事件(如macOS的NSEvents)转发给渲染器之前,会将其转换为Blink的WebInputEvent模型。但由于OWL在隐藏进程中运行Chromium,我们在Swift客户端库中自己进行转换,并将已转换的事件向下转发给Chromium。

xxx

从那里开始,它们遵循与真实输入事件在网页内容中通常会遵循的相同生命周期。这包括当页面指示它未处理该事件时,将事件返回给客户端。发生这种情况时,我们会重新合成一个NSEvent,并让应用程序的其余部分有机会处理该输入。

代理人模式:特殊情况

Atlas的“代理人浏览”(agentic browsing)功能对我们的渲染、输入事件转发和数据存储方法提出了一些独特的挑战。

我们的计算机使用模型期望屏幕的单个图像作为输入。但某些UI元素,例如<select>下拉菜单,会在标签页边界之外的单独窗口中渲染。在代理人模式下,我们将这些弹出窗口合成回主页面图像中的正确坐标处,以便模型能在一个帧中看到完整的上下文。

对于输入,我们应用相同的原则:代理人生成的事件被直接路由到渲染器,绝不通过特权浏览器层。即使在自动控制下,这也保留了沙盒边界。例如,我们不希望这类事件合成使浏览器执行与所显示的网页内容无关操作的键盘快捷键。

代理人浏览也可以在临时的“未登录”上下文中运行。我们不共享用户现有的“无痕”配置文件(Incognito profile)(这可能会泄漏状态),而是使用Chromium的StoragePartition基础设施来启动隔离的、内存中的存储。每个代理人会话都是全新开始,当它结束时,所有cookie和站点数据都将被丢弃。您可以运行多个“未登录”的代理人会话,每个会话都在自己的浏览器标签页中,并且彼此完全隔离。

一种使用网络的新方式

没有全球Chromium社区和他们在为现代网络奠定基础方面所做的令人难以置信的工作,这一切都是不可能的。OWL以一种新的方式建立在这个基础之上:将引擎与应用程序解耦,将世界一流的Web平台与现代原生框架相融合,并释放出更快、更灵活的架构。

通过重新思考浏览器如何容纳Chromium,我们正在为新型体验创造空间:更流畅的启动、更丰富的UI、与操作系统其余部分更紧密的集成,以及一个与思想同步发展的开发循环。如果这听起来像是您喜欢的那种挑战,请查看我们在Atlas的工作机会:Atlas软件工程师⁠iOS软件工程师⁠以及更多职位⁠

chatgpt.com/atlas⁠ ⁠(在新窗口中打开) 试用Atlas。

致谢

特别感谢Darin Fisher和Marie Shin对本文的贡献,以及构建Atlas的整个OpenAI团队。

作者

Ken Rockot, Ben Goodger