SpringAIAlibaba学习使用 ---MCP使用

0 阅读5分钟

SpringAIAlibaba学习使用 ---MCP

本文为学习记录文档,学习参考于三更草堂springAI视频

依旧田甜猫姐镇楼!!!!

MCP概述

为什么需要MCP?

在MCP出现之前,AI应用开发面临一个显著的效率瓶颈,常被称为“M×N”问题。这意味着,如果有M个不同的大模型(如GPT、Claude、文心一言等)需要与N种外部工具或数据源(如数据库、API、文件系统)进行交互,开发者就需要为每一种组合(M乘以N)编写特定的、通常不可复用的适配代码 这种点对点的集成方式导致了:

  • 高昂的重复开发成本:每个新工具或新模型的引入都意味着大量的重复集成工作。
  • 生态系统碎片化: 不同厂商的模型有不同的函数调用接口和规范,使得为一个模型开发的工具很难被其他模型直接使用。
  • 复杂的维护负担: 当某个工具或模型的API发生变更时,所有与之相关的集成点都需要同步更新,维护成本非常高

什么是MCP?

MCP(Model Context Protocol,模型上下文协议)是Anthropic公司推出的开放协议,旨在标准化大语言模型与外部工具、数据源的交互方式。 官方文档:modelcontextprotocol.io/docs/learn/…

MCP相关概念

定义解释
MCP host【MCP主机】使用mcp协议调用工具的应用程序。 例如claude code,我们自己写的spring ai应用等。它负责协调和管理一个或多个 MCP 客户端的 AI 应用程序。MCP 主机通过为每个 MCP 服务器创建一个 MCP 客户端来实现连接
MCP client【MCP客户端】与 MCP 服务器保持连接并从 MCP 服务器获取上下文,供 MCP 主机使用的组件
MCP server 【MCP服务端】给AI模型提供工具的服务

入门案例

目标:创建一个MCP Server去提供一个工具【这里是获取日期的工具】

1、工具代码


    @Tool(description = "通过时区id获取当前时间")
    public String getTimeByZoneId(@ToolParam(description = "时区id,比如 Asia/ShangHai") String zoneId) {

        ZoneId zone = ZoneId.of(zoneId);
        ZonedDateTime now = ZonedDateTime.now(zone);
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        return now.format(dateTimeFormatter);
    }

然后使用MCP Client去获取这个MCP Server上的工具来提供给模型

2、创建MCP服务端

创建新工程后添加依赖

        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-starter-mcp-server-webflux</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

创建启动类

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class McpServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(McpServerApplication.class, args);
    }
}


定义工具类


import org.springframework.ai.tool.annotation.Tool;
import org.springframework.ai.tool.annotation.ToolParam;
import org.springframework.stereotype.Component;

import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
@Component
public class TimeTools {

    @Tool(description = "通过时区id获取当前时间")
    public String getTimeByZoneId(@ToolParam(description = "时区id,比如 Asia/ShangHai") String zoneId) {

        ZoneId zone = ZoneId.of(zoneId);
        ZonedDateTime now = ZonedDateTime.now(zone);
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        return now.format(dateTimeFormatter);
    }

}

配置工具对外提供

import com.sangeng.tool.TimeTools;
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.ai.tool.method.MethodToolCallbackProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class McpConfig {

    @Bean
    public ToolCallbackProvider weatherTools(TimeTools tools) {
        return MethodToolCallbackProvider.builder()
                .toolObjects(tools)
                .build();
    }

}

创建MCP客服端

配置文件

        <!--mcp客户端依赖-->
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-starter-mcp-client-webflux</artifactId>
        </dependency>

          <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

           <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-starter-model-zhipuai</artifactId>
        </dependency>

增加mcp服务端配置

# 服务器配置
server:
  port: 8888 
spring:
  # 应用基本信息配置
  application:
    name: mcp-client # 应用名称
  data:
    redis:
      host: 127.0.0.1
      port: 6379
  # Spring AI 配置
  ai:
    # 智谱AI大模型配置
    zhipuai:
      api-key: ************************* # 智谱API密钥(从环境变量ZHIPU_KEY获取)
      chat:
        options:
          model: glm-4.6 # 使用的聊天模型名称(GLM-4.6)
      embedding:
        options:
          model: embedding-3 # 使用的嵌入模型名称(embedding-3)
          dimensions: 256 # 嵌入向量的维度(256维)
    # 向量存储配置
    vectorstore:
      redis:
        initialize-schema: true # 启动时自动创建Redis向量索引结构(首次部署需开启)
        prefix: rag_prefix # Redis键名前缀,用于区分不同应用的向量数据
        index: rag_index # Redis向量索引名称
    mcp:
      client:
        sse:
          connections:
            server1:
              url: http://localhost:8080   # mcp服务的url地址
            fetcher-mcp:
              url: http://localhost:3000
  http:
    client:
      connect-timeout: 100000

配置工具信息到chatClient

    private final VectorStore vectorStore;
    private final ChatClient chatClient;

    public CoffeeController(VectorStore vectorStore, ChatClient.Builder chatClientBuilder, ToolCallbackProvider toolCallbackProvider) {

        this.vectorStore = vectorStore;
        VectorStoreDocumentRetriever vectorStoreDocumentRetriever = VectorStoreDocumentRetriever.builder()
                .vectorStore(vectorStore)
                .topK(2)
                .similarityThreshold(0.5)
                .build();

        RetrievalAugmentationAdvisor retrievalAugmentationAdvisor = RetrievalAugmentationAdvisor.builder()
                .documentRetriever(vectorStoreDocumentRetriever)
                .build();
        this.chatClient = chatClientBuilder
                .defaultAdvisors(retrievalAugmentationAdvisor)
                .defaultToolCallbacks(toolCallbackProvider.getToolCallbacks())
                .build();

    }

网页信息爬取MCP

MCP地址: www.mcpworld.com/zh/detail/f…

docker部署mcp【任何部署方式都可以,docker比较简单】

docker-compose.yml:

version: '3.8'
services:
  fetcher-mcp:
    image: ghcr.io/jae-jae/fetcher-mcp:latest
    container_name: fetcher-mcp
    restart: unless-stopped
    ports:
      - '3000:3000'
    environment:
      - NODE_ENV=production
    volumes:
      - /tmp:/tmp
    healthcheck:
      test:
        - CMD
        - wget
        - '--spider'
        - '-q'
        - http://localhost:3000
      interval: 30s
      timeout: 10s
      retries: 3

使用 docker-compose up -d 启动

添加MCP服务端相关配置

# 服务器配置
server:
  port: 8888 
spring:
  # 应用基本信息配置
  application:
    name: mcp-client # 应用名称
  data:
    redis:
      host: 127.0.0.1
      port: 6379
  # Spring AI 配置
  ai:
    # 智谱AI大模型配置
    zhipuai:
      api-key: ************************* # 智谱API密钥(从环境变量ZHIPU_KEY获取)
      chat:
        options:
          model: glm-4.6 # 使用的聊天模型名称(GLM-4.6)
      embedding:
        options:
          model: embedding-3 # 使用的嵌入模型名称(embedding-3)
          dimensions: 256 # 嵌入向量的维度(256维)
    # 向量存储配置
    vectorstore:
      redis:
        initialize-schema: true # 启动时自动创建Redis向量索引结构(首次部署需开启)
        prefix: rag_prefix # Redis键名前缀,用于区分不同应用的向量数据
        index: rag_index # Redis向量索引名称
    mcp:
      client:
        sse:
          connections:
            server1:
              url: http://localhost:8080   # mcp服务的url地址
            fetcher-mcp:
              url: http://localhost:3000   # mcp2服务的url地址
  http:
    client:
      connect-timeout: 100000

controller编写

    @GetMapping("/fetcher")
    public String fetcher(@RequestParam("question") String question) {
        return chatClient.prompt()
                .system("你是一个网页爬取专家,你可以运用工具爬取指定网页的内容并且进行总结")
                                .user(question)
                                .call().content();
    }

在调用时候可以通过断点看是否有用到配置的mcp