MCP 原理及部分深层代码解析

导语:
除了整理网络上基本的概念原理,还会增加一些有深度的代码解析,帮助读者进一步了解MCP。

一、什么是MCP

MCP(Model Context Protocol)是由Anthropic于2024年底提出并开源的一种协议,旨在为AI系统(如AI编程助手、Agent等)提供安全、标准化的数据访问方式。它采用客户端-服务器架构,使AI工具(如Claude Desktop、IDE插件等)能够通过MCP客户端与MCP服务端交互,访问本地或远程数据源。

官方文档:MCP Quickstart

https://modelcontextprotocol.io/quickstart/server

MCP的核心特点包括:
模块化:每个模块专注于一个概念、任务或技能。
组合性:多个模块可按需组合,处理复杂任务。
动态路由:主控制器根据上下文动态调用合适模块。
可解释性:每一步推理过程清晰可追踪。
在这里插入图片描述

二、为什么需要MCP

MCP 则提供了一种新的范式,让模型能像人类一样“拆分任务”、“调动知识”、“有条理地思考”。它就像一个“转接头”或“通用插座”,它的核心作用是统一不同外部服务(如 Google Drive、GitHub、Slack、本地文件系统等),通过标准化接口与 AI 模型对接。

这样,开发者只需基于 MCP 规范开发一次“接口适配器”(MCP 服务器),就能让所有兼容 MCP 的模型(MCP 客户端)无缝接入,无需针对每个模型单独适配,大幅提升兼容性与开发效率。

MCP可以标准化地连接AI系统与各类外部工具和数据源:
在这里插入图片描述
传统的 API 就像不同的门和特定的钥匙:在这里插入图片描述

三、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 提供的数据。
在这里插入图片描述
这个图比较直观的展现了一个样例交互流程。在这里插入图片描述
协议层与传输层
在这里插入图片描述
协议层(Protocol Layer)
负责消息封装(framing)、请求/响应关联、高级通信模式管理。

传输层(Transport Layer)
支持两种通信方式:

1.Stdio传输(标准输入/输出)

  • 适用于本地进程间通信。

2.HTTP + SSE传输

  • 服务端→客户端:Server-Sent Events(SSE)

  • 客户端→服务端:HTTP POST

  • 适用于远程网络通信。

所有传输均采用JSON-RPC 2.0进行消息交换。

消息类型

MCP 拥有多种类型的消息来处理不同的场景

请求(Request)(期望获得响应)

interface Request {
  method: string;
  params?: { ... };
}

成功响应(Result)

interface Result {
  [key: string]: unknown;
}

错误响应(Error)

interface Error {
  code: number;
  message: string;
  data?: unknown;
}

通知(Notification)(单向,无需响应)

interface Notification {
  method: string;
  params?: { ... };
}

生命周期

类似于三次握手,MCP客户端与MCP服务端初始化建立连接会进行以下步骤:
在这里插入图片描述
初始化(Initialization)

  • 1.客户端发送initialize请求(含协议版本、能力集)。

    2.服务端返回版本及能力信息。

    3.客户端发送initialized通知确认。

    4.进入正常通信阶段。

消息交换(Message Exchange)
当初始化完毕,就可以进行通信了,目前支持:

  • 请求-响应模式(Request-Response):双向通信。

    通知模式(Notification):单向消息。

终止(Termination)
有以下几种方式会关闭连接

  • 主动关闭(close())。

    传输层断开。

    错误触发终止。

四、MCP能用来做什么

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

五、MCP与API的区别

你可能会问:API 不也能让 AI 调用外部服务吗?为什么需要 MCP?答案在于,MCP 不仅实现了 API 的功能,还带来了更高的标准化和灵活性:
在这里插入图片描述
举个例子:用 API 获取天气数据,AI 得解析复杂的 JSON;而用 MCP 天气服务器,AI 直接拿到简洁的预报结果,还能顺手帮你记录下来。MCP 的标准化和双向性,让 AI 的操作更高效、更自然。

以下是一个简单的表格,展示了两者在不同场景下的表现:
在这里插入图片描述

这里说下我的一些观点,MCP实质上也是一种特殊的API,是针对大模型和智能体而定制的API,转换一下角度,就不难理解了。

六、一个实践案例

基础概念介绍完毕,接下来进行实践,我希望能实现一个自己的 agent,让 AI 不仅能和我交流,还能帮我干活。

先画一个图:
在这里插入图片描述
如图,要实现一个这样的效果,实现一个 myAgent,启动时,MCP Client建立与 MCP 服务端的连接,此时 MCP Server 上的能力或者可调用的工具会注册进来, 让 Client 感知到这个MCP服务能够干啥。

当用户与 Agent 进行交互时,Agent 会让 MCP Client 将用户的输入发送给 AI,让 AI 解析用户意图,一并发送的还有注册在 Client 上的能力集合。

我写了一个搜索助手的 MCP Server ,能力集的数据是这样的,可以看到目前只有一个 function,get_offers,可以看到工具里有它的名字,能力描述,需要的字段(包含字段类型,字段描述)。

available_tools is: [{'type': 'function', 'function': {'name': 'get_offers', 'description': 'Get product offers from API', 'parameters': {'type': 'object', 'properties': {'keywords': {'type': 'string', 'description': 'Keywords to search for products', 'default': ''}, 'pageSize': {'type': 'number', 'description': 'Number of items per page', 'minimum': 1, 'maximum': 100, 'default': 10}}}}}]

AI 会理解用户意图,决定是否用自然语言回答用户,或者选择合适的工具,告诉 client,帮我调用它。

当输入 你好 时,传给 AI 的 message 是这样的,这里系统预设了 AI 的一个身份,用于更好的完成特定领域的任务。

[
    {
        "role": "user",
        "content": "你好"
    },
    {
        "role": "system",
        "content": "You're a helpful digital assistant who can answer questions and support users in completing tasks."
    }
]

此时 client 接收到 AI 的消息后,会解析数据,当没有工具要调用时

AI返回的是这样的:

ChatCompletionMessage(content='你好!有什么可以帮助你的吗?', refusal=None, role='assistant', annotations=None, audio=None, function_call=None, tool_calls=None)

可以看到,AI 返回是带有角色信息的,然后本次并没有识别到需要调用工具的地方,因此直接返回给用户就好,当然,在工程应用时,可以进行额外的逻辑处理。

让 AI 长出手,AI调用 MCP Server流程揭秘

当输入 帮我找一些手表 时,输入是:

[{'role': 'user', 'content': '帮我找一些手表'}, {'role': 'system', 'content': 'You are a helpful assistant that can answer questions and help with tasks.'}]

第一次AI 交互
AI返回的是

AI response is 
ChatCompletionMessage(content='', refusal=None, role='assistant', annotations=None, audio=None, function_call=None, 
tool_calls=[ChatCompletionMessageToolCall(id='0195c8c06aaf3ea050e6d8eed17380ec', function=Function(arguments='{"keywords": "手表", "pageSize": 10}', name='get_offers'), type='function')])

可以看到,AI 识别到了用户的意图,是要寻找一些手表,并自动的选择了一个工具进行调用,根据工具使用说明,决定了选择的工具应该输入什么入参。(这里和模型很相关,是一个重要的节点,识别用户意图并决定要调用工具,有时识别的并不准确,或者返回的结构不是标准可解析的,这时就触发不了工具的调用,还会引入一些辣鸡信息,可能的解决方案是 换效果更好的模型,或者用提示词来约束模型返回,或者系统自己增加鲁棒性,提升成功率)

下面举一个效果不好的例子,大家如果知道有其他解决方法欢迎留言。

AI response is ChatCompletionMessage(content='leton\n{{"name": "get_offers", "arguments": {"keywords": "手表", "pageSize": 10}}}\n</tool_call>', refusal=None, role='assistant', annotations=None, audio=None, function_call=None, tool_calls=None)

Client 调用 MCP Server
client 接收到AI 的消息后,发现要调用工具,并且也有了工具所需的参数,就会与通过协议与 MCP Server 进行通信,告诉 MCP Server 该使用 get_offers 能力了,并且期待 MCP Server 将结果返回回来:

result = await self.session.call_tool(tool_name, tool_args)

获取 MCP Server 数据
MCP Server 不负众望,将结果返回了,可以看看返回的格式是什么样的:

meta=None content=[TextContent(type='text', text='some...product...info', annotations=None)] isError=False

MCP Client 拿到数据后,再将数据发送给 AI,输入是这样的:

{
  "messages": [
    {
      "role": "user",
      "content": "帮我找一些手表"
    },
    {
      "role": "system",
      "content": "You are a helpful assistant that can answer questions and help with tasks."
    },
    {
      "role": "assistant",
      "content": "",
      "tool_calls": [
        {
          "id": "0195c8c06aaf3ea050e6d8eed17380ec",
          "type": "function",
          "function": {
            "name": "get_offers",
            "arguments": "{\"keywords\": \"手表\", \"pageSize\": 10}"
          }
        }
      ]
    },
    {
      "role": "tool",
      "tool_call_id": "0195c8c06aaf3ea050e6d8eed17380ec",
      "content": {
        "type": "text",
        "text": "some...product...info"
      }
    }
  ]
}

第二次 AI 交互
最后,AI 将 MCPServer 的结果,进行总结润色,结构化返回:

🤖AI: [📞调用工具 get_offers 🔑参数是 {'keywords': '手表', 'pageSize': 10}]
根据您的搜索,这里有几款手表供您参考:

1. 款式 ID: ididid2
   价格: $0.24
   供应商: Guangzhou Huapan Cosmetics Co., Ltd.
   评分: **
   收评次数: **
   供应商年限: **年
   推荐指数: ★★

2. 款式 ID: ididid
   价格: $3.99
   供应商: Shenzhen Top Quality Electronics Technology Co., Ltd.
   评分: **
   收评次数: **
   供应商年限: **年
   推荐指数: ★★

这两款手表的评价和销售情况都还不错,您可以根据自己的需求选择合适的款式。如果还有其他问题或需要更多信息,请随时告诉我。
这里给了 它 10 个品 ,但是只总结了两个品,可能适合我之前的输入 帮我找一些手表 有关,看来AI 也会偷懒😅。

上面的交互过程,其实可以化简,如果在工程应用上,调用的 MCP Server 是一个预期内的结构化的结果或者触发某个任务时,可以不必进行二次 AI 调用。如上面的例子中,MCP Server 是一个搜索助手,内部发起调用的是搜索的接口,并进行结构化返回。此时在 AI 识别到用户意图并告诉 Client 该调用什么工具时,与 AI 的交互就可以结束了,由系统接管决定应该返回给用户什么,不必再将结果给到 AI 进行润色总结。

给到 AI 进行润色总结的好处是可以根据用户的输入,再结合工具获取的数据,更智能友好的返回给用户信息,这一点可以在工程应用时,进行衡量取舍。

将MCP Server 的结果交给 AI,在需要进行多轮交互场景是有必要的,根据 MCP Server的结果,进行分析及决策,动态调整要使用的工具,可以将一个复杂的任务交给 AI , 它会自己拆解成小任务,然后自动完成。

对于该场景,也进行了一些实践。

例如,让Al agent拆解抽象任务,并自己主动与系统进行多轮交互,完成任务场景。

七、MCP社区

4月15日,中国第一AI开源社区魔搭(ModelScope)推出全新MCP广场,上架千余款热门的MCP服务,包括支付宝、MiniMax等全新MCP服务在魔搭独家首发。魔搭社区为AI开发者提供丰富的MCP服务及调试工具,并支持第三方平台集成和调用,通过开源开放的方式加速Agent及AI应用的创新和落地。
在这里插入图片描述
在这里插入图片描述

<think>好的,用户现在问的是关于CAN分析仪内部的MCU或SOC是否进行内部逻辑处理。首先,我需要回顾之前关于CAN盒工作原理和通信方法的讨论,确保现在回答的一致性和准确性。用户可能已经了解了一些基础,现在想深入理解CAN分析仪的硬件处理机制。 用户的问题核心在于MCU或SOC在CAN分析仪中的作用,特别是内部逻辑处理。我需要明确这两个术语的区别:MCU是微控制器,通常集成了处理器、内存和外围接口;而SOC是系统级芯片,可能包含更复杂的处理单元和专用硬件模块。需要说明它们在CAN分析仪中的具体角色。 接下来,我需要考虑用户可能的背景。可能是工程师或技术人员,正在开发或使用CAN分析仪,需要了解其内部结构以进行调试或二次开发。用户可能想知道数据处理是在硬件层面还是软件层面完成的,这对性能和功能扩展有影响。 然后,我需要解释MCU/SOC在CAN分析仪中的具体任务,比如协议解析、数据过滤、格式转换等。需要提到它们如何处理原始CAN帧,可能进行的预处理,如校验、ID过滤、数据解析,以及如何与上位机通信,比如通过USB或以太网传输数据。 还要考虑用户可能的后续问题,比如为什么需要内部处理,这样做的好处是什么,比如降低上位机负载,实时性处理等。同时,是否需要举例说明不同级别的CAN分析仪(如基础型和高性能型)在内部处理上的差异。 此外,注意回答的结构要清晰,分点说明功能、处理流程、不同芯片架构的影响,以及具体示例,帮助用户逐步理解。同时,确保语言通俗易懂,避免过于专业的术语,或在必要时进行解释。 最后,验证信息准确性,确保提到的MCU型号和示例应用是实际存在的,比如NXP的S32K系列或TI的C2000系列,这些确实用于汽车电子。同时,提及FPGA的应用场景,说明在高速或复杂处理时的优势。 总结来说,需要全面覆盖用户的问题,同时预判可能的深层需求,提供足够详细的技术细节,帮助用户不仅了解是否处理,还理解如何处理及其意义。</think>以下是关于CAN分析仪内部处理机制的详细说明: ### 一、MCU/SOC的核心处理作用 现代CAN分析仪内部必然包含嵌入式处理器单元,其处理流程可表示为: $$原始CAN帧 \xrightarrow{MCU/SOC} 标准化数据流 \xrightarrow{接口转换} 上位机$$ #### 1. 基础处理模块 | 处理层级 | 典型功能 | 实现方式 | |----------------|-----------------------------------|-------------------------| | 物理层处理 | 总线错误检测/位时序调整 | 专用CAN控制器硬件实现 | | 数据链路层处理 | CRC校验/帧格式转换 | MCU固件逻辑 | | 应用层处理 | DBC解析/信号提取 | SOC软件算法 | #### 2. 典型处理流程 ``` CAN收发器 → 信号整形 → CAN控制器 → 数据缓存 → MCU核心处理 → USB协议栈 → 物理接口 ↑ ↓ 错误检测单元 数据预处理模块 ``` ### 二、关键处理功能详解 #### 1. 硬件级预处理 - **自动过滤机制**: ```c // 典型CAN控制器配置代码(以SJA1000为例) CAN_CTRL->ACR = 0x12; // 验收代码寄存器 CAN_CTRL->AMR = 0xFF; // 验收屏蔽寄存器(0=必须匹配) ``` 实现原理:硬件比较ID值,符合条件才触发中断 - **时间戳生成**: $$t_{stamp} = t_{总线时钟} \times 捕获计数器值$$ 精度可达0.1μs(基于72MHz时钟) #### 2. 软件层处理 - **数据重组**: ```python # 多帧报文重组示例(如UDS多帧传输) def reassemble_frames(frame_list): total_len = frame_list[0].data[0] & 0x0F result = bytearray() for i, frame in enumerate(frame_list[1:]): result.extend(frame.data[1:1+min(7, total_len-i*7)]) return result ``` - **协议转换**: ```plaintext 原始CAN帧(ID:0x101 Data:0xA1 0x23 0x45) → DBC解析 → {"EngineSpeed": 2500rpm, "CoolantTemp": 85℃} ``` ### 三、不同架构对比 | 架构类型 | 典型芯片 | 处理能力 | 延迟特性 | |----------------|-------------------------|--------------------|--------------| | 低端MCU方案 | STM32F042 + MCP2515 | 基本过滤/时间戳 | 100-500μs | | 中端SOC方案 | NXP S32K148(内置CAN FD)| 协议转换/DBC解析 | 20-50μs | | 高端FPGA方案 | Xilinx Zynq-7020 | 多路实时处理 | <1μs | #### 性能对比公式: $$处理能力 = \frac{指令周期数}{帧长度(bit) \times 总线利用率} \times 时钟频率$$ ### 四、典型处理场景示例 #### 1. 网关型处理(如CAN转以太网) ``` CAN总线 → 协议解析 → 数据包封装 → TCP/IP栈 → 以太网PHY ↑ ↑ MCU处理 硬件加速模块 ``` #### 2. 实时监控场景 ```c // 中断服务程序示例(基于ARM Cortex-M) void CAN_IRQHandler() { volatile uint32_t id = CAN->sFIFOMailBox[0].RIR >> 21; uint8_t data[8] = { CAN->sFIFOMailBox[0].RDTR & 0xFF, // ... 读取8字节数据 }; ringbuf_put(&can_rx_buf, id, data); // 存入环形缓冲区 } ``` ### 五、特殊功能实现 1. **总线负载计算**: $$负载率 = \frac{\sum_{i=1}^{n}(帧长_i \times 8 + 47)}{时间窗口 \times 波特率} \times 100\%$$ (注:47为帧额外开销位) 2. **错误帧统计**: | 错误类型 | 检测方式 | 典型处理 | |--------------|-----------------------|-----------------------| | 位错误 | 硬件自动检测 | 错误计数器累加 | | CRC错误 | 校验结果比对 | 丢弃帧并记录 | | 格式错误 | 帧结构检查 | 触发错误中断 | 3. **触发捕获逻辑**: ```python # 配置触发条件示例(ID=0x123且数据字节0>80) analyzer.set_trigger( condition=lambda msg: msg.arbitration_id == 0x123 and msg.data[0] > 0x50 ) ``` ### 六、开发调试接口 现代高端分析仪通常提供: - **JTAG/SWD调试接口**:用于固件更新和实时调试 - **内存映射访问**: ```c #define CAN_MSG_RAM_BASE 0x40003400 // 典型CAN控制器内存地址 typedef struct { uint32_t RIR; uint32_t RDTR; uint32_t RDLR; uint32_t RDHR; } CAN_MailBoxTypeDef; ``` 建议选型策略: 1. 常规诊断:选用MCU方案(如PicoScope CAN模块) 2. 协议开发:选用SOC方案(如Vector VN1610) 3. 实时控制:选用FPGA方案(如Kvaser Leaf Pro)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值