TL;DR:我們需要一個新的框架、膠水層,來幫助我們適配生成式 AI 的輸出,以及解決流式資料傳輸的問題。
在過去幾個月裡,我們一直在專案上探索:如何設計更好的架構,以將業務流程和開發流程中的各類智慧體結合起來,進一步釋放生成式 AI 的潛力?諸如於面向 IDE、DevOps、Team AI 等多個不同消費端的智慧體。

在這個過程中,浮現了一種新的架構模式:流式 BFF。
流式 BFF(Streaming Backend for Frontend) 是一種適用於 AI 原生架構的膠水層,旨在解決 HTTP API 與智慧體協同過程中的資料流處理和介面不一致等問題。
引子 0:生成式 AI 時代的架構演進
在先前的文章裡《LLM 優先的軟體架構》裡,我們介紹了四個原則:使用者意圖導向設計 、上下文感知、原子能力對映、語言 API。而那篇《語言介面:探索大模型優先架構的新一代 API 設計》中,我們介紹了 自然語言即 DSL、即時文字流 DSL、本地函式動態代理等模式。這些模式為我們開發 AI 原生應用帶來了新的思路。
在過去構建 AI 輔助研發應用時,除了應用內建的各類編碼智慧體之外,我們的重點還放在雲端智慧體的整合上,旨在提升整體效率和智慧化水平。這些智慧體包含:
-
AI 平臺智慧體。如部署在類 Dify 平臺上的智慧體
-
三方智慧體服務。即提供智慧體功能的其它服務
-
系統內智慧體。即可以透過函式呼叫的內部智慧體
而由於生成式 AI 的輸出方式:類似於打字機效果,字元逐字詞輸出。在這種限制了互動體驗的場景下,主流的智慧體提供的都是流式輸出方式。這種流式傳輸的實現通常依賴於Server-Sent Events(SSE)技術,它允許服務端主動向客戶端推送訊息,建立長連線後,服務端可以源源不斷地向客戶端推送訊息, 從而實現流式輸出。
引子 1:降低 Streaming Hell 帶來的影響

當客戶端直接呼叫大模型時,通常只需發出一個簡單的請求即可獲取完整的響應。然而,當我們在服務端透過流式方式(例如 Server-Sent Events, SSE)處理資料時, 情況變得更加複雜。每當增加一層服務或代理時,流式資料處理的負擔都會傳遞給下一層。這種層層累積的複雜性,我們稱之為 Streaming Hell。
其帶來的挑戰有:持續連線的開銷、多層流式傳遞的傳染效應、資源管理的複雜性、錯誤傳播和恢復等。要解決 Streaming Hell,我們需要採用一些策略:
-
流式處理標準化:定義統一的介面和協議,使各層服務能夠一致高效地處理流式資料。
-
非同步與事件驅動架構:採用非同步或事件驅動架構,減少對同步流式處理的依賴,提高擴充套件性和響應速度。
-
減少層級依賴:儘量減少不必要的服務呼叫層次,避免每一層服務都直接處理流式資料。
-
流式資料聚合:在必要時對流式資料進行聚合和處理,以減少不必要的傳遞層次,最佳化系統性能。
-
錯誤處理與重試機制:設計健壯的錯誤處理和重試機制,確保當某一層服務出現錯誤時能夠進行自動恢復或降級。
透過有效的設計,我們可以減少 Streaming Hell 帶來的複雜性,並提高系統的可靠性和可維護性。
引子 2:智慧體應用架構面臨的新挑戰

在業務系統整合這些智慧體時,系統的架構需要隨之演進,以適應流式輸出的要求。例如,後端服務需要支援流式響應,前端應用則需要能夠處理和展示這種漸進式的資料流。
挑戰 1:統一多模型介面,簡化資料傳輸與解析
在我們構建面向普通使用者的開源應用,如 ClickPrompt、AutoDev 和 Shire 時,需要支援不同大語言模型的介面。由於使用者可能選擇不同的模型供應商, 這就要求我們能夠相容多種模型介面。在 AutoDev 時代,我們主要採用相容 OpenAI 格式的介面,並且可以支援大量的自定義資料格式, 如採用 JsonPath 從
$.choices[0].message.delta.content
獲取文字。而在非公開 API 場景下,這種基於 JSON 格式的介面存在一些挑戰:
-
解析耗時:JSON 格式需要在應用中進行解析,這會消耗額外的處理時間和資源。
-
資料傳輸量大:在某些場景下,我們只需要傳輸文字內容,而不需要整個 JSON 物件,這導致了不必要的資料傳輸。
所以在時,我們通常會考慮簡化介面、統一介面格式、最佳化資料傳輸等方式來提升系統的效能和使用者體驗。
挑戰 2:智慧體介面不一致
相似的,當我們有 AI 平臺等不同的智慧體提供商時,由於不同的智慧體通常有各自獨特的介面規範,通常會導致介面與處理方式不一致。例如,在 Dify 平臺中:
-
在 Completion 場景下,輸出為
$.answer
。 -
在 Workflow 場景下,輸出為
$.data.outputs
,且outputs
本身也是一個物件。
這種介面的不一致性在多智慧體協同工作時增加了前端處理的複雜度。而為了更好的相容不同的智慧體,通用的方式是引入一層對映機制,將不同智慧體的輸出統一為一致的文字格式。
挑戰 3:與傳統 API 服務的不同步
在 Web 2.0 時代,API 的響應速度至關重要。為了提高響應速度,我們採用了請求快取、DNS 快取以及 CDN 快取等多種最佳化手段。然而,當前服務端使用的是 SSE(Server-Sent Events)技術,以逐字生成的方式傳輸資料,這與傳統 API 的即時響應模式存在顯著差異。
儘管 SSE 不是長連線,但仍需考慮其對伺服器資源的消耗。此外,生成式 AI 本身的響應速度有限,這進一步影響了系統整體的響應時間。同時, 前端在處理流式資料時,需要更高的處理能力和更復雜的邏輯來管理和展示逐步生成的資料流。
流式 BFF:AI 原生架構下的協同模式

傳統的 BFF 模式關注為特定的前端應用定製後端服務,以滿足前端的特定需求。在 AI 原生應用中,由於生成式 AI 的特性以及多個智慧體需要協同工作, 我們需要對 BFF 進行擴充套件,支援流式資料和即時處理。
定義流式 BFF
模式:流式 BFF(Streaming Backend for Frontend) 是一種適用於 AI 原生架構的膠水層,旨在解決 HTTP API 與智慧體協同過程中的資料流處理和介面不一致等問題。
意圖:透過在膠水層,統一智慧體介面,處理不同客戶端的智慧體協同,以簡化系統的開發和使用。
適合場景:當且僅當系統中,存在不同的客戶端,並且這些客戶端需要與多個智慧體協同工作時。
示例:在構建生成式 AI 輔助研發應用時,存在 IDE、DevOps 平臺、IM 應用、團隊 AI 入口等多個客戶端,多個客戶端之間需要部分相同、但是又有所 不同的智慧體。
通常來說,流式 BFF 的核心特性包括:
-
統一介面:封裝並標準化不同智慧體的介面,提供一致的資料格式,簡化前端開發。
-
流式處理:支援即時資料流,能夠處理生成式 AI 逐步產生的資料,實現邊生成邊傳輸,提升使用者體驗。
-
即時過濾:在資料流中即時檢測和過濾敏感資訊,保障系統安全和合規性。
-
協調傳統 API:與傳統的 API 服務高效協同,解決響應速度和資料同步問題。
當然,隨著我們對流式 BFF 的進一步探索,我們相信流式 BFF 還有更多的潛力等待挖掘。
我們需要怎樣的流式 BFF?
儘管,當前我們初步思考了流式 BFF 的一種可能性,然而如何去構建這樣的工具,依舊是一個未知的領域,還需要進一步的沉澱和探索。我們的早先版本是基於 Vercel 的 AI.js SDK 配合 Next.js 來構建的原型,由於 AI.js 提供了非常好的流式介面支援,與此同時,JavaScript/TypeScript 靈活的 any 特性 也使得我們能夠快速地構建出一個流式 BFF。
協調不一致性
BFF 的本質在於協調前端與後端的互動,尤其是在面對複雜服務生態時,BFF 已經很好地解決了與傳統 API 的一致性問題。它透過提供一層抽象, 統一了多個後端服務的呼叫方式。在即時處理場景下,我們更需要關注如何提供外部或第三方服務的介面,而不是構建全新的架構。因此,流式 BFF 的核心問題應該聚焦於如何在介面層面上實現統一,同時透過流式處理確保即時資料傳輸的穩定性和高效性。
內建主流大模型的支援
得益於 Vercel 的 AI SDK,我們能夠輕鬆地為 BFF 內建對主流大模型的支援。Vercel 的 AI SDK 針對多個大模型(如 OpenAI、Anthropic、LlamaIndex 等) 進行了適配,提供了流式介面,使得我們能夠無縫地整合不同的 AI 模型,並透過統一的流式處理機制來響應這些模型的資料。
一個典型的流式模型處理模式如下:
-
exportfunction toDataStream(
-
stream:AsyncIterable<EngineResponse>,
-
callbacks?:AIStreamCallbacksAndOptions,
-
){
-
return toReadableStream(stream)
-
.pipeThrough(createCallbacksTransformer(callbacks))
-
.pipeThrough(createStreamDataTransformer());
-
}
在這種設計模式下,我們可以輕鬆處理來自不同模型的流式響應,確保資料傳輸的連貫性和一致性。
動態的流式介面轉換
在處理生成式 AI API 的流式資料時,通常我們會接收到以下幾類資料:
-
event
,如 ping 等事件。 -
data
:JSON 資料。 -
結束標誌,如
[DONE]
、tts_message_end
或message_end
。
在實際應用中,透過 JSONPath 或類似的工具,流式 BFF 可以根據不同 API 的返回內容動態調整資料處理方式,確保每個流式響應能夠快速轉換為前端可用的格式。
我們需要考慮在流式 BFF 中引入這種動態介面轉換機制,以應對不同智慧體的流式響應。
總結
生成式 AI 原生架構要求我們重新審視傳統後端模式。流式 BFF 為智慧體介面不一致、與傳統 API 不同步等問題提供了有效的解決方案。透過統一介面、 流式處理、即時過濾及 API 協同,流式 BFF 能提升系統的可靠性和響應速度。