ExplainThis 全端開發雙週報 #85 從 MCP 核心協定轉為無狀態,談有狀態與無狀態的設計如何取捨
嗨~歡迎閱讀第 84 期 ExplainThis 全端開發雙週報!
在進到正式的內容前想與大家分享,在這週 ExplainThis 的 E+ 會員方案 (連結),上架了《寫出好維護的程式碼 (下) — 日常開發中的實用方法》。對比起先前在《寫出好維護的程式碼 (上) — 經典的程式設計觀點》以經典理論為主,這門新課程專注在每天寫程式時都可以運用上的方法。
想提升自己程式碼品質,讓自己能寫出更好維護的程式碼的讀者,歡迎加入 E+ 會員 (連結) 觀看~
備註:如果所任職的公司有教育補助,透過補助購買,E+ 會開立有統編的發票。不用花自己的錢,也能每週透過深度主題文與社群交流,拓展技術視野、加速職涯成長。上個月有超過一半的新會員是透過教育訓練補助購買 E+ 。
從 MCP 核心協定轉為無狀態,談有狀態與無狀態的設計如何取捨
不論在前端或後端,在做軟體設計與開發時,不免會遇到要有狀態 (stateful) 還是無狀態 (stateless) 這個問題。在面試中也經常會有面試官問「XX 在設計上是有狀態的還是無狀態的? 為什麼?」,這邊的 XX 可以帶入許多不同的技術名詞,例如驗證 (auth) 上可以選有狀態的 session-based 或無狀態的 token-based,在通訊 (communication) 上可以選有狀態的 WebSockets 或無狀態的 HTTP。
而近兩年在社群中非常熱門的 MCP,也從最開始的有狀態協定,在這一週正式改為無狀態的核心協定 (連結)。要了解這個改變,就需要了解有狀態與無狀態設計該如何取捨,而這也是在面試中經常會出現的問題。
要能夠回答好這個面試問題,或者在工作上做技術決策時要能選到合適的,就需要理解這兩種選擇會遇到的取捨。在這篇文章,我們會透過實際的案例,來討論兩者的區別與取捨。
從驗證的角度看有狀態與無狀態
在 90 年代的網頁開發,session-based 是主流的驗證方式。session-based 的驗證方式會需要透過伺服器端來管理 session,這種作法的問題在於,今天假如網站流量變大,想要多加幾台伺服器做水平擴展,就會有 session 要如何處理的難題。
其中一種解法,是確保同一個使用者的請求都進到同個伺服器 (俗稱 sticky session 的作法);但是這種作法會讓特定使用者的狀態依賴特定伺服器。如果該伺服器掛掉,而 session 又沒有同步到共享儲存,使用者的請求雖然可以被導到別台伺服器,卻可能因為缺少原本的 session 狀態而失敗。這是一種潛在的單點故障問題 (single point of failure)。
舉例來說,在電商結帳流程,如果把商品加入購物車時,session 狀態保存在 A 伺服器,但結帳時 A 伺服器掛掉,所以請求被負載均衡器導向備援用的 B 伺服器,這時因為 B 伺服器沒有相關 session,可能導致購物車清空或直接報錯 (備註:這裡是以簡化版的購物車暫存來說明狀態綁在單台機器上的風險;實務上的電商系統通常會再把購物車狀態放到共享儲存、資料庫或快取中,避免只依賴單台伺服器記憶體)。
又或者在線上表單的填寫過程,如果要維持填寫紀錄。在填完部分資料後,狀態暫存在 A 伺服器的 Session 裡。但這時如果 A 伺服器掛掉,使用者回來繼續填寫後續步驟,送出時請求進到別台伺服器,前面填寫的資料會就此消失,讓整個流程必須從頭來過,使用體驗會很不理想。
假如我們從狀態的角度來看,上面這種 session-based 的設計,會被稱為有狀態 (stateful) 的設計。但為什麼這會被稱為有狀態?讓我們進一步來談相關的定義。
有狀態與無狀態的差別是什麼?
在軟體設計中,所謂的有狀態,是指某一個元件 (例如上述例子中的伺服器) 保有了與之互動所需的資訊 (例如上述提到的購物車中的資訊、填表暫存的資訊)。而無狀態則意味著,該元件本身不帶任何資訊,當需要用該元件時,就要帶上完整的資訊來跟該元件互動。
在日常生活中,也有類似的比喻。在早年醫療資訊還不發達時,去診所看醫生會類似於有狀態,多數人會去家裡附近的診所,而診所醫生的紙本病歷有過去所有的紀錄,甚至有些人如果比較頻繁看病,醫生會特別熟悉,下次去看病時甚至不用拿出病歷也能問診。這種狀況下,醫生的看診速度會很快;但如果今天換一家診所,新診所的醫生沒有過去的病歷,問診上可能會比較困難。
到了近代,許多醫療系統開始往電子病歷與跨院所資料交換的方向發展,這在概念上更接近把狀態從單一診所的紙本病歷,移到某種可被其他醫療單位查詢的共享系統。因此,這種做法也更像是無狀態的設計,不管在哪看診,病歷都是上傳到雲端,而不是放在診所的紙本病歷。醫生都能馬上調出過去的病歷紀錄。這樣一來,即使換診所、換醫生,新的醫生還是能根據過去的病歷來快速了解病人。
回到驗證的案例中,另一種 token-based 的驗證方式,是使用自包含的 token (例如 JWT)。這種設計可以讓驗證流程更接近無狀態,因為伺服器不一定要保存每個使用者的 session,只要驗證 token 的簽章與內容即可。換句話說每一個請求都要自帶足夠的資訊,讓任何一台伺服器都能獨立處理。
具體的作法來說,伺服器產生一個編碼後的 token 給客戶端,裡面已經包含驗證所需的資訊。之後每次請求都把 token 帶上,伺服器不需要保存狀態,只要驗證 token 就夠了。當狀態不是綁定在某台伺服器上,這樣即使 A 伺服器掛掉也不擔心,換成 B 伺服器一樣可行。
MCP 該是有狀態還是無狀態?
在有了上述的理解後,接著讓我們來討論一個新一點的問題「MCP 的設計應該是有狀態,還是無狀態?」。MCP 是個相對新的協定,在最開始提出時是預設有狀態的,但是提出後技術社群一直有不同的聲音;透過思考這個仍在演化中的問題,對於磨練技術設計來說會更有臨場感。
在 MCP 剛被推出的時候,是選擇有狀態的設計。這個設計很大一部分是基於當時 MCP 的使用情境,由於最開始 MCP 主要是透過 stdio 讓客戶端跟在本地運行的伺服器溝通。在這個脈絡下,選擇有狀態的設計能夠有效減少不必要的溝通成本,每次客戶端與伺服器端握完手後,之後客戶端來的請求都可以不再需要這個流程。
但隨著業界對 MCP 的採用越來越高,開始有聲音提出要預設無狀態的 MCP。其中 SEP-1442 (連結) 是由包含 Google Cloud 等多家公司的代表共同提出的議題。在 SEP-1442 中,他們提到有狀態的 MCP 讓遠端多機台的部署難度變高,這點原因跟最開頭提到的驗證問題類似;現行有狀態的設計,讓遠端多機台 MCP 的部署變得困難,例如沒辦法用簡單的負載均衡方式來處理請求。除此之外,從遠端部署的角度來看,如果今天某台部署 MCP 的伺服器掛掉,狀態就會有丟失的風險。
上述的兩種設計,是基於不同的出發點。最初 MCP 之所以選有狀態的設計,出發的角度是從 AI 代理本身的角度出發。假如今天 AI 代理在本地運行、呼叫來自本地運行的不同工具,這時用有狀態的設計非常合理。進一步說,MCP 當時在設計上借鏡 LSP 這種有狀態的協定,某種程度上預設了 AI 代理需要長連線的狀態 (例如持續運行數分鐘、瀏覽多個檔案、呼叫多個工具),這時透過維持狀態減少重新連線,成本會更低一點。
然而,在 MCP 爆紅後,隨著 MCP 被用於遠端部署與第三方工具整合,藉此來對接到更廣泛的不同工具。對於遠端部署來說,無法擴展的問題是更大的痛點,但這個問題不在原先 MCP 設計的預想中 (本來的設計沒有考量要讓 MCP 伺服器部署在數十個不同的 pods)。
社群希望 MCP 改成預設無狀態設計,並不能說最開始的有狀態設計不好,而是實際的使用場景超乎了原本的預料,本地工具協定走向遠端平台化後,原本的最佳解開始承受新的部署壓力。設計沒有永遠的絕對正確,只是在某個場景下更合適,從這個例子來看,根據真實需求持續演化設計,會是在軟體設計中非常重要的。
而到了這週,在 2026-07-28 的最新版 MCP,已經正式把核心協定改為無狀態的,在官方的公告中有以下的影片,說明了關鍵的區別。在修改後的版本,可以透過負載平衡器,讓客戶端的請求,被導去任何的實例當中,對於可擴展性的幫助很大。
閱讀更多
如果你覺得 ExplainThis 的分享有幫助,想閱讀更深入的內容,歡迎加入 E+ 會員 (連結)。除了有會員專屬的深度文與影片,探討前後端開發、AI 工程、職涯發展,同時有 Discord 社群一同交流與成長。
本期推薦
- 近期社群討論度高的 Octane 開源專案保留 React 的 Hooks、Suspense 與元件等寫法,再透過編譯器直接更新 DOM (連結),如果想用 React 的模式寫,但又不想被 React 的部分規則限制,推薦可以一試
- 《The startup’s Postgres survival guide》一文中,把團隊兩年來維運 PostgreSQL 遇過的問題,整理成一份面向新創工程師的實戰指南 (連結) 從資料表設計、索引、交易與連線管理,一路談到查詢計畫、批次寫入、自動清理和大型資料遷移
- Beyond Coding 訪問前 Google、AWS 軟體架構師 Gregor Hohpe,討論真正優秀的軟體架構師,和只會提供答案或堆疊術語的人有什麼不同 (連結) ,正在往資深工程師或架構師發展的人可以從中找到不少具體建議
- 最近重讀 Jeff Atwood 的經典文章《The Best Code is No Code At All》中,提醒工程師每增加一行程式碼,也同時增加除錯、閱讀、維護與支援成本 (連結) ;雖然寫於 2007 年,放到今天的軟體開發仍然很有參考價值。
- 這兩天社群中有個令人感到意外,同時也值得深思的事。前 OpenAI 安全系統的副總,同時也是 Thinking Machines Lab 的共同創辦人 Lilian Weng,在公司剛發布第一個開放權重模型 Inkling 後沒多久,宣布因為身體健康因素,離開自己共同創辦的公司。我們讀了特別有感,寫了一篇貼文談值得打造的未來,不該先耗盡打造的人 (連結)
- 今年數學界最高榮譽之一的菲爾茲獎得主公佈後,社群有極大的討論。其中王虹是史上第三位,也是首位華人女性得主。有一些報導用連跳兩級 16 歲進入北大、麻省理工 (MIT) 博士等標籤來描述王虹,彷彿這種天才般的經歷下,拿獎是再自然不過的事。但讀了比較深度的專訪後,才知道原來王虹的經歷不是如此線性、順遂,當中也有許多值得我們反思的點 (連結)。
- 最近 Kimi 推出 K3 模型後,由於在部分評測中表現超越 Claude Fable,在社群引起廣大的討論。Kimi 的創辦人兼執行長 Zhilin Yang,是在美國的卡內基美隆大學 (CMU) 拿到博士學位,他當年的導師 Russ Salakhutdinov 在社群發文,引起對於獨立學習的討論 (連結)