SpringAI MCP實(shí)戰(zhàn):從理論到代碼、從設(shè)計(jì)Agent再到構(gòu)建MCP服務(wù),嘎嘎強(qiáng)!
MCP(模型上下文協(xié)議)技術(shù)已經(jīng)火熱了一段時(shí)間,最近冰河也正在利用MCP來優(yōu)化業(yè)務(wù)場景。借此機(jī)會(huì),深入研究了SpringAI框架中的MCP實(shí)現(xiàn)。
與以往的技術(shù)學(xué)習(xí)路徑不同,AI領(lǐng)域的學(xué)習(xí)更加注重理論指導(dǎo)實(shí)踐——因?yàn)锳I技術(shù)本身仍在快速演進(jìn),堅(jiān)實(shí)的理論基礎(chǔ)比單純的代碼實(shí)踐更為重要。
一、構(gòu)建智能業(yè)務(wù)Agent的設(shè)計(jì)思路
假設(shè)我們需要實(shí)現(xiàn)"智能套餐推薦"功能:用戶通過自然對話表達(dá)需求,系統(tǒng)自動(dòng)分析并推薦合適的套餐,生成支付鏈接供用戶完成購買。傳統(tǒng)方案需要用戶經(jīng)過多個(gè)步驟——選擇類型、瀏覽套餐、填寫信息等,涉及復(fù)雜的頁面跳轉(zhuǎn)和交互。
構(gòu)建這樣一個(gè)智能Agent,需要從三個(gè)核心層面進(jìn)行設(shè)計(jì):
1.1 大腦:大模型的能力定制
以大模型作為決策核心,負(fù)責(zé)理解用戶意圖并提取關(guān)鍵信息。例如,當(dāng)用戶表達(dá)"我最近經(jīng)常加班到很晚,總覺得肩頸酸痛,眼睛干澀"時(shí),模型需要識別出"職場人群"、"久坐辦公"、"肩頸護(hù)理"、"眼部疲勞"等關(guān)鍵特征。
又例如,當(dāng)用戶表達(dá)"工作三年感覺遇到了技術(shù)瓶頸,想要系統(tǒng)學(xué)習(xí)但不知道從哪開始"時(shí),模型需要識別出"職業(yè)發(fā)展階段"、"技能提升需求"、"學(xué)習(xí)規(guī)劃"、"技術(shù)成長"等關(guān)鍵特征。
通用大模型雖然強(qiáng)大,但往往無法直接滿足特定業(yè)務(wù)需求。我們需要通過兩個(gè)關(guān)鍵手段進(jìn)行定制:
角色定義提示詞:通過精心設(shè)計(jì)的提示詞,讓模型理解其作為"套餐推薦專家"的角色定位,掌握業(yè)務(wù)領(lǐng)域的專業(yè)知識和對話風(fēng)格。
動(dòng)態(tài)知識注入:模型本身不具備企業(yè)內(nèi)部數(shù)據(jù),需要通過RAG(檢索增強(qiáng)生成)技術(shù)為其提供業(yè)務(wù)知識支撐。但這里有個(gè)關(guān)鍵考量——套餐數(shù)據(jù)頻繁變化,傳統(tǒng)的靜態(tài)知識庫更新機(jī)制顯然不夠高效。
1.2 手腳:MCP接口的能力擴(kuò)展
既然套餐數(shù)據(jù)實(shí)時(shí)變化,為什么不直接讓AI訪問現(xiàn)有的業(yè)務(wù)接口呢?這就是MCP的價(jià)值所在。我們可以將現(xiàn)有的RESTful接口封裝為MCP接口,讓AI能夠直接查詢實(shí)時(shí)數(shù)據(jù)、獲取相關(guān)信息、創(chuàng)建支付訂單等。
1.3 架構(gòu)總結(jié)與平臺選擇
綜合來看,構(gòu)建智能Agent需要完成三個(gè)核心任務(wù):
(1)選擇合適的大模型,并通過提示詞工程進(jìn)行角色定制
(2)構(gòu)建知識庫體系,為模型提供業(yè)務(wù)背景知識
(3)開發(fā)MCP接口,讓AI能夠操作業(yè)務(wù)系統(tǒng)
但在實(shí)施過程中,我們面臨幾個(gè)技術(shù)挑戰(zhàn):
- 對話狀態(tài)管理:大模型本身是無狀態(tài)的,需要額外維護(hù)對話歷史
- 向量數(shù)據(jù)庫:知識庫需要使用專門的向量數(shù)據(jù)庫技術(shù)
- 模型對接:不同模型的API對接存在兼容性問題
考慮到這些復(fù)雜性,手動(dòng)構(gòu)建整個(gè)Agent體系效率較低。我們選擇基于Dify等專業(yè)平臺進(jìn)行開發(fā),這樣能夠?qū)W⒂跇I(yè)務(wù)邏輯的實(shí)現(xiàn),而非基礎(chǔ)設(shè)施的搭建。
二、實(shí)戰(zhàn):構(gòu)建天氣查詢MCP服務(wù)
為了驗(yàn)證技術(shù)可行性,我們先從一個(gè)相對簡單的天氣查詢MCP服務(wù)開始驗(yàn)證。這里,使用SpringAI框架將其封裝為MCP服務(wù)。
PS:基于開放的天氣API:https://api.open-meteo.com/v1
2.1 環(huán)境配置
項(xiàng)目依賴(pom.xml):
要求JDK 17及以上版本
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.4.5</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-mcp-server-spring-boot-autoconfigure</artifactId>
<version>1.0.0-M6</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-mcp</artifactId>
<version>1.0.0-M6</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.modelcontextprotocol.sdk</groupId>
<artifactId>mcp-spring-webflux</artifactId>
<version>0.8.0</version>
<scope>compile</scope>
</dependency>
</dependencies>2.2 應(yīng)用配置
server:
port:8082
spring:
ai:
mcp:
server:
name:my-weather-server
sse-endpoint:/sse
sse-message-endpoint:/mcp/messages
type:ASYNC
version:0.0.12.3 核心服務(wù)實(shí)現(xiàn)
(1)應(yīng)用啟動(dòng)類:
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
public ToolCallbackProvider weatherTools(OpenMeteoService openMeteoService) {
return MethodToolCallbackProvider.builder()
.toolObjects(openMeteoService)
.build();
}
}(2)天氣服務(wù)實(shí)現(xiàn):
通過@Tool注解將業(yè)務(wù)方法暴露為MCP工具。
@Service
publicclass OpenMeteoService {
privatefinal WebClient webClient;
public OpenMeteoService(WebClient.Builder webClientBuilder) {
this.webClient = webClientBuilder
.baseUrl("https://api.open-meteo.com/v1")
.build();
}
@Tool(description = "根據(jù)經(jīng)緯度獲取天氣預(yù)報(bào)")
public String getWeatherForecastByLocation(
@ToolParam(description = "緯度,例如:39.9042") String latitude,
@ToolParam(description = "經(jīng)度,例如:116.4074") String longitude) {
try {
String response = webClient.get()
.uri(uriBuilder -> uriBuilder
.path("/forecast")
.queryParam("latitude", latitude)
.queryParam("longitude", longitude)
.queryParam("current", "temperature_2m,wind_speed_10m")
.queryParam("timezone", "auto")
.build())
.retrieve()
.bodyToMono(String.class)
.block();
return"當(dāng)前位置(緯度:" + latitude + ",經(jīng)度:" + longitude + ")的天氣信息:\n" + response;
} catch (Exception e) {
return"獲取天氣信息失?。? + e.getMessage();
}
}
@Tool(description = "根據(jù)經(jīng)緯度獲取空氣質(zhì)量信息")
public String getAirQuality(
@ToolParam(description = "緯度,例如:39.9042") String latitude,
@ToolParam(description = "經(jīng)度,例如:116.4074") String longitude) {
// 模擬數(shù)據(jù),實(shí)際應(yīng)用中應(yīng)調(diào)用真實(shí)API
return"當(dāng)前位置(緯度:" + latitude + ",經(jīng)度:" + longitude + ")的空氣質(zhì)量:\n" +
"- PM2.5: 15 μg/m3 (優(yōu))\n" +
"- PM10: 28 μg/m3 (良)\n" +
"- 空氣質(zhì)量指數(shù)(AQI): 42 (優(yōu))\n" +
"- 主要污染物: 無";
}
}三、MCP服務(wù)調(diào)試與實(shí)踐
完成MCP服務(wù)開發(fā)后,我們需要進(jìn)行充分的測試驗(yàn)證。類比REST API的開發(fā)流程,MCP服務(wù)同樣需要專業(yè)的調(diào)試工具和方法。
3.1 使用Inspector進(jìn)行基礎(chǔ)測試
MCP官方提供的Inspector工具相當(dāng)于傳統(tǒng)開發(fā)中的Postman,能夠直接調(diào)用MCP接口進(jìn)行測試。
安裝和使用步驟:
npx @modelcontextprotocol/inspector node build/index.js通過Inspector界面,我們可以:
- 查看所有可用的MCP工具列表
- 直接調(diào)用工具方法并查看返回結(jié)果
- 驗(yàn)證參數(shù)傳遞和數(shù)據(jù)格式的正確性

3.2 集成到AI開發(fā)環(huán)境
真正的價(jià)值在于將MCP服務(wù)集成到AI應(yīng)用中使用。目前主流的AI開發(fā)工具都支持MCP協(xié)議,包括:
VsCode Cline擴(kuò)展:在對話窗口中直接使用自然語言調(diào)用MCP工具
圖片
Dify等AI應(yīng)用平臺:在可視化界面中配置和使用MCP工具。
自定義SpringAI客戶端:根據(jù)業(yè)務(wù)需求開發(fā)專用的客戶端應(yīng)用。
需要注意的是,不同工具對MCP的支持程度有所差異。例如,當(dāng)前版本的Cursor由于客戶端限制,暫時(shí)無法直接調(diào)用我們開發(fā)的MCP服務(wù)。
四、總結(jié)
通過實(shí)戰(zhàn)構(gòu)建查詢天氣的MCP服務(wù),我們驗(yàn)證了SpringAI MCP技術(shù)的可行性。從技術(shù)架構(gòu)上看,MCP為AI應(yīng)用提供了一種標(biāo)準(zhǔn)化的能力擴(kuò)展機(jī)制,讓大模型能夠安全、可控地訪問外部系統(tǒng)和服務(wù)。
對于企業(yè)級應(yīng)用而言,MCP的價(jià)值不僅在于技術(shù)實(shí)現(xiàn),更重要的是它提供了一種AI與傳統(tǒng)業(yè)務(wù)系統(tǒng)融合的新范式。隨著MCP生態(tài)的不斷完善,我們有理由相信,這種"對話即服務(wù)"的模式將在企業(yè)數(shù)字化升級中發(fā)揮越來越重要的作用。還是那句話:AI早就無限可能!




































