用一个实际例子快速理解MCP应用的工作步骤

已经有很多的文章介绍MCP server,MCP Client工作原理,这里不做太多介绍。但是很多介绍都只是侧重介绍概念,实际的工作原理理解起来对初学者还是不太友好。本文以一个智能旅游咨询系统为例,详细说明在利用 Model Context Protocol(MCP)应用时,从用户输入到给出最终结果,上下文信息的传递过程以及每一步的封装填充情况。能够让读者快速了解,所谓的model context protocol中上下文的含义,同一般的function call的差异。
在这里插入图片描述

工作过程与原理介绍

场景设定

用户希望了解北京故宫的开放时间和门票价格,系统利用 MCP 协调不同的工具(如开放时间查询工具、门票价格查询工具)来获取相关信息并给出回答。

整个系统的消息交互图如下:

用户 客户端 LLM MCP服务器 GET /tools HTTP/1.1 工具列表 缓存工具列表 输入"北京故宫的开放时间和门票价格是多少?" 封装请求 问题和工具列表 分析并生成工具调用指令 调用工具列表 确认操作 确认 查询开放时间 执行工具 结果 收集工具结果 确认操作 确认 结果 执行工具 返回结果 收集工具结果 发送结果 生成自然语言回答 返回结果 结果展示 用户 客户端 LLM MCP服务器

完整流程概述

  1. 客户端与MCP服务器建立连接,获取可用工具列表
  2. 用户输入问题,客户端封装请求
  3. 客户端调用LLM进行意图分析,生成工具调用指令
  4. 客户端向MCP服务器发起工具调用(需用户确认)
  5. MCP服务器执行工具并返回结果
  6. 客户端整合结果,调用LLM生成最终回答
  7. 客户端向用户展示最终结果

详细步骤说明

1. 客户端初始化 & 获取工具列表

客户端首次连接MCP服务器时,通过/tools端点获取注册的工具列表:

请求:

GET /tools HTTP/1.1
Host: mcp-server.example.com
Accept: application/json

响应:

{"tools": [{"name": "opening_hours_query","description": "景区开放时间查询工具","parameters": {"location": "string"}},{"name": "ticket_price_query","description": "景区门票价格查询工具","parameters": {"location": "string"}}]
}

说明:客户端需要缓存工具列表,用于后续LLM分析。


2. 用户输入 & 请求封装

用户在客户端界面输入问题:

“北京故宫的开放时间和门票价格是多少?”

客户端封装请求,包含用户问题、用户标识和时间戳:

{"user_id": "12345","timestamp": "2025-04-09 12:00:00","question": "北京故宫的开放时间和门票价格是多少?"
}

3. LLM分析 & 生成工具调用指令

客户端将用户问题+工具描述发送给LLM:

{"question": "北京故宫的开放时间和门票价格是多少?","available_tools": [{"name": "opening_hours_query","description": "景区开放时间查询工具"},{"name": "ticket_price_query","description": "景区门票价格查询工具"}]
}

LLM返回结构化工具调用指令:

{"request_id": "abcdef123456","llm_response": [{ "tool_call_id": "call_1","tool_name": "opening_hours_query","parameters": {"location": "北京故宫"}},{ "tool_call_id": "call_2","tool_name": "ticket_price_query","parameters": {"location": "北京故宫"}}]
}

4. 客户端发起工具调用(含用户确认)

客户端按照MCP协议(JSON-RPC)格式封装请求,并先向用户展示确认对话框:

用户确认界面:

即将执行以下操作:
1. 查询[北京故宫]的开放时间
2. 查询[北京故宫]的门票价格是否继续? [确认] [取消]

用户确认后,发送正式请求:

{"jsonrpc": "2.0","method": "tool/execute","params": {"tool": "opening_hours_query","arguments": {"location": "北京故宫"}},"id": "call_1"
}

5. MCP服务器执行工具

MCP服务器执行工具并返回结果:

{"jsonrpc": "2.0","result": {"status": "success","data": "旺季8:30-17:00,淡季8:30-16:30"},"id": "call_1"
}

6. 客户端整合结果 & 生成最终回答

客户端收集所有工具结果后,再次调用LLM:

{"request_id": "abcdef123456","question": "北京故宫的开放时间和门票价格是多少?","tool_results": [{"tool_call_id": "call_1","tool_name": "opening_hours_query","result": "旺季8:30-17:00,淡季8:30-16:30"},{"tool_call_id": "call_2","tool_name": "ticket_price_query","result": "旺季60元,淡季40元"}]
}

LLM生成自然语言回答:

{"final_answer": "北京故宫开放时间:旺季8:30-17:00,淡季8:30-16:30;门票价格:旺季60元,淡季40元。"
}

7. 客户端展示最终结果

将LLM生成的回答呈现给用户:

“北京故宫开放时间:旺季8:30-17:00,淡季8:30-16:30;门票价格:旺季60元,淡季40元。”


这个流程确保了系统的安全性、可扩展性和协议合规性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/77309.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【LeetCode 题解】数据库:1321.餐馆营业额变化增长

一、问题描述 本题给定了一个名为 Customer 的表,记录了餐馆顾客的交易数据,包括顾客 ID、姓名、访问日期和消费金额。作为餐馆老板,我们的任务是分析营业额的变化增长情况,具体来说,就是计算以 7 天(某日…

【Python】读取xlsb或xlsx的单一或连续单元格工具类

代码主要来自Kimi.ai,有修改。 优先使用工作表序号索引工作表,序号从1开始。 运行需要先安装openpyxl和pyxlsb两个第三方库。 import openpyxl from openpyxl.utils import range_boundaries from pyxlsb import open_workbook as open_xlsbclass Exc…

【蓝桥杯】动态规划:背包问题

这篇文章主要记录动态规划方面的学习。 动态规划的核心思想: 把大问题分解成小问题,记住小问题的解,避免重复计算。 动态规划(DP)的三大特点: ①最优子结构:大问题的最优解可以由小问题的最优解推导出来 ②重叠子问题:在求解过程中会反复遇到相同的小问题 ③无后效…

华为数字芯片机考2025合集1已校正

单选 1.以下低功耗措施中,哪种不是降低电路翻转率的方法? A.在不进行算术运算的时候,使这些模块的输入保持不变,不让新的操作数进来 B.采用Gray 码或One‐hot 码作为状态机编码 C.减少电路中的glitch D.重新安排“if‐else”表达…

React 列表渲染

开发环境:Reacttsantd 你可能经常需要通过 JavaScript 的数组方法 来操作数组中的数据,从而将一个数据集渲染成多个相似的组件。在这篇文章中,你将学会如何在 React 中使用 filter() 筛选需要渲染的组件和使用 map() 把数组转换成组件数组。 …

力扣刷题DAY11(动态规划-线性DP)

一、最长上升子序列 300. 最长递增子序列 &#xff08;一&#xff09;初版代码 class Solution { public:int lengthOfLIS(vector<int>& nums) {int n nums.size();vector<int> f(n 1, 1); //初始化为1&#xff0c;因为每个数至少可以作为一个单独的序列in…

DFS--

数字的全排列 #include <bits/stdc.h> using namespace std;//最大的排列数目 const int N10; int n; //存储排列的路径 int path[N]; //标记数字是否已经被使用 bool st[N];void dfs(int u){//到达递归边界&#xff0c;输出一个排列if(un){//输出循环for(int i0; i<…

栈与队列及其基础应用

一.栈 1.栈的定义 栈是一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底。栈中的数据元素遵守后进先出LIFO&#xff08;Last In First Out&#xff09;的原则。其结构可以参考羽毛…

openEuler-22.03-LTS-SP3 编译安装 Greenplum-db 6.20.0

openEuler-22.03-LTS-SP3 编译安装 Greenplum-db 6.20.0 1、配置 yum 华为源2、安装依赖3、源码安装 openssl 1.0.1u3.1、openssl 1.1.1 降级到 openssl 1.0.1 4、源码安装 python 2.75、使用 pip3 安装 Python 相关依赖6、编译安装 Greenplum-db 6.20.06.1、修改配置6.2、基于…

机器学习02——概要

一、简介 机器学习是一门在没有明确编程的情况下让计算机学习的科学。 监督学习是有目标的&#xff0c;输入数据对应明确的输出&#xff1b;无监督学习则是“探索”型的&#xff0c;模型的目标是从数据中发现潜在的模式或结构&#xff0c;而不需要预先知道标签。 二、机器学…

swift-08-属性、汇编分析inout本质

一、Swift中跟实例相关的属性可以分为2大类 1.1 存储属性&#xff08; Stored Property&#xff09; 类似于成员变量这个概念 存储在实例的内存中 结构体、类可以定义存储属性 枚举不可以定义存储属性&#xff08;因为枚举只存储关联值和case&#xff09; 1.2 计算属性&am…

【HarmonyOS Next之旅】DevEco Studio使用指南(十二)

目录 1 -> Code Linter代码检查 2 -> 配置代码检查规则 3 -> 查看/处理代码检查结果 1 -> Code Linter代码检查 Code Linter针对ArkTS/TS代码进行最佳实践/编程规范方面的检查。 可根据扫描结果中告警提示手工修复代码缺陷&#xff0c;或者执行一键式自动修复…

前端vue项目打包成桌面端exe应用

主要 使用 Electron将 vue项目打包为 exe 1.首先下载Electron git clone https://github.com/electron/electron-quick-start cd electron-quick-start npm install安装完依赖之后 npm start运行成功 注意&#xff1a;如果你的项目使用了VueRouter&#xff0c;那么切记&…

基于springcloud的“微服务架构的巡游出租管理平台”的设计与实现(源码+数据库+文档+PPT)

基于springcloud的“微服务架构的巡游出租管理平台”的设计与实现&#xff08;源码数据库文档PPT) 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;springcloud 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 系统总体结构图 E-R实体关系图…

新一代达梦官方管理工具SQLark:可视化建表操作指南

在数据库管理工作中&#xff0c;新建表是一项基础且频繁的操作。SQLark 的可视化建表功能为我们提供了一种高效、便捷且丝滑流畅的建表新体验。一起来了解下吧。 SQLark 官方下载链接&#xff1a;www.sqlark.com 新建表作为常见的功能&#xff0c;相比其他管理工具&#xff0c;…

Scala相关知识学习总结6

1、集合计算高级函数说明 - 过滤&#xff1a;遍历集合&#xff0c;提取满足特定条件的元素组成新集合。 - 转化/映射&#xff08;map&#xff09;&#xff1a;将集合里的每个元素应用到指定函数进行转换。 - 扁平化&#xff1a;文档未详细阐述其具体含义和操作。 - 扁平化映射&…

pandas.DataFrame.dtypes--查看和验证 DataFrame 列的数据类型!

查看每列的数据类型&#xff0c;方便分析是否需要数据类型转换 property DataFrame.dtypes[source] Return the dtypes in the DataFrame. This returns a Series with the data type of each column. The result’s index is the original DataFrame’s columns. Columns with…

计算机中的单位

在计算机科学中&#xff0c;单位用于衡量数据存储、内存、数据传输速率等。以下是一些常见的计算机单位及其含义&#xff1a; ### **1. 数据存储单位** 数据存储单位用于衡量计算机存储设备&#xff08;如硬盘、内存、闪存等&#xff09;的容量。 | 单位 | 符号 | 含义…

Spring Boot 自定义配置类(包含字符串、数字、布尔、小数、集合、映射、嵌套对象)实现步骤及示例

Spring Boot 自定义配置类实现步骤及示例 步骤说明 创建配置类&#xff1a;定义一个 POJO 类&#xff0c;使用 ConfigurationProperties 注解指定配置前缀。启用配置绑定&#xff1a;在启动类或配置类上添加 EnableConfigurationProperties 注解。配置文件写法&#xff1a;在 …

Linux: 线程控制

目录 一 前言 二 线程控制 1. POSIX线程库(原生线程库) 2. 创建线程 2.1 pthread_create 2.2pthread_self()获取线程id 3.线程终止 3.1.return 方式 3.2 pthread_exit 4 线程等待 三 理解线程tid 一 前言 在上一篇文章中我们已经学习了线程的概念&#xff0c;线程的创…