作者:Ken Rockot,技術人員和 Ben Goodger,ChatGPT Atlas 工程主管
上星期我們推出了 ChatGPT Atlas,這是一個讓 ChatGPT 伴隨您瀏覽網絡的新方式。除了是一款功能齊全的網絡瀏覽器,Atlas 還提供了一個對未來的展望:一個你能夠帶著 ChatGPT 在網絡世界中四處遊走並提問的世界。在這篇貼文中,我們將深入探討此產品在工程上最複雜的一面:我們如何將 ChatGPT 打造成一個越用越好用的瀏覽器。
要讓 ChatGPT 成為互聯網的真正副手,意味著必須重新構想瀏覽器的整體架構:將 Atlas 從 Chromium 執行環境中分離出來。這涉及開發一種新的 Chromium 整合方式,使我們能夠達成產品目標:瞬間啟動、在開啟更多分頁時仍維持反應靈敏,並為智能代理應用場景打造穩固的基礎。

Chromium 是一個天然的建構基石。它提供了一個最先進的網頁引擎,擁有強大的安全架構、可靠的效能紀錄,以及卓越的網頁兼容能力。此外,它由一個不斷改良它的全球社群所開發。它是現代桌上型網頁瀏覽器常見的首選。
我們才華洋溢的設計團隊對我們的用戶體驗抱持著雄心壯志的目標,包括為「智能代理模式」等功能設計豐富的動畫和視覺效果。這要求我們的工程團隊利用最現代的原生框架來架設我們的用戶介面(SwiftUI、AppKit 和 Metal),而不是簡單地重新包裝開源的 Chromium 用戶體驗。因此,Atlas 的用戶介面是對整個應用程式用戶體驗的全面重建。
我們還有其他產品目標,例如更快的啟動時間,以及在不影響效能的情況下支援數百個分頁。這些目標很難透過現成的 Chromium 來達成,因為 Chromium 對於許多細節都有既定的設計理念,包括啟動順序、執行緒模型和分頁模型等。我們曾考慮對此進行大幅修改,但我們希望針對 Chromium 的修正檔保持集中,以便能夠快速整合新版本。為了保證我們的開發速度得到最大限度的提升,我們需要提出一種不同的方法來整合並操作 Chromium 執行環境。
衡量我們技術投資的標準不僅是它能促進更快速的實驗與功能交付速度,同時也要能讓我們延續 OpenAI 工程文化的核心精神:首日即上線。每位新工程師都在上任第一天下午完成並合併一項小的修改。我們需要確保這是可行的,儘管 Chromium 可能需要花費數小時取得程式碼及進行編譯。
為應對這些挑戰,我們建立了一個新的架構層,我們稱之為 OWL:OpenAI 的 Web 層。OWL 是我們整合 Chromium 的方式,它代表將 Chromium 的瀏覽器程序運行在 Atlas 主應用程序流程之外。
想像一下:Chromium 透過將分頁移至獨立程序中,徹底改變了瀏覽器。我們將這個概念更進一步,把 Chromium 本身從主應用程式程序移出,並移至一個隔離的服務層。這個轉變可產生一連串的好處:
- 一個更簡潔、現代的應用程式:Atlas 幾乎完全以 SwiftUI 和 AppKit 架設。單一的語言,單一的技術堆疊,單一的乾淨程式碼庫。
- 更快的啟動速度:Chromium 在背景以非同步方式啟動。Atlas 不會等待,像素幾乎是瞬間顯示在螢幕上。
- 與卡頓和崩潰說再見:Chromium 是一個強大而且複雜的網絡引擎。即使它的主執行緒停止回應,Atlas 仍能正常運作。即使它崩潰,Atlas 仍能正常運作。
- 更少的合併麻煩:由於我們並非建立在如此大量的 Chromium 開源用戶介面之上,我們與上游 Chromium 的差異要小得多,而且更容易維護。
- 更快地改進:大多數工程師從不需要在本機編譯 Chromium。OWL 在內部是以預先編譯的二進位檔發佈的,因此要架設 Atlas 花費的只是幾分鐘而不是幾小時。
由於我們團隊中多數工程師都不會定期從原程式碼編譯 Chromium,開發速度可以快很多,即使是剛加入的團隊成員也可以在入職第一天下午完成合併簡單的修改。
從宏觀角度來看,Atlas 瀏覽器是 OWL 的客戶端,而 Chromium 瀏覽器程序是 OWL 的伺服器主機。它們透過 IPC 進行通訊,具體來說是透過 Mojo(在新視窗中開啟),也就是 Chromium 自家的訊息傳遞系統。我們為 Mojo 撰寫了自訂的 Swift(甚至包括 TypeScript)橋接層,讓我們的 Swift 應用程式能夠直接呼叫主機端介面。
OWL 用戶端函式庫提供了一個簡單的公開 Swift API,它抽象化了主機服務層所提供的數個關鍵概念:
- 工作階段:全域設定與控制主機
- 用戶設定檔:管理特定用戶設定檔的瀏覽器狀態
- WebView:控制並嵌入單一網頁內容(例如渲染、輸入、導航、縮放等)
- WebContentRenderer:把輸入事件傳送進 Chromium 的渲染管道,並接收來自渲染器的回饋資料
- LayerHost/Client:在用戶介面與 Chromium 之間進行合成資訊交換
此外,還提供多種服務端點,用來管理書籤、下載、擴充套件以及自動填入等高層級功能。
WebView 在客戶端應用程式中共用一個互相排他的顯示區域,會被切換進出同一個共享合成容器。舉例來說,瀏覽器視窗通常只有一個可見的共享容器,當在分頁列中選取一個分頁時,該分頁的 WebView 會被切換到該容器中。在 Chromium 的部分,這個容器對應到一個gfx::AcceleratedWidget,其底層實際上是由 CALayer 所支援的。我們讓客戶端取得該層的內容 ID,而 NSView則使用私有的 CALayerHost API 將其嵌入。
像下拉式選單或顏色選擇器這些特殊情況下,Chromium 會在獨立的彈出 Widget 中渲染,渲染模式與主要畫面相同。它們雖然沒有content::WebContents ,但確實有自己的content::RenderWidgetHostView及各自的gfx::AcceleratedWidget,因此相同的委派渲染模型依然適用。OWL 內部會將視圖幾何資訊與 Chromium 端同步,以便 GPU 合成器可以相應更新,並隨時生成正確大小與裝置比例的圖層內容。我們也重複使用這個技術,將 Chromium 自身的原生 Views 用戶介面元素選擇性地投射到 Atlas 中
(這對於快速啟動像是權限提示之類的功能也很有用,無需在 SwiftUI 中重新製作)。此技術大量借用了 Chromium 在 macOS 上針對可安裝網頁應用程式的既有架構。輸入事件:解析與轉發Chromium 的用戶介面會將平台事件(例如 macOS NSEvents)轉換為 Blink 的 WebInputEvent 模型,再轉發到渲染器。但由於 OWL 在隱藏程序中執行 Chromium,我們在 Swift 客戶端函式庫中自行執行該轉譯,並將已轉譯的事件向下轉發給 Chromium。從這裡開始,它們會遵循真實輸入事件通常在網頁內容中的生命週期。這包括當頁面顯示未處理事件時,將事件回傳給客戶端。當發生這種情況時,我們會重新生成 NSEvent,並讓應用程式的其他部分有機會處理輸入。智能代理模式:特殊情況Atlas 的智能代理瀏覽功能對我們在渲染、輸入事件轉發和資料儲存的處理方式,帶來了一些獨特的挑戰。我們的電腦使用模型預期以螢幕的單一影像作為輸入。然而部分用戶介面元素,例如 下拉式選單,會在分開的視窗中呈現,超出分頁的邊界。在智能代理模式中,我們會將這些彈出視窗依正確座標合成回主頁面圖像,讓模型能在單一畫面中看到完整內容。
對於輸入,我們採用相同原則:由智能代理產生的事件會直接傳送到渲染器,從不經過特權瀏覽器層。這樣即使在自動控制下也能保持沙盒邊界。例如,我們不希望這類事件合成鍵盤快捷鍵,讓瀏覽器執行與所顯示網頁內容無關的操作。
智能代理瀏覽也可以在短暫的「登出」環境中執行。我們不共用用戶現有的無痕模式設定檔(因可能洩露瀏覽器狀態),而是使用 Chromium 的StoragePartition基礎架構來建立隔離的記憶體內的儲存空間。每個智能代理工作階段都是重新開始的,當它結束時,所有 Cookie 和網站資料都會被捨棄。您可以執行多個「登出」智能代理工作階段,每個工作階段都在自己的瀏覽器分頁中,並且彼此完全隔離。
如果沒有全球 Chromium 社群以及他們打造現代互聯網基礎方面的卓越貢獻,這一切都不可能實現。OWL 在此基礎上以創新方式發展:將引擎與應用程式分離,結合世界級網絡平台與現代原生框架,開創更快速、更靈活的架構。
透過重新設計瀏覽器對 Chromium 的承載方式,我們正在開啟新的體驗可能性:啟動更順暢、介面更豐富、與作業系統的整合更緊密,以及開發流程以跟得上想法的速度前進。如果這聽起來正是您想要的挑戰,歡迎查看我們的職缺,加入 Atlas 擔任軟件工程師, Atlas,軟件工程師,iOS,以及更多相關職位。
試用 Atlas 請前往 chatgpt.com/atlas(在新視窗中開啟)。


