一文带你彻底搞懂MCP

最近很多人在聊MCP,但大多数都在讲MCP中的“服务端”、“客户端”的概念。但有些开发者仍然是一头雾水,搞不懂MCP到底是什么,也不知道如何在开发中应用MCP。接下来,本文将揭开MCP的神秘面纱,带你彻底搞懂MCP。

一、LLM的函数调用(Function Calling)

这一篇文章中解读了OpenManus的代码

揭秘OpenManus,带你了解Manus的设计思路 https://mp.weixin.qq.com/s?__biz=Mzg5NTg5NzY3Ng==&mid=2247484529&idx=1&sn=c657962f61fbe3b15b49d9c2d7608223&scene=21#wechat_redirect

从代码中,我们可以发现,实现Manus的关键思路,就是学会让模型调用函数工具。OpenManus通过四个核心函数工具实现了智能体的所有操作,分别为:

  • 执行Python函数

  • 谷歌搜索

  • 操作浏览器

  • 保存文件

OpenManus首先会对任务进行拆解,让模型规划应该调用哪些函数工具,何时调用函数工具,以及如何填写函数工具的参数。

因此,让LLM学会调用函数工具,是智能体的关键。

让LLM学会调用工具,步骤如下:

(1)写好函数工具

开发者需要在本地写好函数工具,例如,如果想让LLM学会查询天气,我们需要在本地写好一个查询天气的函数

(2)写好函数的介绍(这个很关键)

LLM将会函数的介绍,理解函数的作用。函数介绍包括:函数的作用、参数的类型、参数的作用等。例如,DeepSeek的函数介绍格式如下:

tools =[
    {
        "type":"function",
        "function":{
            "name":"get_weather",
            "description":"Get weather of an location, the user shoud supply a location first",
            "parameters":{
                "type":"object",
                "properties":{
                    "location":{
                        "type":"string",
                        "description":"The city and state, e.g. San Francisco, CA",
                        }
                 },
                "required":["location"]
            },
        }
    },
]

这是一个天气查询的函数,参数为location,LLM将会通过这些介绍,学会如何调用函数。

(3)解析响应,并在本地执行函数

若DeepSeek认为当前应该调用函数,则会输出参数的填写方式,格式如下:

{
	"message": {
		"role": "assistant",
		"content": "",
		"tool_calls": [{
			"index": 0,
			"id": "call 0_c2fd458f-b1e3-43a0-b76a-c9138e609678",
			"type": "function",
			"function": {
				"name": "get_weather",
				"arguments": "{\"location\":\"Beijing\"}"
			}
		}]
	}
}

我们可以通过解析message中是的tool_calls字段,将DeepSeek给出的参数填写在函数中,并在本地执行函数。

(4)LLM根据运行结果进行总结并回复

最后把函数执行的结果反馈给DeepSeek,DeepSeek再整理执行结果,给出回复。

在这个过程中,会遇到一些问题:

对于DeepSeek来说,这个功能是不稳定的,DeepSeek团队也表示正在积极修复。

 

对于不同模型来说,不同模型的函数介绍格式不同、返回的参数格式不同。如果我们的项目中需要兼容DeepSeek、GPT、Grok等多家不同的模型,那我们就需要针对每一家模型设置参数解析的格式,增加了开发的工作量。

二、MCP

MCP,全称Model Context Protocol(模型上下文协议),是一个开放、基于共识的协议,由Claude(Anthropic)领导,旨在帮助AI模型(如LLM)与各种工具、服务和数据库进行标准化交互。它通过MCP服务器使AI模型能以统一方式调用外部能力,而无需为每个集成编写自定义代码。这似乎能提高AI应用的开发效率和可靠性。

讲人话,MCP就是一个扩展坞,兼容不同模型的参数格式,方便我们调用。

 

那么问题又来了,MCP是如何兼容这么多模型的格式的?

难道是MCP已经帮我们预设好了每家模型的格式?

其实不然,MCP使用了更巧妙的办法。

我们可以分析一段MCP官方给出的代码示例

https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/clients/simple-chatbot/mcp_simple_chatbot/main.py#L196


            all_tools = []
            for server in self.servers:
                tools = await server.list_tools()
                all_tools.extend(tools)

            tools_description = "\n".join([tool.format_for_llm() for tool in all_tools])

            system_message = (
                "You are a helpful assistant with access to these tools:\n\n"
                f"{tools_description}\n"
                "Choose the appropriate tool based on the user's question. "
                "If no tool is needed, reply directly.\n\n"
                "IMPORTANT: When you need to use a tool, you must ONLY respond with "
                "the exact JSON object format below, nothing else:\n"
                "{\n"
                '    "tool": "tool-name",\n'
                '    "arguments": {\n'
                '        "argument-name": "value"\n'
                "    }\n"
                "}\n\n"
                "After receiving a tool's response:\n"
                "1. Transform the raw data into a natural, conversational response\n"
                "2. Keep responses concise but informative\n"
                "3. Focus on the most relevant information\n"
                "4. Use appropriate context from the user's question\n"
                "5. Avoid simply repeating the raw data\n\n"
                "Please use only the tools that are explicitly defined above."
            )

方便起见,我们翻译一些系统提示词:


您是一个有用的助手,可以访问这些工具:

{tools_description}
根据用户的问题选择合适的工具。如果不需要工具,请直接回复。

重要提示:当您需要使用工具时,您必须只回复下面确切的JSON对象格式,不回复别的内容:
{
  "tool": "tool-name",
  "arguments": {
    "argument-name": "value"
  }
}

收到执行结果后:

1.将原始数据转换为自然的对话式响应
2.保持回答简洁但信息丰富
3.关注最相关的信息
4.使用用户问题中的适当上下文
5.避免简单地重复原始数据

你只能使用上面明确定义的工具。

看到这里,你是不是恍然大悟。

MCP实际上就是把函数的介绍写在了系统提示词里。

对于Function Calling来说,我需要把函数的参数填到请求参数tools里面,这些函数最终以什么样的方式输入到模型里,这个过程是不透明的,解析tools的工作是在云端进行的,返回的格式也是在云端定义的。我们只能通过官方文档来确定返回参数的格式。

而MCP很巧妙的绕过了云端解析tools的过程。MCP把函数的介绍、参数的返回格式都写在了系统提示里面,这样一来,只要LLM能够理解系统提示词,就能够按照提示词定义的格式输出。这就实现了格式的统一。

在理解了MCP的原理后,我们就能很清晰地解释MCP的服务端和客户端了:

✅MCP服务端就是执行函数工具的场所。

✅MCP客户端就是与LLM交互的场所,包括介绍函数和获取函数的参数

对于大多数的开发者来说,需要开发的是MCP客户端,MCP服务端中常用的函数工具、数据查询工具等已经由社区的开发者们开发好了,可以直接进行调用。

而在MCP客户端中,开发者根据业务流程,让LLM选择合适的函数工具进行调用,最终实现业务逻辑。

 

 

MCP2515是一款常用的CAN控制器芯片,用于控制CAN总线的通信。位修改指令是MCP2515提供的一种特殊的指令,用于在不影响其他位的情况下修改寄存器中的特定位。 为了使用位修改指令,你需要了解MCP2515的寄存器映射以及位修改指令的格式MCP2515的寄存器可以通过SPI接口进行读写操作。以下是位修改指令的一般格式: 1. 发送读寄存器命令(0x03)以及要修改的寄存器地址。 2. 发送待修改位的屏蔽字节(Mask Byte)以及相应的数据字节(Data Byte)。 屏蔽字节是用来指定哪些位需要被修改,相应的数据字节则是指定要写入的新值。屏蔽字节中置位(1)的位表示对应的位可以被修改,而清零(0)的位表示对应的位保持不变。 下面是一个示例来说明位修改指令的使用: 假设要将MCP2515的CANCTRL寄存器(地址为0x0F)中的REQOP位(位6-4)设置为二进制值011,而不影响其他位。 首先,发送读寄存器命令(0x03)以及CANCTRL寄存器地址(0x0F)。 然后,发送屏蔽字节为0xE7(二进制11100111)和数据字节为0x18(二进制00011000)。 屏蔽字节0xE7的二进制表示为:11100111 数据字节0x18的二进制表示为:00011000 根据屏蔽字节和数据字节的对应关系,可以看出只有REQOP位(位6-4)会被修改。屏蔽字节中置位的位对应的位可以进行修改,而清零的位则表示对应的位保持不变。 最后,MCP2515将根据指定的屏蔽字节和数据字节将CANCTRL寄存器中的REQOP位设置为011,同时保持其他位不变。 请注意,具体的寄存器和位的映射关系,以及屏蔽字节和数据字节的设置会根据具体的MCP2515芯片和应用场景而有所不同。确保参考相关文档和手册以获取准确的指令格式和使用方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

G.E.N.

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

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

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

打赏作者

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

抵扣说明:

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

余额充值