![]()
作者 | Matteo Rossi
譯者 | 平川
1 簡介:為什么 MCP Java SDK 很重要
大語言模型不再僅僅用于實驗性的聊天機器人或個人生產力工具。在企業中,這些模型正在改變團隊與系統互動以及做出實際決策的方式。從本質上講,它們已經成為真正的架構組件。
盡管如此,當前的集成還比較脆弱。許多團隊使用供應商特有的機制將集成邏輯嵌入到提示中,或者直接向模型暴露 API。雖然這些方法在原型設計階段很有用,但它們難以擴展,并且治理能力也非常有限。
這種情況與 SOA 的早期階段頗為相似,當時由于缺乏統一的標準,導致系統結構脆弱,難以開發和集成。MCP 現在處于同樣的穩定化階段:它在基于 LLM 的架構中引入了一個協議層,其中包含了結構、邊界和互操作模型。
為了應對這些挑戰,模型上下文協議(MCP)引入一種標準化且與模型無關的方法,用于展示上下文工具和數據。MCP 在模型與外部系統之間定義了一個協議層的契約,避免了將集成語義硬編碼到提示或特定于 SDK 的調用中。這種共享且標準化的約定使功能變得明確、可發現且可管理。
在這個背景下,Java MCP SDK 的出現尤為重要。JVM 生態系統支撐著企業的大部分工作負載,這里的架構規范并非是一種審美上的偏好。基于 Java 的系統必須具備可觀測性、可測試性、高可靠性以及長期可維護性。如果在這些環境中引入 LLM,而沒有與之相匹配的同等水平的規范,就會導致不一致的情況,變得難以管理和解決。
Java 中基于 SDK 和 MCP 的集成方案,使架構師能夠將大語言模型的采用與企業現有的架構實踐相融合,并將服務邊界、契約和控制平面等概念應用于與大語言模型的交互中。
本文將從這一角度探討 MCP 及其 Java SDK。本文的目的并非講解如何編寫 MCP 代碼,而是探討 MCP 如何重新定義大語言模型的集成標準,它解決了哪些問題,以及在設計旨在突破原型階段、實現規模化應用的系統時要做哪些權衡取舍。
2 MCP 入門:基于協議的 LLM 集成視角
為了從架構的角度更好地理解 MCP,我們需要將關注點從單個集成轉向交互模型。MCP 既不是代理框架,也不是運行時環境;它是一種協議,通過結構化的契約來定義模型如何與外部功能進行交互。
MCP 架構基于一組明確區分的角色。主機為模型提供執行環境;客戶端負責處理模型的請求,而服務器則將工具和資源作為明確定義的功能對外提供。這種間接模型是刻意設計的:模型絕不會直接調用 API 或基礎設施,它們只調用通過協議聲明的內容。其結果是形成了一道治理邊界,該邊界可以控制訪問,而不會干擾模型的推理過程。
![]()
圖 1: MCP 分層架構圖(圖片來源)
MCP 的主要特點之一在于其功能發現能力。MCP 并非預先配置好模型可用的工具,而是允許客戶端在運行時向服務器發起查詢,從而發現功能及其關聯的模式。這一能力使系統更具適應性,并減少在提示詞或代理邏輯中對功能進行硬編碼的需求。從架構角度來看,該機制實現了模型與系統之間的松耦合。
MCP 還區分了工具和資源。工具代表模型可以請求的操作,而資源則提供結構化的上下文數據。這種區分便于清晰地區分不同的數據訪問模式。無論是從安全性還是治理角度來看,只讀上下文數據與會改變狀態的操作在管理方式上都大不相同。
![]()
圖 2:MCP 服務器組成
作為一種規范,MCP 還重新定義了快速開發流程。其上下文不能只是在運行時臨時拼湊而成的固定字符串,而必須是通過明確的接口提供的經過精心策劃的結構化信息集合。
最終,MCP 代表了從以模型為中心的集成向基于協議的設計轉變。LLM 交互被視為分布式系統交互,需遵循與任何其他類型的集成相同的架構規范。
3 MCP Java SDK 內部的設計與架構選擇
Java MCP SDK 將 Anthropic 公司 MCP 協議的抽象原則轉化為適用于基于 JVM 的系統的具體實現。Anthropic 的設計既保持了協議的準確性,又遵循了 Java 企業應用的最佳實踐。該協議側重于定義抽象角色、消息格式和能力協商,而 SDK 則通過以 Java 為中心的設計選擇實現了這些概念。這些設計選擇包括強類型模型、為客戶端和服務器提供明確的接口,以及基于模式交互所采用的構建器結構。
總體上看,該 SDK 采用多層架構設計。其中,傳輸機制(如用于本地集成的 STDIO 或用于分布式通信的 HTTP)、協議語義以及會話管理之間有著明確的劃分。這種劃分使得團隊能夠根據不同的交互模式調整 MCP 協議,而不會影響底層邏輯。
該 SDK 支持同步和異步兩種交互模式。在內部,它傾向于采用非阻塞通信和響應式流程,這種模式非常適合 MCP I/O 交互。同時,該 SDK 還提供了更高層次的抽象,可以在傳統的命令式代碼中使用。在企業生態系統中,這兩種選擇使得純響應式技術棧能夠與傳統或混合編程范式共存。
該 SDK 的另一個關鍵方面是與框架集成。在 Java 企業環境中,首要問題就是:它是否能與 Spring 進行集成?在基于 Spring 的應用程序中,MCP 服務器可以與現有的服務一起集成,從而受益于 Spring 的獨有特性,例如依賴注入、配置管理以及已有的針對其他應用程序的管理實踐。這種設計使得 MCP 能夠逐步采用,一步一步引入 MCP 端點,而不需要從頭重寫應用程序或重新組織整個架構。
只需很少的代碼,就可以將 MCP 工具提供程序集成到 Spring 框架中:
}在這個例子中,MonitoringTools 是一個標準的 Spring 托管 Bean。該 Bean 暴露的方法只需向 MethodToolCallbackProvider 注冊,即可成為 MCP 工具。通過這種機制,MCP 功能得以與其他服務的行為保持一致,并成為同一依賴關系圖的一部分。Spring 對其生命周期、配置和注入的處理方式,與應用程序中所有其他 Bean 完全一致。
Java SDK 的最大優勢在于將協議概念明確化。工具的定義需要有明確的輸入和輸出,而資源則必須進行恰當的描述和結構化。這種對明確性的要求迫使團隊將 MCP 服務器視為有界上下文,而非通用的集成層。
從架構的角度來看,這些特性使 MCP 服務器與防腐層、API 網關等成熟的模式相契合。SDK 提供了構建模塊,而這些邊界所帶來的架構規范則帶來了長遠價值。
此外,通過將功能暴露視為一項需要開發和設計的活動,該 SDK 有效防止了功能的無序擴張——這是大語言模型集成中非常常見的陷阱。因此,并非將整個 API 對外開放,而是根據功能和業務需求,提供經過精心設計的功能。
從這個意義上說,Java MCP SDK 遠不止是一個協議。它迫使開發團隊重新思考大語言模型的集成,將其視為系統架構中的核心組件,而非僅僅是需要接入的外部工具。
4 使用 Java 設計 MCP 服務器:暴露功能,而非 API
在使用 MCP 時,一個關鍵決策在于如何將 MCP 服務器集成到整體架構中。乍看之下,將 MCP 服務器視為一個簡單的適配器,負責將模型請求轉發給現有的 API,似乎既直觀又易于實現。然而,這種做法會削弱該協議的許多優勢。
在企業系統中,API 通常是為大語言模型設計的。在理想情況下,它們會暴露底層的基本操作,并假設特定的調用序列。在其他情況下,它們則反映了歷史上的限制或組織層面的問題(參見康威定律)。即使通過 MCP,將此類 API 直接暴露給模型,也可能會導致產生 MCP 本意要解決的緊耦合問題。
一種更有效的方法是將 MCP 服務器視為功能提供者。采用這種方法,MCP 服務器將定義封裝了特定領域業務功能的高級工具,而不是直接暴露原始端點。讓我們以票務系統為例。MCP 服務器無需暴露完整的 API,而是可以設計為僅暴露諸如 retrieveIncidentSummary、searchRelatedIncidents 和 proposeMitigationSteps 之類的工具。這些工具暴露了模型被授權執行的操作,而非底層系統在技術上能夠執行的操作。
這種設計在 MCP 服務器與防腐層之間建立了非常緊密的對應關系。服務器負責將模型發出的請求轉換為與核心系統之間安全且經過驗證的交互。在任何調用到達核心系統之前,系統都會對輸入進行驗證、執行授權檢查,并確保數據被正確地建模。除非明確允許,否則模型絕不應接觸到內部標識符、實現細節、過于具體的錯誤信息,或可能產生副作用的操作。
因此,可以使用 Java 來實現 MCP 服務器,既可以將其作為獨立的服務來運行,也可以將其集成到現有的 Spring 應用程序中。這種實現方式使我們可以復用領域服務、存儲庫和安全組件,同時為模型提供一個有限制而且是有意暴露的接口。
如上所述,另一個需要考慮的重要區別在于只讀功能與狀態修改功能之間的區別。許多用例都是基于這樣一個事實而開發的,即模型能夠探索數據并提出操作建議,但不能直接執行這些操作。MCP 通過鼓勵開發細粒度的詳細工具來明確這種區別。例如,MCP 服務器可以提供一個工具,用于評估操作的影響或準備請求,而將操作的執行留給一個獨立的由人工驅動的流程。
要實現所有這些功能,必須采用良好的操作規范。MCP 服務器為可觀測性和審計提供了天然的切入點。該工具的每一次調用都可以進行記錄、跟蹤和分析,而且不依賴模型的內部推理過程。
5 MCP 客戶端與編排:當模型遇到架構
MCP 服務器決定提供哪些功能,而 MCP 客戶端則決定如何使用這些功能。在早期的大語言模型(LLM)集成中,編排邏輯直接嵌入到提示詞或代理框架中,這使得維護工作變得非常復雜,運行時的關聯關系也很難理解。
MCP 客戶端充當模型與一個或多個 MCP 服務器之間的中介。它負責識別可用的工具、管理會話以及協調對工具的調用。它是該架構的關鍵組件,而不是一個被動的通信層。
在 Java 生態系統中,我們可以將 MCP 客戶端集成到能夠協調復雜工作流的服務中。例如一個運維助手,它利用 MCP 客戶端查詢多個服務器(監控、工單和文檔),并將這些服務器的響應整合到適合該模型的上下文中。這種協調邏輯現在位于代碼而非提示詞中,使得版本控制和測試都變得更加容易。
該模型的一大關鍵優勢在于能夠明確控制交互流程,包括調用序列、超時處理、部分錯誤處理以及備用方案。客戶端可以處理所有這些情況,并自主決定何時中斷模型的運行,將控制權交由人工操作員管理。在提示詞中實現這些功能非常復雜,在應用程序代碼中則要簡單得多。
MCP 客戶端在上下文管理中發揮著核心作用。客戶端不需要手動拼湊冗長的提示詞,就能夠精確地決定在任何給定的時刻向模型暴露哪些資源。這種選擇能最大限度地精簡上下文,并大幅降低敏感或無關信息泄露的風險。
從架構角度來看,MCP 客戶端不過是分布式系統中的協調器。它們管理對話,并將對話視為對服務的調用流。這種方法將大語言模型集成的復雜性分解為三個關鍵問題:狀態管理、冪等性和錯誤處理。對于基于 Java 的分布式系統開發者而言,他們對于這些問題都有著非常明確且立場鮮明的看法。
6 MCP 與原生工具調用:權衡與設計考量
使用 MCP 是有代價的。與大語言模型提供商提供的原生工具調用方式相比,MCP 增加了額外的層級和抽象。對于小型或實驗性項目而言,其額外帶來的成本很可能超過好處。
原生調用工具更為簡單直觀:模型調用一個函數,接收響應,然后繼續執行。這種簡單性帶來了一個副作用:強耦合。工具定義通常嵌入在提示詞或 SDK 配置中,這使得版本控制和獨立模型管理變得十分困難。
另一方面,MCP 通過協議實現標準化,將定義及與工具的交互關系外部化。雖然這種標準化增加了復雜性,但也提升了架構的清晰度。工具因此成為具有明確模式、屬性和生命周期的一等實體,不用修改或重新配置模型,即可對其進行管理、控制和開發。
另一個權衡在于可觀測性。調用原生工具往往會模糊模型推理與工具交互之間的界限:我該如何追蹤故障和意外行為?MCP 的客戶端 - 服務器模型明確界定了邊界和職責,便于記錄和追蹤指標。
在性能方面,MCP 會引入網絡跳數和協議開銷,在延遲敏感的場景中必須對此進行評估。實際上,這是在可預測性、可觀測性和可測試性與純粹性能之間的一種權衡。具體取決于你的解決方案中哪些要求更為重要。
MCP 的真正優勢在于其架構方法。它使我們能夠將基于大語言模型的系統與其他分布式系統進行整合,并采用一致且經過驗證的運維、開發和測試實踐來統一管理。如果在我們所處的環境中,長期維護、安全性以及職責的合理劃分(包括組織層面的職責)比快速實驗更為重要,那么 MCP 就是應該采用的模式。
7 安全性、治理與可觀測性:實現 MCP 的大規模可運維性
一旦實驗階段結束,安全性和治理問題便會立即成為首要的關注點。MCP 并不能消除這些問題,而是提供了架構層面的切入點,而這通常無法應用于基于提示詞或原生模型的集成方案中。
通過在協議層限制訪問權限,MCP 本質上貫徹了最小權限原則。這與那些讓模型直接與整個 API 集合或數據庫交互的方法截然不同——后者通常使用通用憑證且權限定義模糊。
該模型可輕松地集成到現有的安全框架中:可以在 MCP 服務器的邊界上實施身份驗證和授權控制,采用 OAuth、mTLS 等機制或企業身份驗證提供商。安全職責不會下放給模型。大語言模型不會判斷某項操作是否被允許,而只能請求 MCP 服務器明確暴露的功能。
治理原則同樣適用于工具的生命周期。隨著時間的推移,新的用例會推動新工具的誕生,因此必須應用與 API 管理中類似的治理策略:版本控制、棄用策略、文檔編寫以及屬性暴露。
最后,上下文管理對安全性和合規性也具有重要的影響。上下文被視為受管理的資源,而非無結構的提示,這使得 MCP 能夠應用數據最小化策略。隨著時間的推移,根據具體用例,敏感信息可以被屏蔽、審查或有選擇地限制。在受監管的環境中,這種控制有助于降低意外泄露數據的風險,并簡化數據保護法規的合規流程。
8 案例研究:基于 MCP 構建的企業運營助手
讓我們以企業運維助手的設計為例,試著更深入地理解這些概念的運作原理。該系統的目標是根據相關信號提出解決方案,從而幫助服務經理和應用程序維護團隊處理事件,同時又不賦予大語言模型對生產系統的直接控制權。
![]()
圖 3:企業運營助手
問題空間
在絕大多數企業中,用于支持生產的運維知識分散在監控平臺、工單系統、運維手冊和內部文檔中。一旦發生故障,運維團隊必須手動整合各項指標、日志和歷史數據。時間就是關鍵。大語言模型是綜合和聚合信息并提供洞察的理想工具,但以這種方式將其集成到運維工作流中可能存在很高的風險。
直接方法是指將監控 API 和工單系統直接暴露給模型,并利用它對原生工具的調用。這種方案會導致系統耦合度高、結構脆弱且存在潛在風險:模型能夠訪問所有數據,數據驗證機制非常有限,最重要的是,幾乎沒有任何監督機制。在這種情況下,很難在事后控制操作,也難以應用一致的安全約束。
基于 MCP 的架構
在基于 MCP 的設計中,我們引入了明確的架構邊界;我們針對每個運營領域提供專用的 MCP 服務器:
MCP 監控服務器提供了一個只讀工具,例如 getSystemMetrics。
MCP 知識服務器將運行手冊和歷史事件報告作為結構化資源提供,并配有 getRecentIncidents 工具。
MCP 工單服務器允許創建事件報告草稿,但在未經人工批準的情況下,不允許發送和打開工單。
每個 MCP 服務器都有其自身的運行邏輯,并負責驗證對領域內特定功能的訪問權限。這些工具的設計基于運行環境,而非原始 API 功能。
集成到運維助手中的 MCP 客戶端負責協調這些服務器之間的交互,管理上下文構建,并根據正在分析的事件決定應公開哪些資源。該模型接收選好的運維環境視圖,從而使大語言模型能夠有效地進行推理,而且不需要過多的權限或信息。
交互流程
當運維人員向 MCP 客戶端詢問諸如“為什么服務 X 最近幾天一直出現問題?”之類的問題時,在后臺,客戶端會:
向 MCP 監控服務器查詢系統的最新指標。
從 MCP 知識服務器檢索相關的運行手冊和歷史事件。
創建一個針對性的上下文,并將其提供給模型。
允許模型提出假設及相應的解決方案建議。
如有需要,生成一份事件報告草稿以供審核和評估。
該模型從不直接與生產系統交互,而且只提供解決問題的思路和建議,而具體的事件解決工作由運維人員負責。
實際代碼
讓我們來分析一下代碼層面實現了哪些內容。為了實現 MCP 客戶端,我們使用了 spring-ai-starter-mcp-client,并結合 OpenAI 以及 spring-ai-starter-model-openai 來實現 ChatClient 部分。
客戶端提供了一個調用 analyze() 方法的 API。該方法隨后會調用 getSystemMetrics 工具來獲取系統指標,調用 getRecentIncidents 工具來獲取近期事件,然后構建上下文并傳遞給 ChatGPT 用于檢索相關信息。
}提示詞構造如下:
}在 MCP 服務器端,我們僅通過 spring-ai-starter-mcp-server 和 spring-ai-starter-mcp-server-webmvc 暴露了上述兩個工具。簡單起見,工具響應是模擬的;在實際應用場景中,MCP 服務器將集成監控工具、知識工具以及最終的工單工具 API 。
}通過調用客戶端 API,我們得到了以下結果(為便于閱讀,只截取了部分結果):
Additional Metrics to be Collected: 1. Database operation times: This would help identify any problematic queries or operations…..你可以利用這些內容提交工單,其中包含對當前情況的初步分析、可能的原因以及解決方案。
架構案例小結
本案例研究重點介紹了 MCP 架構的一些基本特征。首先,它展示了 MCP 服務器如何作為反腐層發揮作用,保護核心系統,并在所有情況下提供預先定義好且受控的交互。其次,它展示了 MCP 客戶端如何實現顯式編排和上下文管理,將復雜性從提示構建轉移到源代碼層面。最后,它闡明了治理和可觀測性是架構中天然存在的集成需求。
照此構建的系統既能充分發揮大語言模型的優勢(例如推理、綜合和解釋能力),又能滿足業務環境(如運營)所需的安全性和可靠性要求。
9 經驗教訓:何時適合使用 MCP Java SDK,何時不適合
與任何架構設計選擇一樣,其價值主要取決于具體情境。MCP 并非適用于所有 LLM 集成的通用解決方案。在某些情況下,當更簡單、更直接的方法已經足夠時,就不應該使用 MCP 替代,尤其是在原型開發階段。為了做出明智的決策,重要的是要了解 MCP Java SDK 何時能帶來價值,何時只是引入了不必要的管理、維護復雜性。
其中最重要的一個經驗是,在必須兼顧大語言模型交互以及業務約束的環境中,MCP 能發揮最大的價值。臨時拼湊的工具很難像 MCP 那樣,建立起具有明確邊界和可維護性的強治理機制。顯式契約、功能發現、職責分離以及最小化暴露面等概念,有助于 MCP 與企業環境中的設計實踐保持一致。
另一個關鍵點在于,MCP 在用于揭示意圖而非基礎設施時效果最佳。如果僅僅將 MCP 服務器視為現有 API 的簡單封裝,就無法實現這些優勢。必須投入精力設計具有實際意義且與業務目標相契合的功能,從而實現更清晰的邊界、更安全的交互,以及更加可預測和可觀測的行為。這是從多年 API 設計經驗中總結出的教訓:高質量的抽象比協議的選擇更重要。
MCP 還倡導并推行一種更健康、更合理的職責分配模式,即將所有任務分配給源代碼而非提示詞。授權、驗證和協調工作由專門為此設計的系統負責,從而使大語言模型能夠專注于推理和綜合:這不僅減輕了認知負荷,還提升了系統的韌性。
然而,這一切都是有成本的。MCP 會引入額外的組件、通信開銷、操作復雜性以及更多的故障點。對于小型團隊或短期實驗而言,這些成本很可能超過其帶來的收益。在這種情況下,只要了解其局限性,原生工具或直接集成可能就是完全合適的解決方案。
其中一項限制在于組織是否已經準備好使用這一新范式。MCP 要求具備一定的架構成熟度,團隊必須已經意識到定義契約、管理版本的必要性,并且要在共享基礎設施上進行操作。如果忽視了這些職責,MCP 便會淪為又一層集成,而非一種規范。
歸根結底,MCP 必須被視為一項長期架構投資。隨著系統的發展以及團隊和解決方案的可擴展性提升,其回報也會隨之增長。當這些條件都具備時,MCP 便能提供一個能夠支撐可持續增長的基礎,而非僅僅是短期內的權宜之計。
10 結論:MCP 作為大語言模型感知系統的控制平面
將大語言模型集成到企業系統中,標志著軟件架構的構思與設計方式正在發生根本性的變革。大語言模型將概率推理引入了傳統上由確定性邏輯主導的環境。要管理這一變革,需要一套結構嚴謹的架構規范;僅靠個別供應商提供的智能提示或原生擴展是遠遠不夠的。
MCP 正是朝著這一方向邁出的重要一步。MCP 定義了一種標準化方式來提供工具和上下文,將大語言模型(LLM)的集成重新定義為協議層面的挑戰,而非實現細節。這一轉變使得架構師們能夠將他們熟悉的原則(例如職責分離、最小權限原則、可觀測性,以及明確且有文檔記錄的契約)應用于一類全新的系統。
MCP Java SDK 的發布對整個 Java 生態系統和企業界而言都具有根本性的重要意義。它使企業在進行大語言模型集成時,不會犧牲支撐其關鍵系統架構的嚴謹性。MCP 不再將大語言模型視為游離于規則和既定邊界之外的外部特殊組件,而是將其納入企業架構,使其成為一個常規且重要的組成部分。
然而,MCP 的核心并非在于提供新功能,而在于賦予現有功能一種更本質、更負責任的形式。它提供了一個控制平面,用于隨著時間的推移觀察、管理和開發模型與系統之間的交互。隨著基于大語言模型(LLM)的功能日益融入核心業務流程,這種治理機制變得至關重要。
需要明確的是,MCP 既無法消除大語言模型固有的不確定性,也無法保證更高的準確性。它所提供的,是在明確界定且預先設定的架構邊界內管理不確定性的一種方法。對于那些希望超越實驗階段、邁向可持續 AI 應用的組織而言,這一區別至關重要。
隨著大語言模型的持續發展,MCP 等協議將在未來的架構轉型中發揮與 HTTP 和 REST 范式在以往轉型中同樣重要的作用。其目標并非規定具體的實現細節,而是確立共同的預期,從而在系統之間實現可持續的互操作。
這項工作僅僅是個開始:大語言模型正在持續重塑系統設計,而 MCP 是一個讓基于 Java 的企業架構可以將其自身生態系統與 AI 相融合的協議。文中代碼可通過以下鏈接獲取( mcp-client 和 mcp-server )。
https://www.infoq.com/articles/mcp-java-architectural-strategy-llm-integrations/
聲明:本文由 InfoQ 翻譯,未經許可禁止轉載。
特別聲明:以上內容(如有圖片或視頻亦包括在內)為自媒體平臺“網易號”用戶上傳并發布,本平臺僅提供信息存儲服務。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.