ExplainThis 全端開發雙週報 #85 從 MCP 核心協定轉為無狀態,談有狀態與無狀態的設計如何取捨
從 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 在社群發文,引起對於獨立學習的討論 (連結)



