【從一台 Server 到分散式架構】第 24 篇:AI 系統架構——串流回應、推理服務與擴展策略

AI 學習助理上線一週後,用戶的反饋出奇地好。

但 DevOps 阿強拉著小明看了一張圖:

「現在每次用戶問問題,後端要等 LLM 生成完整回答——平均要 8 秒——才回傳給前端。8 秒的空白,用戶以為沒反應,很多人點了兩三次。而且 API 費用這週爆了,因為很多重複請求。」

另一個工程師說:「而且如果我們之後想要自架 LLM 模型,GPU 要怎麼管理、要怎麼擴展,我完全不知道從哪裡想起。」

小明面對著兩個問題:

  1. 用戶體驗:怎麼讓 AI 的回答感覺「即時」而不是「等一個結果」?
  2. 系統架構:推理服務要怎麼設計才能擴展?

問題一:串流回應——讓 AI 像在「打字」

LLM 生成文字的方式是逐 Token 生成:先生成第一個字(Token),再生成第二個字,一直到整段回應完成。

如果你等所有 Token 都生成完才回傳,用戶看到的是「空等 8 秒,突然出現一大段文字」。

如果你讓每個 Token 生成出來就立刻傳給前端,用戶看到的是「文字一個接一個冒出來,像有人在打字」。

這就是 Streaming(串流回應)

技術實作:Server-Sent Events 或 WebSocket

兩種常見做法:

Server-Sent Events(SSE)

  • HTTP 的單向串流:伺服器持續把 Token 推給前端
  • 實作簡單,HTTP/1.1 就支援
  • 適合「伺服器主動推送、不需要雙向」的場景——AI 串流完全符合

WebSocket

  • 雙向連線(第 17 篇介紹過)
  • 如果你的 AI 助理需要「用戶可以隨時打斷或追問」,WebSocket 更適合

小明他們先用 SSE——簡單,夠用:

用戶送出問題
→ 後端呼叫 LLM API(帶 stream=true)
→ LLM 每生成幾個 Token 就回傳一小段
→ 後端把這些小段透過 SSE 推給前端
→ 前端即時顯示,像打字效果

問題二:推理很耗資源,怎麼擴展?

用外部 API 的情況

如果用 OpenAI、Anthropic 等 API,推理資源是對方的——你只需要考慮:

  • Rate Limit(速率限制):每分鐘能打幾次、多少 Token
  • 並行請求數:同時有多少個請求在等 LLM 回應
  • 成本控制:每個 Token 都要錢,要避免重複請求

這種情況下,你的架構要處理的主要是前面的佇列和請求管理

自架 LLM 的情況

如果要自己跑模型(開源模型如 Llama、Mistral),需要 GPU 機器,而 GPU 資源貴且難擴展:

比較CPU(一般後端)GPU(LLM 推理)
擴展方式加機器成本低加 GPU 機器貴很多
啟動速度秒級模型載入可能需要幾分鐘
利用率容易充分利用閒置時浪費成本很高

自架 LLM 的擴展策略:

  1. 模型服務與應用服務分開部署:LLM 推理服務跑在 GPU 機器,普通 API 跑在 CPU 機器,分別擴展
  2. 請求佇列:GPU 機器數量有限,把 LLM 請求放進佇列,按順序處理,避免 GPU 被瞬間打爆
  3. 批次推理(Batching):多個請求同時進模型,比一個一個跑更有效率地利用 GPU

請求佇列:讓 AI 服務「削峰填谷」

這個概念和第 08 篇的 Message Queue 一樣,只是應用在 AI 服務上:

用戶瞬間湧入提問,請求進佇列排隊;GPU 機器按自己的速度消化佇列,不會被打爆。


快取也能幫 AI 省錢

很多問題其實是重複的(「什麼是遞迴?」「如何宣告變數?」),每次都呼叫 LLM 太浪費。

語意快取(Semantic Cache)

把「問題的向量」和「LLM 的回答」存起來。下次有相似的問題,先去快取找——如果找到語意很相似的舊問題(向量距離夠近),就直接回傳快取的答案,不用再打 LLM。

這比傳統 key-value 快取更聰明:「Python loop 怎麼寫」和「Python 如何做迴圈」是不同的字串,但語意相近,語意快取能把它們視為同一個問題。


完整的 AI 助理架構


小結與預告

這篇小明學到的重點是:

  1. 串流回應(Streaming):逐 Token 推送給前端,讓用戶感受「AI 在打字」,而不是等一個慢速結果——用 SSE 實作最簡單。
  2. 推理資源貴且難擴展:GPU 機器不能隨意加,要做好請求佇列削峰;模型服務要和普通 API 服務分開,各自獨立擴展。
  3. 語意快取省成本:相似問題不用重複打 LLM,用向量距離判斷「夠像就用舊答案」。

到這裡,小明他們的系統功能齊全了:課程平台、微服務、即時通知、AI 助理……

是時候退一步,把這整個系統拍一張全景圖。

下一篇,我們來做一件重要的事:把從第 01 篇走到現在的每個元件,畫成一張完整的架構圖,看看這個系統到底長成了什麼樣子。

相關推薦

2026-04-07
【從一台 Server 到分散式架構】第 31 篇:從面試題反推架構——用本系列思維拆解系統設計考題
「設計一個 URL 短網址服務」「設計一個訊息系統」——系統設計面試問的不是背答案,而是思考方式。這篇整理了一套可以重複使用的面試框架,並用兩道例題示範如何從需求出發,一步步推導出架構、說清楚取捨。
2026-04-06
【從一台 Server 到分散式架構】第 30 篇:限流、排隊與降級實戰——開賣與直播場景
平常流量是 1000 QPS,但「開賣」的那一刻,瞬間湧入 50 萬個請求——系統要怎麼活下來?這篇用課程平台的限量課程開賣和直播開播場景,把第 13 篇學到的限流、降級、熔斷,落地到一個真實的高流量設計,走過每個防護層是怎麼工作的。
2026-04-05
【從一台 Server 到分散式架構】第 29 篇:用同樣的思維看 ChatGPT——AI 聊天系統架構
ChatGPT 看起來像一個聊天視窗,背後卻有幾個特殊的設計挑戰:回應是串流的、推理非常耗資源、每輪對話要記住上下文、系統要支援幾千萬用戶同時使用。這篇用熟悉的架構思維,拆解 AI 聊天系統的關鍵設計。
2026-04-04
【從一台 Server 到分散式架構】第 28 篇:用同樣的思維看 Twitter——社群動態與時序設計
Twitter 的核心功能看起來很簡單:發推文、看動態、按讚留言。但「動態牆」背後藏著一個棘手的設計問題:你追蹤 200 個人,每個人都可能隨時發文——你打開 App 時,那條時序動態要怎麼快速組出來?這篇來看社群動態系統的兩種策略:推(Fan-out on Write)與拉(Fan-out on Read)。