11-MCP(模型上下文协议Model​ Context Protocol)

一、简介

MCP 就像 AI 领域的 JDBC:以前大模型要用外部工具时,每个项目都要自己定义调用方式,重复又混乱;MCP 统一了协议,模型能像调用标准接口一样去用数据库、API 或服务,开发者少写胶水代码,工具也能跨项目复用。

https://modelcontextprotocol.io/docs/getting-started/intro

在这里插入图片描述

https://docs.langchain4j.dev/tutorials/mcp/

在这里插入图片描述

二、调用上万个通用的MCP

https://mcp.so/zh

在这里插入图片描述

阿里云百炼也有类似的,但是数量较少

在这里插入图片描述

三、MCP架构知识

MCP遵循客户端-服务器架构包含以下几个核心部分

在这里插入图片描述

  • MCP 主机(MCP Hosts):发起请求的 AI 应用程序,比如聊天机器人、AI 驱动的 IDE 等。
  • MCP 客户端(MCP Clients):在主机程序内部,与 MCP 服务器保持 1:1 的连接。
  • MCP 服务器(MCP Servers):为 MCP 客户端提供上下文、工具和提示信息。
  • 本地资源(Local Resources):本地计算机中可供 MCP 服务器安全访问的资源,如文件、数据库。
  • 远程资源(Remote Resources):MCP 服务器可以连接到的远程资源,如通过 API 提供的数据

在MCP通信协议中,一般有两种模式

在这里插入图片描述

STDIO(标准输入/输出)

支持标准输入和输出流进行通信,主要用于本地集成、命令行工具等场景

SSE (Server-Sent Events)

支持使用 HTTP POST​,请求进行服务器到客户端流式处理,以实现客户端到服务器的通信

两者对比

在这里插入图片描述

四、代码实战

前置环境

首先下载nodejs环境

在这里插入图片描述

注册百度地图账号+申请API-key

https://lbsyun.baidu.com/apiconsole/key

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

nodejs配置编码

在这里插入图片描述

开发步骤

https://docs.langchain4j.dev/tutorials/mcp/#creating-an-mcp-tool-provider

建module

在这里插入图片描述

pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.liming</groupId>
        <artifactId>langchain4j-v1</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <artifactId>langchain4j-14chat-mcp</artifactId>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--langchain4j-open-ai 基础-->
        <dependency>
            <groupId>dev.langchain4j</groupId>
            <artifactId>langchain4j-open-ai</artifactId>
        </dependency>
        <!--langchain4j 高阶-->
        <dependency>
            <groupId>dev.langchain4j</groupId>
            <artifactId>langchain4j</artifactId>
        </dependency>
        <!-- langchain4j-reactor实现流式输出 -->
        <dependency>
            <groupId>dev.langchain4j</groupId>
            <artifactId>langchain4j-reactor</artifactId>
        </dependency>
        <!--DashScope (Qwen)接入阿里云百炼平台
            https://docs.langchain4j.dev/integrations/language-models/dashscope
        -->
        <dependency>
            <groupId>dev.langchain4j</groupId>
            <artifactId>langchain4j-community-dashscope-spring-boot-starter</artifactId>
        </dependency>
        <!-- MCP Client 依赖 -->
        <dependency>
            <groupId>dev.langchain4j</groupId>
            <artifactId>langchain4j-mcp</artifactId>
        </dependency>
        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!--hutool-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.22</version>
        </dependency>
        <!--test-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

yml

server:
  port: 9014
  servlet:
    encoding:
      charset: UTF-8
      enabled: true
      force: true

spring:
  application:
    name: langchain4j-14chat-mcp

langchain4j:
  community:
    dashscope:
      streaming-chat-model:
        api-key: ${aliQwen-api}
        model-name: qwen-plus
      chat-model:
        api-key: ${aliQwen-api}
        model-name: qwen-plus

主启动

package com.liming;

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

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

业务类

新建接口McpService
package com.liming.service;

import reactor.core.publisher.Flux;

public interface McpService {
    Flux<String> chat(String question);
}
controller
package com.liming.controller;

import com.liming.service.McpService;
import dev.langchain4j.mcp.McpToolProvider;
import dev.langchain4j.mcp.client.DefaultMcpClient;
import dev.langchain4j.mcp.client.McpClient;
import dev.langchain4j.mcp.client.transport.McpTransport;
import dev.langchain4j.mcp.client.transport.stdio.StdioMcpTransport;
import dev.langchain4j.model.chat.StreamingChatModel;
import dev.langchain4j.service.AiServices;
import dev.langchain4j.service.tool.ToolProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;

import java.util.List;
import java.util.Map;

/**
 * @Description: 知识出处
 * <p>
 * 第1步,如何进行mcp编码
 * https://docs.langchain4j.dev/tutorials/mcp#creating-an-mcp-tool-provider
 * <p>
 * 第2步,如何使用baidu map mcp,它提供了哪些功能对外服务
 * https://mcp.so/zh/server/baidu-map/baidu-maps?tab=tools
 * <p>
 * http://localhost:9014/mcp/chat?question=查询61.149.121.66归属地
 * http://localhost:9014/mcp/chat?question=查询北京天气
 * http://localhost:9014/mcp/chat?question=查询昌平到天安门路线规划
 */
@RestController
public class McpCallServerController {
    @Autowired
    private StreamingChatModel streamingChatModel;

    @GetMapping("/mcp/chat")
    public Flux<String> chat(@RequestParam("question") String question) {
        /**1.构建McpTransport协议
         *
         * 1.1 cmd:启动 Windows 命令行解释器。
         * 1.2 /c:告诉 cmd 执行完后面的命令后关闭自身。
         * 1.3 npx:npx = npm execute package,Node.js 的一个工具,用于执行 npm 包中的可执行文件。
         * 1.4 -y 或 --yes:自动确认操作(类似于默认接受所有提示)。
         * 1.5 @baidumap/mcp-server-baidu-map:要通过 npx 执行的 npm 包名
         * 1.6 BAIDU_MAP_API_KEY 是访问百度地图开放平台API的AK
         */
        McpTransport transport = new StdioMcpTransport.Builder()
                .command(List.of("cmd", "/c", "npx", "-y", "@baidumap/mcp-server-baidu-map"))
                .environment(Map.of("BAIDU_MAP_API_KEY", System.getenv("BAIDU_MAP_API_KEY")))
                .build();

        // 2.构建McpClient客户端
        McpClient mcpClient = new DefaultMcpClient.Builder()
                .transport(transport)
                .build();

        // 3.创建工具集和原生的FunctionCalling类似
        ToolProvider toolProvider = McpToolProvider.builder()
                .mcpClients(mcpClient)
                .build();

        // 4.通过AiServivces给我们自定义接口McpService构建实现类并将工具集和大模型赋值给AiService
        McpService mcpService = AiServices.builder(McpService.class)
                .streamingChatModel(streamingChatModel)
                .toolProvider(toolProvider)
                .build();

        // 5.调用我们定义的HighApi接口,通过大模型对百度mcpserver调用
        return mcpService.chat(question);
    }
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

五、复习

  • Function Calling,为了让大模型使用Util工具
  • RAG,为了让大模型获取足够的上下文
  • MCP,为了让大模型之间的调用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小钟佳运

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值